Friday, January 18, 2008

Actionscript 2D Physics Engine : pEngine

In response to my review of the available Actionscript 2D Physics Engines I received a comment from the YAAB (Yet Another Actionscript Blog) regarding a 2D Physics Engine they are working on called pEngine. This engine is a port of the Chipmunk engine from C. At the moment there are some interesting looking demos and not much else. But if you are interested in Flash physics it may be worthwhile bookmarking the YAAB feed.

Thursday, January 17, 2008

Box2DFlashAS3 : Detecting Jack-in-the-Box Collisions

In my last post we started looking at the basics of using Box2DFlashAS3. We saw that you needed to listen for enterFrame events and use this event to update the position of the Sprites representing your Physics Bodies. This post I want to consider how you'd deal with special cases. For example, when you have a Body that needs to respond to a collision in a unique way. Imagine a ball falling onto a Jack-in-the-Box and triggering the box to spring open. The ball will be thrown up and to one side. This sort of response can't be represented by manipulating the elasticity of the two Bodies. The question is how would you detect and respond to the ball colliding with these bodies.

Our Jack-in-the-Box simulation has one special object: the ball. We want to take action when the ball collides with a special object (i.e the Jack-in-the-Box). The ball is a standard b2Body and it maintains a list of what it is in contact with. You can access this list using ball.GetContactList() to return a b2ContactNode. The first body in the list can be accessed using b2ContactNode's "other" property (I assume you can move through the list of contacts using "next" and "prev" but I haven't needed to test this yet). You can then check if this is a b2Body that needs a response. For example, if we have a b2Body called jack we could check if it is in contact with our ball like this :

var c_ball:b2ContactNode = this.ball.GetContactList();
var o_contact:b2Body = c_ball.other;

if(this.jack == o_contact)
{
var vec:b2Vec2 = new b2Vec2(200,-400);
this.ball.SetLinearVelocity(vec);
}

In this example, we test if the body in contact with the ball is jack. If true we set a new force that moves the ball up and to the right. In my simulation it is unlikely that the ball will collide with multiple special objects at the same time. So I'm happy to assume that there will only be one body in the contact list. If your ball will be in contact with multiple bodies you will want to check all bodies in the contact list.

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.

Wednesday, January 16, 2008

Melbourne Flex 3/AIR Pre-release event

Added 18/01/08 : Demand for this event has out stripped expectations and the number of registered attendees has exceeded the venues capacity. If you registered prior to this addition then you should receive an invitation confirming you've registration and providing venue details.

Last week I posted regarding the possibility of Danny Dura coming to Melbourne for a Flex 3/AIR Pre-release event. Well it's confirmed now. This will be a great opportunity for the uninitiated to discover what Flex has to offer and for Flex developers to see first hand the many new features of Flex 3. Attendees will go in the draw for a copy of CS3 Web Premium and Flex Builder 3 Professional.

If you'd like to find out more about Danny Dura then take a look at http://www.danieldura.com/.

Event date and details removed; these will be provided in an invitation email.

Blogged with Flock

Friday, January 11, 2008

Actionscript 2D Physics Engines : Motor 2

This post is part of a series reviewing the available Actionscript 2D Physics Engines. Each engine was tested through the development of three simple simulations; Hello World, Rope Bridge and Stunt Bike. You can find out more about the testing methodology and access the other reviews from the introduction post.

Motor 2 screenshot

Motor 2 is the newest of the Actionscript 2D Physics Engines. Like Box2DFlashAS3 it is a port of Erin Catto's C++ physics library Box2D. Though it is probably more accurate to call it a series of variations on Box2D's themes as Michael Baczynski has exchanged some of Catto's libraries for his own.

I want to start by saying this isn't a review in the same sense as my posts on the other engines. The current Motor 2 release is just a preview. Major features like joints/constraints still need to be implemented. From my perspective that means I couldn't build 2 out of 3 of the test simulations (both Rope Bridge and Stunt Bike require joints). Consequently I haven't built anything with Motor 2. What I offer here is some observations based on looking at the demos and staring at the available code long enough to know where to start building a simulation. I offer this post from the perspective of someone who has spent quite a few hours with the other available engines and is therefore able to make some comparative observations. But really it is a placholder awaiting a more complete release.

So what can I say about Motor 2?

On the up side the demos suggest that the engine will be reasonable fast and accurate. The demo code suggests that Motor 2 is much cleaner than Box2DFlashAS3 and consequently will be easier to pick up (I suspect it will have a similar learning curve to FOAM). Another plus is that the source code is commented. The commenting isn't as comprehensive as APE or FOAM but it's still a vast improvement over Box2DFlashAS3.

On the down side we have no documentation outside the code. The demos are too simple to give us an idea of the engines potential and there is no roadmap to indicate what a full feature set will include.

In summary, I'd say that Motor 2 shows a lot of promise but that it's too early to make a call. I look forward to a more complete release so I can run a few tests and review these observations.