package{ import flash.display.Sprite; import flash.events.Event; // Classes used in this example import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; public class GroundPositionAndSize extends Sprite { public var m_world:b2World; public var m_physScale:Number = 100; public var m_iterations:int = 10; public var m_timeStep:Number = 1 / 30; public function GroundPositionAndSize() { // Add event for main loop addEventListener(Event.ENTER_FRAME, Update, false, 0, true); ///////////////////////////////////////////// // // // Create a World // // // ///////////////////////////////////////////// // Creating a World // Every Box2D program begins with the creation of a world object. // This is the physics hub that manages memory, objects, and simulation. // Let's define a bounding box for the world. Box2D // Size of Flash Stage: width = 512 pixel, height = 384 pixel // In this world: // 1 meter = 100 pixels (Define in debugDraw.m_drawScale = 100;) // i.e. 5.12 meter (width) x 3.84 meter (height) // There is really no need to create a SUPER HUGE world while you // only play within a very small bounded area. This will waste // your computer resources and lower down the animation performance. // Therefore create the world according to your requirement, not // big is better than small. var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-10.0, -10.0); worldAABB.upperBound.Set(10.0, 10.0); // Gravity of the world // (x-direction e.g. wind blow, y-direction e.g. earth gravity) // In our real world, gravity is 10 m per square second var gravity:b2Vec2 = new b2Vec2(0.0, 5.0); // Allow bodies to sleep // This tell the world to allow bodies to sleep when they come to rest. // A sleeping body doesn't require any simulation. var doSleep:Boolean = true; // Create the world object // Our world object stores all Body Definitions and physics // settings. Everything happens within here. m_world = new b2World(worldAABB, gravity, doSleep); //////////////////////////////////////////////////// // So now we have our physics world, // // let's start adding some stuff to it. // //////////////////////////////////////////////////// // Vars used to create bodies // Your Body Definitions store shapes, mass, friction, and elasticity // (bouncyness) info. The world object only takes bodies, not shapes. var bodyDef:b2BodyDef; var body:b2Body; var boxDef:b2PolygonDef; /////////// Ground Box (earth or floor) /////////// // Now we have our world. There is nothing in our world. // The first thing we need to add is the ground (earth or floor) // SCOPE: create the ground body (or Floor). // we need a body definition. With the body definition we specify // the initial position of the ground body. // Note that the ground object has no density like the later // definitions. That's because it is static and we don't want it // effected by any forces. // STEP 1: Define the body bodyDef = new b2BodyDef(); // STEP 2: Position of Floor (CENTER POINT) // bodyDef.position.Set(2.55, 3.6); // bodyDef.position.Set(x-from left of stage, y-from top of stage); // 1 meter = 100 pixel // i.e. x = 255 pixel, y = 360 pixel // i.e. the CENTER POINT of floor is: // 255 from the left and // 360 from top bodyDef.position.Set(2.55, 3.6); // STEP 3: Create a ground polygon definition. boxDef = new b2PolygonDef(); // STEP 4: Set the Size of box // 1 meter = 100 pixels // i.e. width = 2 x 2 x 100 = 400 pixel, // height = 0.6 x 2 x 100 = 120 pixel // NOTE: // The size count from the CENTER POINT of the floor (2.55, 3.6) // or (255, 360) // This can use to calculate the surface of floor, e.g. // 0.3 = 0.3 x 100 = 30 above 360 (i.e. y = 330) // 0.6 = 0.6 x 100 = 60 above 360 (i.e. y = 300) // 0.9 = 0.9 x 100 = 90 above 360 (i.e. y = 270) // Now: // The surface of ground is at y-300 // In other words, falling box will drop to y-300, rebounce and rest boxDef.SetAsBox(2, 0.6); // Now the ground has been defined and set. The falling box will fall // and rebounce according to above definition and setting. // However the ground is now just an INVISIBLE box. We want // the user see the ground. The following codes allow user to see // the ground: // bodyDef.userData = new PhysGround(); // bodyDef.userData.width = 2 * 2 * 100; // bodyDef.userData.height = 0.6 * 2 * 100; // addChild(bodyDef.userData); // Actually you can comment the above four lines and the falling box // still fall and rebounce as usual. /* // In order to show the position of center point of floor and size of floor // STEP 5 - STEP 7 are commented. // STEP 5: Add sprite to body userData // We have a Sprite object in the library called PhysGround. // Here we are associating that with our body definition. bodyDef.userData = new GroundBox(); // STEP 6: Set Size of our body (GroundBox) // Size of box is (2, 0.6) // Makes sure the width and height match the Size of Polygon (boxDef) bodyDef.userData.width = 2 * 2 * 100; // Half-Height * 2 * PhyScale // 0.6 come from the y of boxDef.SetAsBox(2, 0.6) bodyDef.userData.height = 0.6 * 2 * 100; // STEP 7: Add body to sprite so that we can see it addChild(bodyDef.userData); */ // STEP 8: The body definition is passed to the world object to create the ground body. // The world object does not keep a reference to the body definition. // The ground body is created as a static body. Static bodies don't collide with // other static bodies and are immovable. Box2D determines that a body is static // when it has zero mass. Bodies have zero mass by default, therefore they are static by default. body = m_world.CreateBody(bodyDef); // STEP 9: Create the ground polygon shape on the ground body. // We finish the ground body by creating the ground polygon shape on the ground body. body.CreateShape(boxDef); //////////////////////////////////////////////////////////////// // Creating a Dynamic Body // // So now we have a ground body. // // We can use the same technique to create a dynamic body. // //////////////////////////////////////////////////////////////// // So now we have a ground body. We can use the same technique to // create a dynamic body. The main difference, besides dimensions, // is that we must establish the dynamic body's MASS properties. // SCOPE: create the falling box // we need a body definition. With the body definition we specify // the initial position of the ground body. // STEP 1: Define the falling box body bodyDef = new b2BodyDef(); // STEP 2: Position of falling box // Remember that in this world: // 1 meter = 100 pixels // 3.5 meters (or 350 pixels from the left side) // 1.0 meters (or 100 pixels from the top) // You can also use: //bodyDef.position.x = 3.5; //bodyDef.position.y = 1; bodyDef.position.Set(3.5, 1) // STEP 3: Create a polygon definition. boxDef = new b2PolygonDef(); // STEP 4: Set the Size of the polygon // 1 meter = 100 pixels // i.e. width = 0.4 x 2 x 100 = 80 pixel, // height = 0.2 x 2 x 100 = 40 pixel // Why x 2? // Because the size is calculated from the center point boxDef.SetAsBox(0.4, 0.2); // STEP 5: Define density // The default density is zero if not specify // Unit is kg per square meter boxDef.density = 1.0; // STEP 6: Define restitution // Restitution is how elastic or how bouncy the shape is // Range: 0 - 1 // In this example, it will refer to bouncy // 0 -> no bouncy // 1 -> very bouncy boxDef.restitution = 0.8; // STEP 7: Define friction //Friction should be between 0 and 1 // Range: 0 - 1 // 0 -> no friction // 1 -> very rough surface with high friction boxDef.friction = 0.5; // STEP 8: Add sprite to body userData // We have a Sprite object in the library called PhysBox. // Here we are associating that with our body definition. bodyDef.userData = new FallBox(); // STEP 9: Set Size of our body (FallBox) // Size of box is (0.4, 0.2) // Makes sure the width and height match the Size of Polygon (bodyDef) // width and height of box // Check STEP 4: boxDef.SetAsBox(0.4, 0.2) bodyDef.userData.width = 0.4 * 2 * 100; bodyDef.userData.height = 0.2 * 2 * 100; // STEP 10: Add body to sprite so that we can see it addChild(bodyDef.userData); // STEP 11: The shape is attached. // We instruct the body to compute it's mass properties from the // attached shapes using the method SetMassFromShapes. // You can attach more than one shape per body. If the computed // mass is zero, then the body becomes truly static. Bodies have // a mass of zero by default, that's why we didn't need to call // SetMassFromShapes for the ground body. body = m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); ///////////////////////////////////////////// // // // Debug Drawing // // // ///////////////////////////////////////////// // You can implement the b2DebugDraw class to get // detailed drawing of the physics world. // Uncomment the following block of codes if you // wish to use Debug Drawing /* var dbgDraw:b2DebugDraw = new b2DebugDraw(); var dbgSprite:Sprite = new Sprite(); addChild(dbgSprite); dbgDraw.m_sprite = dbgSprite; dbgDraw.m_drawScale = 30.0; dbgDraw.m_fillAlpha = 0.0; dbgDraw.m_lineThickness = 1.0; dbgDraw.m_drawFlags = 0xFFFFFFFF; m_world.SetDebugDraw(dbgDraw); */ } ///////////////////////////////////////////// // // // Simulating the World (of Box2D) // // // ///////////////////////////////////////////// public function Update(e:Event):void{ //m_timeStep is the Frame rate //m_iterations = how many times do the calculation 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.GetPosition().x * m_physScale; bb.m_userData.y = bb.GetPosition().y * m_physScale; bb.m_userData.rotation = bb.GetAngle() * (180 / Math.PI); } } } } }