Thursday, January 17, 2008

Box2DFlashAS3 : Getting Started

The last couple of weeks I've been trialling and reviewing the available Actionscript 2D Physics Engines. The outcome of all this research is that I've settled on Box2DFlashAS3 (referred to as Box2D for the rest of this post) as the most mature of the available engines. Today I'd thought it best to give an overview of the basics that are required to start developing with Box2D. The basic steps are :

  • define the b2AABB and it's boundaries
  • define a gravity vector
  • create the world and pass it the AABB and gravity objects
  • create bodies and add them to your world (not covered here)
  • create an enter frame event listener for updating your world

Thats the overview so let's take a look at the details. The code below is pretty much how it appears in the sample files but it's straight forward enough not to need changing :

//from your Classes constructor
// Create the world AABB
var worldAABB:b2AABB = new b2AABB();
worldAABB.minVertex.Set(-1000.0, -1000.0);
worldAABB.maxVertex.Set(1000.0, 1000.0);

// Define the gravity vector
var gravity:b2Vec2 = new b2Vec2(0.0,800.0);

You'll find yourself using the b2Vec2 Class a lot. Essentially whenever we define a force for the world or for a body or set the position of a body b2Vec2 will be a required parameter. It essentially has "x" and "y" properties which are either used as a force for that axis or a position for a body based on context. In this case we are defining gravity so we want a force along the y axis. The amount of gravity you need is effected by your projects frame rate and the speed you generally want things to happen. FOAM has a zero gravity example to implement a similar simulation in Box2D you would set the vectors y value to 0.

// Allow bodies to sleep
var doSleep:Boolean = true;
// Construct a world object
world = new b2World(worldAABB, gravity,doSleep);
//start listening for enter frame events
this.addEventListener(Event.ENTER_FRAME, Update);

private function Update(event:Event):void
world.Step(timeStep, iterations);
// Render bodies
// Go through body list and update sprite positions/rotations
for (var bb:b2Body = 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 = degrees(bb.m_rotation);

The world's m_bodyList is an array of b2Body objects. Each b2Body's userData represents the Sprite or MovieClip used to represent the b2Body. At each step the world calculates the positions and interactions of each b2Body. It's then up to you to update the userData's position. An update mechanism is provided by most of the other engines but Box2D expects you to manage this updates yourself. What is important to note is that changing a b2Body's position or rotation doesn't change it Sprites position and rotation. Therefore, if you want to manually move a Body then you will also need to manually move the userData's position.

These are the basics of getting started with Box2D. What's missing from this post is how you actually add Bodies to your world. Adding a Body in Box2D takes almost as much code as setting up the world and updating it. So it seemed best to save that for another post.

No comments: