package { import Box2D.Collision.b2AABB; import Box2D.Collision.b2ContactPoint; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Collision.Shapes.b2ShapeDef; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2ContactListener; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import caurina.transitions.Tweener; import flash.display.Bitmap; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class KiraKira extends Sprite { // 物理エンジン内の1mを表すためのピクセル数 public static const DRAW_SCALE:Number = 100; // 物理エンジンの管理クラス private var world:b2World; // 星の画像 [Embed(source='star.png')] private static const StarImage:Class; public function KiraKira() { //////////////////////////////////////// // 物理エンジンのセットアップ // 外枠を定義する 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 contactListener:ContactListener = new ContactListener(); contactListener.parent = this; world.SetListener(contactListener); //////////////////////////////////////// // 描画設定 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 | b2DebugDraw.e_jointBit; world.SetDebugDraw(debugDraw); // イベントハンドラを登録する stage.addEventListener(MouseEvent.CLICK, clickHandler); addEventListener(Event.ENTER_FRAME, enterFrameHandler); } // 物と物が接触したときのエフェクトを発生させる public function addContactEffect(point:b2ContactPoint):void { // 星の画像を読み込んで、サイズと位置を調整する var starImage:Bitmap = new StarImage(); starImage.width = 50; starImage.height = 50; starImage.x = -starImage.width / 2; starImage.y = -starImage.height / 2; // 星の画像を表示するためのSpriteを作る // 座標はコンタクトが発生した場所とする var sprite:Sprite = new Sprite(); sprite.x = point.position.x * DRAW_SCALE; sprite.y = point.position.y * DRAW_SCALE; sprite.addChild(starImage); addChild(sprite); // 星が飛んでいく方向と距離をランダムに決める // 角度は0~360度、距離は50~150 var angle:Number = Math.random() * 360; var length:Number = Math.random() * 100 + 50; // 星が飛んでいく先の座標を計算する var dx:Number = sprite.x + length * Math.cos(angle); var dy:Number = sprite.y + length * Math.sin(angle); // Tweenerで星を飛ばす Tweener.addTween(sprite, { time: 3, // 3秒間 scaleX: 0, // 消えるまで縮小する scaleY: 0, alpha: 0, // 完全に透明にする rotation: 200, // 少し回転させる x: dx, y: dy, onComplete: function():void { removeChild(sprite); } }); } private function clickHandler(event:MouseEvent):void { //////////////////////////////////////// // クリックした点からボールを落とします var starDef:b2BodyDef = new b2BodyDef(); starDef.position.Set(event.stageX / DRAW_SCALE, event.stageY / DRAW_SCALE); var starShapeDef:b2CircleDef = new b2CircleDef(); starShapeDef.radius = 0.2; starShapeDef.restitution = 0.3; starShapeDef.density = 1; var star:b2Body = world.CreateDynamicBody(starDef); star.CreateShape(starShapeDef); star.SetMassFromShapes(); } private function enterFrameHandler(event:Event):void { world.Step(1 / 24, 10); } } }