Adding Bodies to the World

Box2D for Flash Games


November 2012

$14.99

Create amazing and realistic physics-based Flash games using Box2D with this book and ebook.

(For more resources related on Spring, see here.)

Creating a fixture

A fixture is used to bind the shape on a body, and to define its material setting density, friction, and restitution.

  1. The first step is to create the fixture:

    var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape=circleShape;

    Once we have created the fixture with the constructor, we assign the previously created shape using the shape property.

  2. Finally we are ready to add the ball to the world:

    var theBall:b2Body=world.CreateBody(bodyDef); theBall.CreateFixture(fixtureDef);

    b2Body is the body itself: the physical, concrete body that has been created using the bodyDef attribute.

  3. To recap, use the following steps when you want to place a body in the world:

    i. Create a body definition, which will hold body information such as its position.

    ii. Create a shape, which is how the body will look.

    iii. Create a fixture to attach the shape to the body definition.

    iv. Create the body itself in the world using the fixture.

    Once you know the importance of each step, adding bodies to your Box2D World will be easy and fun.

  4. Back to our project. The following is how the class should look now:

    package {
    import flash.display.Sprite;
    import flash.events.Event;
    import Box2D.Dynamics.*;
    import Box2D.Collision.*;
    import Box2D.Collision.Shapes.*;
    import Bo x2D.Common.Math.*;
    public class Main extends Sprite {
    private var world:b2World;
    private var worldScale:Number=30;
    public function Main() {
    world=new b2World(new b2Vec2(0,9.81),true);
    var bodyDef:b2BodyDef=new b2BodyDef();
    bodyDef.position.Set(320/worldScale,30/worldScale);
    var circleShape:b2CircleShape;
    circleShape=new b2CircleShape(25/worldScale);
    var fixtureDef:b2FixtureDef = new b2FixtureDef();
    fixtureDef.shape=circleShape;
    var theBall:b2Body=world.CreateBody(bodyDef);
    theBall.CreateFixture(fixtureDef);
    addEventListener(Event.ENTER_FRAME,updateWorld);
    }
    private function updateWorld(e:Event):void {
    world.Step(1/30,10,10);
    world.ClearForces;
    }
    }
    }

Time to save the project and test it. Ready to see your first Box2D body in action? Run the movie!

Ok, it did not display anything. Before you throw this article, let me tell you that Box2D only simulates the physic world, but it does not display anything.

This means your body is alive and kicking in your Box2D World; it's just that you can't see it.

Creating a box shape

Let's perform the following steps:

  1. First, body and fixture definitions can be reassigned to define our new body. This way, we don't need to declare another bodyDef variable, but we just need to reuse the one we used for the creation of the sphere by changing its position:

    bodyDef.position.Set(320/worldScale,470/worldScale);

    Now the body definition is located in the horizontal center, and close to the bottom of the screen.

  2. To create a polygon shape, we will use the b2PolygonShape class :

    var polygonShape:b2PolygonShape=new b2PolygonShape();

    This way we create a polygon shape in the same way we created the circle shape earlier.

  3. Polygon shapes must follow some restrictions, but at the moment because we only need an axis-aligned box, the SetAsBox method is all we need.

    polygonShape.SetAsBox(320/worldScale,10/worldScale);

    The method requires two arguments: the half-width and the half-height of the box. In the end, our new polygon shape will have its center at pixels (320, 470), and it will have a width of 640 pixels and a height of 20 pixels—just what we need to create a fl oor.

  4. Now we change the shape attribute of the fixture definition, attaching the new polygon shape:

    fixtureDef.shape=polygonShape;

  5. Finally, we can create the world body and embed the fixture in it, just like we did with the sphere.

    var theFloor:b2Body=world.CreateBody(bodyDef); theFloor.CreateFixture(fixtureDef);

  6. The following is how your Main function should look now:

    public function Main() {
    world=new b2World(new b2Vec2(0,9.81),true);
    var bodyDef:b2BodyDef=new b2BodyDef();
    bodyDef.position.Set(320/worldScale,30/worldScale);
    var circleShape:b2CircleShape;
    circleShape=new b2CircleShape(25/worldScale);
    var fixtureDef:b2FixtureDef=new b2FixtureDef();
    fixtureDef.shape=circleShape;
    var theBall:b2Body=world.CreateBody(bodyDef);
    theBall.CreateFixture(fixtureDef);
    bodyDef.position.Set(320/worldScale,470/worldScale);
    var polygonShape:b2PolygonShape=new b2PolygonShape();
    polygonShape.SetAsBox(320/worldScale,10/worldScale);
    fixtureDef.shape=polygonShape;
    var theFloor:b2Body=world.CreateBody(bodyDef);
    theFloor.CreateFixture(fixtureDef);

    var debugDraw:b2DebugDraw=new b2DebugDraw();
    var debugSprite:Sprite=new Sprite();
    addChild(debugSprite);
    debugDraw.SetSprite(debugSprite);
    debugDraw.SetDrawScale(worldScale);
    debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
    debugDraw.SetFillAlpha(0.5);
    world.SetDebugDraw(debugDraw);
    addEventListener(Event.ENTER_FRAME,updateWorld);
    }

  7. Test the movie and you'll see the floor:

Different body types — static, dynamic, and kinematic

There are three types of Box2D bodies: static, dynamic, and kinematic.

A static body does not react to any force, impulse, or collision and does not move. A static body can only be moved manually by the user. By default, every Box2D body is a static body, and that's why the ball does not move. A static body also does not collide with other static or kinematic bodies.

A dynamic body reacts to forces, impulses, collisions, and any other world event. Dynamic bodies can also be moved manually, although I'd suggest to let them be moved by world forces, and collide with all body types.

A kinematic body is something hybrid between a static and a dynamic body. Kinematic bodies do not react to forces, but can be moved both manually and by setting their velocity. Kinematic bodies do not collide with other static or kinematic bodies.

Back to our simulation now. Which type of body would you assign to the ball and the fl oor?

The floor must be a static body, as it does not have to move, while the ball will be a dynamic body to be moved by world forces.

To tell Box2D the type of each body, you just have to set the type property of the body definition, which can be b2Body.b2_staticBody, b2Body.b2_dynamicBody, or b2Body.b2_kinematicBody respectively for static, dynamic, or kinematic bodies.

Your new Main function is shown as follows:

public function Main() {
world=new b2World(new b2Vec2(0,9.81),true);
var bodyDef:b2BodyDef=new b2BodyDef();
bodyDef.position.Set(320/worldScale,30/worldScale);
bodyDef.type=b2Body.b2_dynamicBody;
var circleShape:b2CircleShape;
circleShape=new b2CircleShape(25/worldScale);
var fixtureDef:b2FixtureDef=new b2FixtureDef();
fixtureDef.shape=circleShape;
var theBall:b2Body=world.CreateBody(bodyDef);
theBall.CreateFixture(fixtureDef);
bodyDef.position.Set(320/worldScale,470/worldScale);
bodyDef.type=b2Body.b2_staticBody;
var polygonShape:b2PolygonShape=new b2PolygonShape();
polygonShape.SetAsBox(320/worldScale,10/worldScale);
fixtureDef.shape=polygonShape;
var theFloor:b2Body=world.CreateBody(bodyDef);
theFloor.CreateFixture(fixtureDef);
var debugDraw:b2DebugDraw=new b2DebugDraw();
var debugSprite:Sprite=new Sprite();
addChild(debugSprite);
debugDraw.SetSprite(debugSprite);
debugDraw.SetDrawScale(worldScale);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
debugDraw.SetFillAlpha(0.5);
world.SetDebugDraw(debugDraw);
addEventListener(Event.ENTER_FRAME,updateWorld);
}

Now the ball should fall down. Test the movie and see:

Before the congratulations for running your first simulation, let me spend to say a couple of words about different colors you will see when using the debug draw.

Static bodies will be drawn in green. Dynamic bodies will be drawn in red when they're not sleeping and in gray where they are put to sleep. Kinematic bodies, will be drawn with blue.

Now it should also clear the concept of putting bodies to sleep and saving CPU work. As you can see, when the ball hits the ground, no other forces are acting on it, so it can be put to sleep until something happens.

Now, a new problem. The ball did not bounce. We need to give our bodies some more attributes if we want to run a complete simulation.

Summary

In this article, we learned how to create fixture, box shape and used them to design levels of successful games, such as Totem Destroyer.


Resources for Article :


Further resources on this subject:


Books to Consider

comments powered by Disqus