package { import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; public class DrawingCircle extends Sprite { // 物理エンジン内の1mを表すためのピクセル数 private static const DRAW_SCALE:Number = 100; // 物理エンジンの管理クラス private var world:b2World; // 円の中心 private var circleCenter:Point = new Point(); public function DrawingCircle() { //////////////////////////////////////// // 物理エンジンのセットアップ // 外枠を定義する var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-100, -100); worldAABB.upperBound.Set(100, 100); // 重力を下方向に10m/s^2とする var gravity:b2Vec2 = new b2Vec2(0, 10); // 外枠と重力を指定して、物理エンジン全体をセットアップする world = new b2World(worldAABB, gravity, true); //////////////////////////////////////// // 床の設置 // 床は画面の下のほうに設置します // 床の位置を左から2.5m、上から3mとする var floorBodyDef:b2BodyDef = new b2BodyDef(); floorBodyDef.position.Set(2.5, 3); // 床の形を、幅4m、厚さ20cmとする // 指定するのはその半分の値 var floorShapeDef:b2PolygonDef = new b2PolygonDef(); floorShapeDef.SetAsBox(2, 0.1); // 床を動かない物体として作る var floor:b2Body = world.CreateStaticBody(floorBodyDef); floor.CreateShape(floorShapeDef); //////////////////////////////////////// // 描画設定 var debugDraw:b2DebugDraw = new b2DebugDraw(); debugDraw.m_sprite = this; debugDraw.m_drawScale = DRAW_SCALE; // 1mを100ピクセルにする debugDraw.m_fillAlpha = 0.3; // 不透明度 debugDraw.m_lineThickness = 1; // 線の太さ debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit; world.SetDebugDraw(debugDraw); // イベントハンドラを登録する stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); addEventListener(Event.ENTER_FRAME, enterFrameHandler); } private function mouseDownHandler(event:MouseEvent):void { // マウスが押された場所を記憶しておく circleCenter.x = event.stageX; circleCenter.y = event.stageY; } private function mouseUpHandler(event:MouseEvent):void { // 円の中心座標 var x:Number = circleCenter.x / DRAW_SCALE; var y:Number = circleCenter.y / DRAW_SCALE; // 円の中心からマウスが離された位置までの距離 var dx:Number = (event.stageX - circleCenter.x) / DRAW_SCALE; var dy:Number = (event.stageY - circleCenter.y) / DRAW_SCALE; // 円の半径 var radius:Number = Math.sqrt(dx * dx + dy * dy); // 小さすぎる円ができるのを防ぐ if (radius < 0.05) { return; } // 円の場所を設定する var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.position.Set(x, y); // 円の大きさなどを設定する var shapeDef:b2CircleDef = new b2CircleDef(); shapeDef.radius = radius; shapeDef.density = 1; // 密度 [kg/m^2] shapeDef.restitution = 0.5; // 反発係数、通常は0~1 // 円を動く物体として作る var body:b2Body = world.CreateDynamicBody(bodyDef); body.CreateShape(shapeDef); body.SetMassFromShapes(); } private function enterFrameHandler(event:Event):void { // Flashはデフォルトで秒間24フレームなので、 // 物理シミュレーションを1/24秒進める world.Step(1 / 24, 10); } } }