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

Advertisements

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

%d bloggers like this: