/**
* Copyright freddy ( http://wonderfl.net/user/freddy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ugND
*/
package {
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.ui.*;
import flash.utils.*;
//マウスイベントを処理する
public class Bounce extends Sprite {
private var mouseDown:Boolean = false; //マウスダウン
private var mouseDelta:int =0; //マウスホイール
private var circle:Shape; //円
private var ball:Ball; //ボール
private var g:Number = 0.000005; //重力加速度
private var e:Number = 0.9; //跳ね返り係数
private var seg1:Segment = new Segment(0.2, 0.35, 0.5, 0.35);
private var seg2:Segment = new Segment(0.27, 0.35, 0.34, 0.28);
private var seg3:Segment = new Segment(0.34, 0.28, 0.41, 0.35);
private var seg4:Segment = new Segment(0.41, 0.35, 0.48, 0.28);
private var seg5:Segment = new Segment(0.2, 0.05, 0.25, 0.1);
private var seg6:Segment = new Segment(0.3, 0.1, 0.25, 0.15);
private var seg7:Segment = new Segment(0.2, 0.15, 0.25, 0.2);
private var seg8:Segment = new Segment(0.3, 0.2, 0.25, 0.25);
private var cir1:Circle = new Circle(0.1, 0.15, 0.07);
private var cir2:Circle = new Circle(0.2-0.015, 0.35, 0.015);
private var line:Shape; //線
//コンストラクタ
public function Bounce() {
//子スプライト
var child:Sprite=new Sprite();
child.graphics.beginFill(0xffffff);
child.graphics.drawRect(0,0,480,480);
child.graphics.endFill();
child.graphics.lineStyle(0,0x000000);
child.graphics.moveTo(seg1.a.x*1000, seg1.a.y*1000);
child.graphics.lineTo(seg1.b.x*1000, seg1.b.y*1000);
child.graphics.moveTo(seg2.a.x*1000, seg2.a.y*1000);
child.graphics.lineTo(seg2.b.x*1000, seg2.b.y*1000);
child.graphics.moveTo(seg3.a.x*1000, seg3.a.y*1000);
child.graphics.lineTo(seg3.b.x*1000, seg3.b.y*1000);
child.graphics.moveTo(seg4.a.x*1000, seg4.a.y*1000);
child.graphics.lineTo(seg4.b.x*1000, seg4.b.y*1000);
child.graphics.moveTo(seg5.a.x*1000, seg5.a.y*1000);
child.graphics.lineTo(seg5.b.x*1000, seg5.b.y*1000);
child.graphics.moveTo(seg6.a.x*1000, seg6.a.y*1000);
child.graphics.lineTo(seg6.b.x*1000, seg6.b.y*1000);
child.graphics.moveTo(seg7.a.x*1000, seg7.a.y*1000);
child.graphics.lineTo(seg7.b.x*1000, seg7.b.y*1000);
child.graphics.moveTo(seg8.a.x*1000, seg8.a.y*1000);
child.graphics.lineTo(seg8.b.x*1000, seg8.b.y*1000);
child.graphics.drawCircle(cir1.a.x*1000, cir1.a.y*1000, cir1.r*1000); //XY座標,半径
child.graphics.drawCircle(cir2.a.x*1000, cir2.a.y*1000, cir2.r*1000); //XY座標,半径
addChild(child);
//円の追加
// ball = new Ball(10, 240, 10, 0, 0.2, 0, 0.1);
ball = new Ball(0.015, 0.240, 0.240, 0, 0.0007, 0.001, 0.01);
circle=makeCircle(ball.r*1000,0xffff00);
circle.x=ball.x*1000;
circle.y=ball.y*1000;
child.addChild(circle);
//イベントリスナーの追加
child.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
child.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
child.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWheelHandler);
//タイマーの追加
var timer:Timer=new Timer(1000/60,0);
timer.addEventListener(TimerEvent.TIMER,onTick);
timer.start();
}
//マウスダウンイベントの処理
private function mouseDownHandler(evt:MouseEvent):void {
mouseDown=true;
}
//マウスアップイベントの処理
private function mouseUpHandler(evt:MouseEvent):void {
mouseDown=false;
}
//マウスホイールイベントの処理
private function mouseWheelHandler(evt:MouseEvent):void {
mouseDelta=evt.delta;
}
//タイマーイベントの処理
private function onTick(evt:TimerEvent):void {
var i:int;
var n:Number, m:Number;
for(i=0; i<10; i++)
{
if(mouseDown)
{
ball.vx = (mouseX/1000-ball.x)/100;
ball.vy = (mouseY/1000-ball.y)/100;
}
ball.x += ball.vx;
ball.y += ball.vy+g/2;
ball.vy += g;
ball.rotation += ball.vrotation;
if(ball.y >= 0.480-ball.r) // floor
{
ball.y = (e+1.0)*(0.480-ball.r)-e*ball.y;
ball.vy = -e*ball.vy;
m = -2.0*(e+1.0)*ball.vx/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
n = (2.0-e)*ball.vx/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = m;
ball.vx = n;
}
if(ball.y < 0+ball.r) // ceil
{
ball.y = (e+1.0)*(0+ball.r)-e*ball.y;
ball.vy = -e*ball.vy;
m = -2.0*(e+1.0)*(-ball.vx)/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
n = (2.0-e)*(-ball.vx)/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = m;
ball.vx = -n;
}
if(ball.x >= 0.480-ball.r) // right wall
{
ball.x = (e+1.0)*(0.480-ball.r)-e*ball.x;
ball.vx = -e*ball.vx;
m = -2.0*(e+1.0)*(-ball.vy)/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
n = (2.0-e)*(-ball.vy)/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = m;
ball.vy = -n;
}
if(ball.x < 0+ball.r) // left wall
{
ball.x = (e+1.0)*(0+ball.r)-e*ball.x;
ball.vx = -e*ball.vx;
m = -2.0*(e+1.0)*ball.vy/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
n = (2.0-e)*ball.vy/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = m;
ball.vy = n;
}
seg1.collision(ball);
seg2.collision(ball);
seg3.collision(ball);
seg4.collision(ball);
seg5.collision(ball);
seg6.collision(ball);
seg7.collision(ball);
seg8.collision(ball);
cir1.collision(ball);
cir2.collision(ball);
}
circle.x = ball.x*1000;
circle.y = ball.y*1000;
circle.rotation= -ball.rotation*180/3.1415926535;
}
//円の追加
private function makeCircle(r:uint,color:uint):Shape {
var circle:Shape=new Shape();
circle.graphics.beginFill(color); //背景色
circle.graphics.lineStyle(0,0x000000);//線幅・線色
circle.graphics.drawCircle(0,0,r); //XY座標,半径
circle.graphics.endFill(); //塗り潰し終了
// circle.graphics.lineStyle(0,color);//線幅・線色
circle.graphics.moveTo(0,0); //始点のXY座標
circle.graphics.lineTo(r,0); //終点のXY座標
return circle;
}
//ラインの追加
private function makeLine(x0:int,y0:int,x1:int,y1:int,color:uint):Shape {
var line:Shape=new Shape();
line.graphics.lineStyle(0,color);//線幅・線色
line.graphics.moveTo(x0,y0); //始点のXY座標
line.graphics.lineTo(x1,y1); //終点のXY座標
return line
}
}
}
class Ball
{
public var r:Number;
public var x:Number;
public var y:Number;
public var rotation:Number;
public var vx:Number;
public var vy:Number;
public var vrotation:Number;
public function Ball(_r:Number, _x:Number, _y:Number, _rot:Number, _vx:Number, _vy:Number, _vrot:Number)
{
r = _r;
x = _x;
y = _y;
rotation = _rot;
vx = _vx;
vy = _vy;
vrotation = _vrot;
}
}
class Circle
{
public var a:Vector2 = new Vector2();
public var r:Number;
private var e:Number = 0.9; //跳ね返り係数 ////////////////////////////
public function Circle(x:Number, y:Number, radius:Number)
{
a.setXY(x, y);
r = radius;
}
public function collision(ball:Ball):void
{
var x:Vector2 = new Vector2(ball.x, ball.y);
var n:Vector2 = new Vector2();
var k:Number;
var i:Number, j:Number;
var collision:Boolean = false;
n.setV(x);
n.subtract(a);
n.multiplyN(1.0-r/n.length());
if(n.length() <= ball.r)
{
collision = true;
k = ball.r-n.length();
}
if(collision)
{
n.normalize();
// position
x.setV(n);
x.multiplyN((1+e)*k);
ball.x += x.x;
ball.y += x.y;
// velocity
var s:Matrix22 = new Matrix22(n.y, n.x, -n.x, n.y);
var si:Matrix22 = new Matrix22(n.y, -n.x, n.x, n.y);
x.setXY(ball.vx, ball.vy);
x.multiplyMV(si);
x.y = -e*x.y;
i = -2.0*(e+1.0)*(-x.x)/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
j = (2.0-e)*(-x.x)/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = i;
x.x = -j;
x.multiplyMV(s);
ball.vx = x.x;
ball.vy = x.y;
}
/*
ball.y = (e+1.0)*(0.480-ball.r)-e*ball.y;
ball.vy = -e*ball.vy;
m = -2.0*(e+1.0)*ball.vx/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
n = (2.0-e)*ball.vx/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = m;
ball.vx = n;
*/
}
}
class Matrix22
{
public var m00:Number, m01:Number;
public var m10:Number, m11:Number;
public function Matrix22(_m00:Number = 0, _m01:Number = 0, _m10:Number = 0, _m11:Number = 0)
{
m00=_m00; m01=_m01;
m10=_m10; m11=_m11;
}
public function setM(a:Matrix22):void
{
m00=a.m00; m01=a.m01;
m10=a.m10; m11=a.m11;
}
public function setXY(_m00:Number, _m01:Number, _m10:Number, _m11:Number):void
{
m00=_m00; m01=_m01;
m10=_m10; m11=_m11;
}
public function isZero():Boolean
{
return m00==0 && m01==0 && m10==0 && m11==0;
}
public function isIdentity():Boolean
{
return m00==1 && m01==0 && m10==0 && m11==1;
}
public function minus():void
{
m00=-m00; m01=-m01;
m10=-m10; m11=-m11;
}
public function multiplyN(a:Number):void
{
m00*=a; m01*=a;
m10*=a; m11*=a;
}
public function multiplyM(a:Matrix22):void
{
var _m00:Number = m00*a.m00+m01*a.m10;
var _m01:Number = m00*a.m01+m01*a.m11;
var _m10:Number = m10*a.m00+m11*a.m10;
var _m11:Number = m10*a.m01+m11*a.m11;
m00=_m00; m01=_m01;
m10=_m10; m11=_m11;
}
public function divide(a:Number):void
{
m00/=a; m01/=a;
m10/=a; m11/=a;
}
public function add(a:Matrix22):void
{
m00+=a.m00; m01+=a.m01;
m10+=a.m10; m11+=a.m11;
}
public function subtract(a:Matrix22):void
{
m00-=a.m00; m01-=a.m01;
m10-=a.m10; m11-=a.m11;
}
public function equal(a:Matrix22):Boolean
{
return m00==a.m00 && m01==a.m01 && m10==a.m10 && m11==a.m11;
}
public function notEqual(a:Matrix22):Boolean
{
return m00!=a.m00 || m01!=a.m01 || m10!=a.m10 || m11!=a.m11;
}
}
class Vector2
{
public var x:Number;
public var y:Number;
public function Vector2(_x:Number = 0, _y:Number = 0)
{
x = _x;
y = _y;
}
public function setV(a:Vector2):void
{
x = a.x;
y = a.y;
}
public function setXY(_x:Number, _y:Number):void
{
x = _x;
y = _y;
}
public function length():Number
{
return Math.sqrt(x*x+y*y);
}
public function length2():Number
{
return x*x+y*y;
}
public function isZero():Boolean
{
return x==0 && y==0;
}
public function normalize():void
{
var a:Number = Math.sqrt(x*x+y*y);
x /= a;
y /= a;
}
public function dot(a:Vector2):Number
{
return x*a.x+y*a.y;
}
public function minus():void
{
x = -x;
y = -y;
}
public function multiplyN(a:Number):void
{
x *= a;
y *= a;
}
public function multiplyMV(a:Matrix22):void
{
var _x:Number = a.m00*x+a.m01*y;
var _y:Number = a.m10*x+a.m11*y;
x = _x;
y = _y;
}
public function multiplyVM(a:Matrix22):void
{
var _x:Number = x*a.m00+y*a.m10;
var _y:Number = x*a.m01+y*a.m11;
x = _x;
y = _y;
}
public function divide(a:Number):void
{
x /= a;
y /= a;
}
public function add(a:Vector2):void
{
x += a.x;
y += a.y;
}
public function subtract(a:Vector2):void
{
x -= a.x;
y -= a.y;
}
public function equal(a:Vector2):Boolean
{
return x==a.x && y==a.y;
}
public function notEqual(a:Vector2):Boolean
{
return x!=a.x || y!=a.y;
}
}
class Segment
{
public var a:Vector2 = new Vector2();
public var b:Vector2 = new Vector2();
private var e:Number = 0.9; //跳ね返り係数 ////////////////////////////
public function Segment(ax:Number, ay:Number, bx:Number, by:Number)
{
a.setXY(ax, ay);
b.setXY(bx, by);
}
public function collision(ball:Ball):void
{
var ab:Vector2 = new Vector2();
var ax:Vector2 = new Vector2();
var x:Vector2 = new Vector2(ball.x, ball.y);
var n:Vector2 = new Vector2();
var k:Number;
var i:Number, j:Number;
var collision:Boolean = false;
ab.setV(b);
ab.subtract(a);
ax.setV(x);
ax.subtract(a);
k = ab.dot(ax);
if(k < 0) // point A
{
if(ax.length2() <= ball.r*ball.r)
{
n.setV(ax);
collision = true;
}
}
else if(k > ab.length2()) // point B
{
n.setV(x);
n.subtract(b);
if(n.length2() <= ball.r*ball.r)
{
collision = true;
}
}
else // line AB
{
k /= ab.length2();
ab.multiplyN(k);
n.setV(x);
n.subtract(a);
n.subtract(ab);
if(n.length2() <= ball.r*ball.r)
{
collision = true;
}
}
if(collision)
{
k = ball.r-n.length();
n.normalize();
// position
x.setV(n);
x.multiplyN((1+e)*k);
ball.x += x.x;
ball.y += x.y;
// velocity
var s:Matrix22 = new Matrix22(n.y, n.x, -n.x, n.y);
var si:Matrix22 = new Matrix22(n.y, -n.x, n.x, n.y);
x.setXY(ball.vx, ball.vy);
x.multiplyMV(si);
x.y = -e*x.y;
i = -2.0*(e+1.0)*(-x.x)/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
j = (2.0-e)*(-x.x)/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = i;
x.x = -j;
x.multiplyMV(s);
ball.vx = x.x;
ball.vy = x.y;
}
/*
ball.y = (e+1.0)*(0.480-ball.r)-e*ball.y;
ball.vy = -e*ball.vy;
m = -2.0*(e+1.0)*ball.vx/3.0/ball.r + (1.0-2.0*e)*ball.vrotation/3.0;
n = (2.0-e)*ball.vx/3.0 - (1.0+e)*ball.vrotation*ball.r/3.0;
ball.vrotation = m;
ball.vx = n;
*/
}
}