実際にオブジェクト同士の衝突に関するCheckCollision関数がよくわからなかったので、メモします。
private function CheckCollision(ball0:Ball , ball1:Ball):void{ var dx = ball1.x - ball0.x; var dy = ball1.y - ball0.y; var dist:Number = Math.sqrt(dx * dx + dy * dy); if(dist < ball0.radius + ball1,radius){
まずは、ボール間の距離を出して、半径同士の和と比較をしています。つまり、オブジェクト同士がぶつかったかどうかを判定しています。 ぶつかった場合は以下のようになります。
var angle:Number = Math.atan2(dy,dx); var sin : Number = Math.sin(angle); var cos : Number = Math.cos(angle);
まず、2点間の角度を出し、sin,cosを出してます。 次はオブジェクトの位置の回転です。
var pos0:Point = new Point(0,0); var pos1:Point = rotate(dx,dy,sin,cos,true); var vel0:Point = rotate(ball0.vx , ball0.vy , sin , cos ,true); var vel1:Point = rotate(ball1.vx , ball1.vy ,sin ,cos ,true);
ここでPoint,rotate()と今まで見たこともないモノが出てきましたね。 Pointは「import flash.geom.Point」でパッケージされたモノ、Point オブジェクトは 2 次元の座標系の位置を表します。x は水平方向の軸を表し、y は垂直方向の軸を表します。 今回のball0は”回転の中心(ピボットテーブル)”に使用するので、座標は(0、0)になります。
rotate()は回転を表す「dx * cos - dy *sin」をまとめた奴です。いちいち書くのがめんどくさいので。これは速度の回転にも使います。 引数の最後のtrue,falseは回転するか、回転を元に戻すかで違いがあります。
private function rotate(x:Number , y:Number ,sin:Number , cos:Number , reverse:Boolean) :Point { var result:Point = new Point(); if(reverse){ result.x = x * cos + y * sin; result.y = y * cos - y * sin; }else{ result.x =x * cos - y * sin ; result.y = y * cos + y *sin; } return result; }
※ 次は実際に衝突した際の反応。 var vxTotal:Number = vel0.x - vel1.x; vel0.x = ((ball0.mass - ball1.mass) * vel0.x + 2 *ball1.mass * vel1.x) / (vel0.mass + vel1.mass) ; vel1.x = vel0.x + vxTotal;
これは今でもよくわからない。 2点のオブジェクトの相対的な速度の差を求め、支点となるオブジェクト(今回はball0)の最終速度を求め、実際のオブジェクトの最終速度を求めています。ここは理解がまだ乏しい。
pos0.x += vel0.x; pos1.x += vel1.x; var pos0F:Object = rotate(pos0.x , pos0.y ,sin ,cos ,false); var pos1F:Object = rotate(pos1.x ,pos1.y,sin,cos,false);
ball1.x = ball0.x + pos1F.x; ball1.y = ball0.y + pos1F.y; ball0.x = ball1.x + pos0F.x; ball0.y = ball1.y + pos0F.y;
衝突した後の、位置を更新して、回転。 ball0,ball1を先ほど回転させたので、それを元に戻している? 位置と同じように、速度も元に戻して終了です。
var vel0F:Object = rotate(vel0.x , vel0.y , sin ,cos ,false); var vel1F:Object = rotate(vel1.x , vel1.y , sin ,cos,false);
ball0.vx = vel0F.x; ball0.vy = vel0F.y; ball1.vx = vel1F.x; ball1.vy = vel1F.y;