package { import Box2D.Collision.b2AABB; 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 Box2D.Dynamics.Joints.b2Joint; import Box2D.Dynamics.Joints.b2RevoluteJoint; import Box2D.Dynamics.Joints.b2RevoluteJointDef; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.utils.Timer; /** * @author Brett Jephson */ public class Box2DDemo extends Sprite { private var world:b2World; private var joints:Array = []; private var smallBox:b2PolygonDef = new b2PolygonDef(); private var scale:Number = 2.5; private var timer:Timer; public function Box2DDemo() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); defineWorld(); defineObjects(); startTime(); renderDebug(); } private function defineWorld():void { var bounds:b2AABB = new b2AABB(); bounds.lowerBound.Set(-10.0, -10.0); bounds.upperBound.Set(150.0, 150.0); var gravity:b2Vec2 = new b2Vec2(0, 10); var doSleep:Boolean = true; world = new b2World(bounds, gravity, doSleep); b2World.m_positionCorrection = true; b2World.m_warmStarting = true; } private function defineObjects():void { var i:int, j:int = 0; var rowsOfBoxes:int = 7; var columnsOfBoxes:int = 7; // Create a simple weighing scale var box:b2PolygonDef = new b2PolygonDef(); box.SetAsBox(60, 1); box.friction = 1; box.density = 1; var pivotDefinition:b2BodyDef = new b2BodyDef(); pivotDefinition.position.Set(80, 60); var pivot:b2Body = world.CreateBody(pivotDefinition); pivot.CreateShape(box); pivot.SetMassFromShapes(); var revJointData:b2RevoluteJointDef = new b2RevoluteJointDef(); revJointData.Initialize(world.GetGroundBody(), pivot, new b2Vec2(pivot.GetPosition().x, pivot.GetPosition().y)); joints.push(world.CreateJoint(revJointData) as b2RevoluteJoint); // Add lots of little boxes for (; i < rowsOfBoxes; i++) { j = 0; for (; j < columnsOfBoxes; j++) { addBox(40 + (2*i), 10 + (2*j)); } } for (i=0; i < rowsOfBoxes; i++) { j = 0; for (; j < columnsOfBoxes; j++) { addBox(120 - (2*i), 10 + (2*j)); } } } private function startTime():void { timer = new Timer(30); timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0 , true); timer.start(); } private function addBox(x:int, y:int):void { smallBox.SetAsBox(1, 1); smallBox.friction = 1; smallBox.density = 1; var boxDefinition:b2BodyDef = new b2BodyDef(); boxDefinition.position.Set(x, y); var newBox:b2Body = world.CreateBody(boxDefinition); newBox.CreateShape(smallBox); newBox.SetMassFromShapes(); } public function onTimer(e:TimerEvent):void { update(); } private function update():void { world.Step(0.095, 30) } private function renderDebug():void { var debug_draw:b2DebugDraw = new b2DebugDraw(); var debug_sprite:Sprite = new Sprite(); addChild(debug_sprite); debug_draw.m_sprite = debug_sprite; debug_draw.m_drawScale=scale; debug_draw.m_fillAlpha=0.5; debug_draw.m_lineThickness=1; debug_draw.m_drawFlags=b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit; world.SetDebugDraw(debug_draw); } public function dispose():void { while (world.GetBodyList() != null) { var body:b2Body = world.GetBodyList(); world.DestroyBody(body); } while (world.GetJointList() != null) { var joint:b2Joint = world.GetJointList(); world.DestroyJoint(joint); } timer.removeEventListener(TimerEvent.TIMER, onTimer, false); joints = null; } } }