Wwwebber's Blog

Box2d 2.1 b2world.QueryPoint() and iterating over a b2fixture list

Posted in actionscript 3, Box2d by wwwebber on May 20, 2010

In version 2.1 (and earlier I believe) of box2d objects are stored in linked lists. A common task will be iterate over one of these linked lists. For instance if you want to iterate over a body’s b2fixture linked list. In my case, I had the following problem: I was making a kids math game on how to combine like terms called Rj The Robot , and I only wanted the robot to jump if it was standing on a ‘floor’ shape. Now all ‘foors’ in the game had a string attached to their b2fixture called ‘is_floor’. Below is some code that demonstrates how floor bodies, shapes and fixtures are creating. Note: if you don’t know what a b2fixture is read this.

//bottom wall
var bottom_wallShape:b2PolygonShape = new b2PolygonShape();
var bottom_wallBd:b2BodyDef = new b2BodyDef();
bottom_wallBd.type = b2Body.b2_staticBody;
var bottom_wallBody:b2Body;
bottom_wallBd.position.Set(halfOfStageWidth /PIXELS_PER_METER , halfOfStage*2/ PIXELS_PER_METER- .5 );
bottom_wallShape.SetAsBox(ground_width, ground_height);
bottom_wallBody = myB2World.CreateBody(bottom_wallBd);


var fd:b2FixtureDef = new b2FixtureDef();
fd.friction = 1 ;
fd.shape = bottom_wallShape;
fd.userData = 'is_floor';
bottom_wallBody.CreateFixture(fd);


Now, I wanted the hero to be able to tell if it was standing on a shape whose b2fixture had the string ‘is_floor’ as its userdata. The solution is to use the b2World.QueryPoint() function . This function takes the form of myb2World.QueryPoint(callbackFunction, someB2Vec) where the someB2Vec is the point to check.  In the picture below I was sending the red dot, called heroFootPoint in my code, to the function. Below is the full code explained in the comments
//get hero's center point
var currentCenter:b2Vec2 = _body.GetWorldCenter();
heroFootPoint.x = currentCenter.x
heroFootPoint.y = currentCenter.y + 1.43    //add 1.43 so point is below Robot  foot;
var bIsOnFloor:Boolean = false;             //assume not standing on floor

function bOnFloorFixture(fixture:b2Fixture):Boolean    //call back function
{                                                                                                               //this call back function
var body:b2Body = b2Fixture(fixture).GetBody();            //get body of current fixture
var bsFixture:b2Fixture = body.GetFixtureList();
while (bsFixture != null )                                                                 //it
{
if (bsFixture.GetUserData() == ‘is_floor’)                  //found a fixture whose userdata is ‘is_floor’…ie are standing on the floor
{
bIsOnFloor = true;
return false;                                                                           //return false so that we don’t continue iterating over the list
}
bsFixture = bsFixture.GetNext();                              //if we got here we didn’t yet find a fixture with ‘is_floor’ userdat..

}                                                                                              //so see if body has another b2fixture attached for checking

return true;                                                                                    //callback returns true means that the queryWorld() function will check next b2Fixture at heroFootPoint
}
myB2World.QueryPoint(bOnFloorFixture, heroFootPoint);               //start queryPoint()…check all fixtures overlapping heroFootPoint

Comments Off on Box2d 2.1 b2world.QueryPoint() and iterating over a b2fixture list

Upgrading to Box2D 2.1 (Flash)

Posted in Uncategorized by wwwebber on May 11, 2010

Box2d 2.1 offers several improvements in its use of events, its object models and added features like buoyancy, over 2.02 but you’ll find that none of your code compiles anymore.

Read this post about fixtures
Read this forum post about the new and improved contact listener
2.1 a documentation
Other changes

Version 2.02 Version 2.1
myB2body.WakeUp() myB2Body.SetAwake(true)

Gone and Not Necessarily Missed

  • myB2Body.SetMassFromShapes() //apparently done automatically
  • declaring a size of your   B2World() . Create a world with new b2World(GRAVITY_VECTOR,  doSleep ) Notice the lack of a b2aab for the world size!

New and Very Welcome

The new contactListner is vastly improved and would take a whole post in itself to explain, but it’s a very welcome improvement

I’ll add other small feature changes as I stumble upon them while working on my new kids game: RJ the Robot ( math based platform game)

Comments Off on Upgrading to Box2D 2.1 (Flash)