package { import flash.display.Sprite; import flash.display.MovieClip; import flash.events.*; import flash.events.MouseEvent; // Classes used in this example import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; public class ObstacleFall2 extends Sprite{ public var m_world:b2World; public var m_iterations:int = 10; public var m_timeStep:Number = 1/30; public var GRAVITY_AMOUNT = 250.0; //public var GRAVITY_AMOUNT = 50.0; //////////////////////////////////////////////////////////////////////////////////////// public function ObstacleFall2() { // This is the constructor. // STAGE PROPERTIES //stage.scaleMode = StageScaleMode.NO_SCALE; //stage.align = StageAlign.TOP_LEFT; //stage.quality = "low"; // Creat world AABB var worldAABB:b2AABB = new b2AABB(); //worldAABB.minVertex.Set(-1000.0, -1000.0); //worldAABB.maxVertex.Set(1000.0, 1000.0); // try to make this work with stage variables worldAABB.minVertex.Set (0, 0); worldAABB.maxVertex.Set (stage.stageWidth, stage.stageHeight); // Define the gravity vector var gravity:b2Vec2 = new b2Vec2(0.0, GRAVITY_AMOUNT); // Allow bodies to sleep var doSleep:Boolean = true; // Construct a world object m_world = new b2World(worldAABB, gravity, doSleep); stage.addEventListener (Event.ADDED, initStageBodies); stage.addEventListener (MouseEvent.CLICK, mouseClickHandle); //`stage.addEventListener (KeyboardEvent.KEY_UP, keyUpHandler); } //////////////////////////////////////////////////////////////////////////////////////// public function addGroundBody (spr:Sprite):void { // This method encapsulates adding a new ground body to the world definition. // Vars used to create bodies var bodyDef:b2BodyDef; var boxDef:b2BoxDef; var circleDef:b2CircleDef; // Add ground body bodyDef = new b2BodyDef(); boxDef = new b2BoxDef(); bodyDef.userData = spr; boxDef.extents.Set(bodyDef.userData.width / 2, bodyDef.userData.height / 2); boxDef.friction = 0.3; bodyDef.position.Set(bodyDef.userData.x, bodyDef.userData.y); bodyDef.AddShape(boxDef); addChild(bodyDef.userData); m_world.CreateBody(bodyDef); } //////////////////////////////////////////////////////////////////////////////////////// public function addNewCircleBody (_x, _y):void { trace ("addNewCircleBody: "+_x+", "+_y); // Vars used to create bodies var bodyDef:b2BodyDef; var boxDef:b2BoxDef; var circleDef:b2CircleDef; bodyDef = new b2BodyDef(); // Circle circleDef = new b2CircleDef(); circleDef.radius = 30; circleDef.density = 1.0; circleDef.friction = 0.3; circleDef.restitution = 0.1; bodyDef.AddShape(circleDef); bodyDef.userData = new PhysCircle(); // this is the object in the library bodyDef.userData.width = circleDef.radius * 2; bodyDef.userData.height = circleDef.radius * 2; bodyDef.position.x = _x - circleDef.radius/2; bodyDef.position.y = _y - circleDef.radius/2; //bodyDef.userData.x = _x; //bodyDef.userData.y = _y; m_world.CreateBody(bodyDef); addChild(bodyDef.userData); } //////////////////////////////////////////////////////////////////////////////////////// public function mouseClickHandle (e:Event) { addNewCircleBody (mouseX, mouseY); } public function keyUpHandler (e:Event) { // To Do: // Figure out how to simply reverse gravity; trace ("keyUpHandler"); // Creat world AABB var worldAABB:b2AABB = new b2AABB(); //worldAABB.minVertex.Set(-1000.0, -1000.0); //worldAABB.maxVertex.Set(1000.0, 1000.0); // try to make this work with stage variables worldAABB.minVertex.Set (0, 0); worldAABB.maxVertex.Set (stage.stageWidth, stage.stageHeight); GRAVITY_AMOUNT = GRAVITY_AMOUNT * -1; var gravity:b2Vec2 = new b2Vec2(0.0, GRAVITY_AMOUNT); // Allow bodies to sleep var doSleep:Boolean = true; // Construct a world object m_world = new b2World(worldAABB, gravity, doSleep); } //////////////////////////////////////////////////////////////////////////////////////// public function drawObstacles ():void { // This method draws the obstacles that the balls will fall through. var boxwidth = 2; var boxspacing = 80; var xpos = boxspacing; var ypos = 100; var tmpsprt:Sprite; for (var i=0; i < 12; i++) { tmpsprt = new Sprite(); tmpsprt.graphics.beginFill(0x000000); tmpsprt.graphics.drawRect(-boxwidth/2, -boxwidth/2,boxwidth,boxwidth); tmpsprt.graphics.endFill(); tmpsprt.x = xpos; tmpsprt.y = ypos; xpos += boxspacing; if (xpos >= stage.stageWidth) { xpos = boxspacing + 25; ypos += boxspacing; } addGroundBody (tmpsprt); } for (var i=0; i < 12; i++) { tmpsprt = new Sprite(); tmpsprt.graphics.beginFill(0x000000); tmpsprt.graphics.drawRect(-boxwidth/2, -boxwidth/2,boxwidth,boxwidth); tmpsprt.graphics.endFill(); tmpsprt.x = xpos; tmpsprt.y = ypos; xpos += boxspacing; if (xpos >= stage.stageWidth) { xpos = boxspacing + 25; ypos += boxspacing; } addGroundBody (tmpsprt); } } //////////////////////////////////////////////////////////////////////////////////////// public function createSomeObjects ():void { // This method creates some physics objects (ie the balls that fall). // Add some objects for (var i:int = 1; i < 3; i++){ addNewCircleBody(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight * 2/3); } } //////////////////////////////////////////////////////////////////////////////////////// public function initStageBodies (e:Event):void { // This method is triggered by the event: // stage.addEventListener(Event.ADDED, initStageBodies); // This was the only way I could get the objects on the stage to have references. trace ("initStageBodies"); stage.removeEventListener (Event.ADDED, initStageBodies); addGroundBody (PhysGround); addGroundBody (PhysGroundLeft); addGroundBody (PhysGroundRight); drawObstacles(); //createSomeObjects(); // Add event for main loop addEventListener(Event.ENTER_FRAME, Update, false, 0, true); } //////////////////////////////////////////////////////////////////////////////////////// public function Update(e:Event):void { // This is the main loop of the program. m_world.Step(m_timeStep, m_iterations); // Go through body list and update sprite positions/rotations for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next){ if (bb.m_userData is Sprite){ bb.m_userData.x = bb.m_position.x; bb.m_userData.y = bb.m_position.y; bb.m_userData.rotation = bb.m_rotation * (180/Math.PI); } } } } }