# Introduction to Box2D for Flash and AS3

##### Tutorial Details
• Difficulty: Intermediate
• Platform: Flash (Flash Player 9)
• Language: AS3
• Software used: Flash Pro CS3 and FlashDevelop, but you can use any AS3 compiler and editor
This entry is part 1 of 3 in the series Box2D for Flash and AS3

Box2D is a popular physics engine with a solid Flash port, which was used to create the excellent game Fantastic Contraption. In this tutorial, the first of a series, you’ll get to grips with the basics of Box2D 2.1a for Flash and AS3.

## Step 1: The Boring Setup

I’m going to assume you already know how to set up a basic Flash project using your editor and workflow of choice, whether that means creating a FLA with a document class, a pure AS3 project in a different editor, or whatever. I’m using FlashDevelop, but you should use whatever you feel comfortable with.

Create your project, and name the main class Main.as. Give it some boilerplate code; mine looks like this:

package
{
import flash.display.Sprite;
import flash.events.Event;

public class Main extends Sprite
{

public function Main():void
{
if (stage) init();
}

private function init(e:Event = null):void
{
getStarted();
}

private function getStarted():void
{

}

}

}


Don’t worry about the [Frame] metatag — that’s just how FlashDevelop creates a preloader. All you need to know is that getStarted() is run when the SWF has fully loaded. Create a function of the same name that runs when your Main class has loaded.

I’m also going to assume you’re comfortable with using a separate library or API in your project. Download Box2DFlash 2.1a from this page (I’m using the Flash 9 version), and extract the zip to wherever you normally put your APIs. Next, add a classpath to point to the \Source\ folder from the zip. Alternatively, you could just extract the contents of the \Source\ folder to the same directory as your Main class.

Great! That was easy. Let’s start using Box2D.

## Step 2: A Whole New b2World

“If you want to make an apple pie from scratch, you must first create the universe,” wrote Carl Sagan; if we want to make a few physics objects, we only need to create a world.

In Box2D, a world is not a planet or an ecosystem; it’s just the name given for the object that manages the overall physics simulation. It also sets the strength of gravity — not just how quickly objects accelerate but also in which direction they fall.

We’ll create a vector to set the gravity before creating the world itself:

import Box2D.Common.Math.b2Vec2;

//...

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
}


A b2Vec2 is a Box2D Euclidean vector (the second 2 stands for 2D again, because it’s possible to have a 3D Euclidean vector). Daniel Sidhion wrote an excellent tutorial explaining what Euclidean vectors are (they are nothing to do with the Vector class in AS3), so check that out if you’re not sure. But briefly, think of a Euclidean vector as an arrow:

This arrow shows b2Vec2(4, 9); it points down and to the right. Our gravity vector, then, will point straight down. The longer the arrow, the stronger the gravity, so later on in the tutorial you could try changing the gravity vector to b2Vec(0, 2) to simulate a much weaker gravity, much like that on the Moon.

Now we’ll create the world itself:

import Box2D.Dynamics.b2World;

//...

public var world:b2World;

//...

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);
}


The second parameter we pass to b2World() tells it that it can stop simulating objects that it doesn’t need to simulate any more, which helps speed up the simulation but is completely irrelevant to us at the moment.

Run the SWF to check there are no errors. You won’t be able to see anything yet, though. The world is currently completely empty!

## Step 3: Reinvent the Wheel

Let’s create a simple circular object; this could represent a rock, a basketball, or a potato, but I’m going to see it as a wheel.

I’d love to say that doing this is as simple as:

var wheel:b2CircularObject = new b2CircularObject();


…but that would be a big fat lie. The thing about Box2D is, apparently simple things can require quite a bit of code to get sorted. This extra complexity is very useful for doing advanced work, but it kinda gets in our way for simple things like what we’re trying to do at the moment. I’m going to quickly go over what we need to do to make this wheel; we can examine it in more detail in later tutorials.

To create a single “physics object” — that is, an object with a shape and a mass that Box2D can simulate within a world — we must construct it using five different classes:

• A body definition, which is like a template for creating…
• A body, which has a mass and a position, but doesn’t have…
• A shape, which could be as simple as a circle, that must be connected to a body using…
• A fixture, which is created using…
• A fixture definition which is another template, like the body definition.

Phew. Here’s what that all looks like in code:

import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2Body;
import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Dynamics.b2Fixture;
import Box2D.Dynamics.b2FixtureDef;

//...

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);
}


The argument that we pass to b2CircleShape() specifies the radius of the circle. Everything else should make sense based on the list above, even if the reasoning behind this structure makes no sense.

Note that we never write new b2Body() or new b2Fixture(); the world is used to create the body from the body definition, and the body is used to create the fixture from the fixture definition. This means that the world knows about all the bodies that are created within it, and the body knows about all the fixtures that are created that connect shapes to it.

The actual physics object that we’ve created is the wheelBody; everything else is just part of a recipe to form that one object. So, to check that we’ve been successful, let’s see whether the wheelBody exists:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

trace(wheelBody);
}


Result:

[object b2Body]


Good.

## Step 4: Move Your Body

Do you know what I mean when I talk about the “game loop” and a “tick”? If not, go read my short article, Understanding the Game Loop, right now, because it’s really important for what we’re doing.

The Box2D world object has a method, Step(), which drives the simulation. You specify a tiny period of time (a fraction of a second), and Step() simulates the movement and collisions of every object in the world; once the function has run, all the body objects will have been updated with their new positions.

Let’s see this in action. Instead of tracing wheelBody itself, we’ll trace its position. Then, we’ll run b2World.Step(), and trace the wheel’s position again:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
world.Step(0.025, 10, 10);
trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
}


(The GetPosition() method of a body returns a b2Vec2, so we need to trace the individual x and y properties rather than just calling trace(wheelBody.GetPosition().)

The first parameter we pass to Step() is the number of seconds to simulate passing in the Box2D world. The other two parameters specify how much accuracy Box2D should use in all the mathematical calculations it uses to simulate the passing of time. Don’t worry about these right now; just know that bigger numbers could make Box2D take more time to simulate the world — if you set these too high, it might even take longer than 0.025 seconds to run Step(), so we’d be getting out of sync with the real world!

Test the SWF, and look at your output window:

0 0
0 0


That’s a little depressing. The wheel hasn’t moved at all — and yet, the world has gravity, so you’d think it would have fallen a little bit. What’s going on?

## Step 5: Being Dynamic

By default, all Box2D bodies are static, meaning that they don’t move. Think of the actual platforms in a platform game; they’re solid objects, but aren’t affected by gravity and can’t be pushed around.

We need our wheel to be dynamic, so that it can move. Guess how we define this property of the body? Using the body definition, of course!

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
world.Step(0.025, 10, 10);
trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
}


Try the SWF now, and see what you get:

0 0
0 0.00625


It’s moved! How exciting!

## Step 6: Keep on Moving

We can’t call this a game loop yet, though, because it’s only running once; we need it to run over and over and over again. We can make this happen using a Timer and an event listener:

import flash.utils.Timer;
import flash.events.TimerEvent;

//...

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var stepTimer:Timer = new Timer(0.025 * 1000);
trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
stepTimer.start();
}

private function onTick(a_event:TimerEvent):void
{
world.Step(0.025, 10, 10);
trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
}


(Note that I’ve given the timer a period of 0.025 seconds as well, so that it stays in sync with the world’s steps. You don’t have to do this — in fact, if you make the two periods different, you can get some really cool time-related effects, like slow-motion.)

But, oops, that code won’t work; we need wheelBody to be accessible in the onTick() function. While we’re at it, we might as well make the timer accessible everywhere, too:

public var world:b2World;
public var wheelBody:b2Body;
public var stepTimer:Timer;

//...

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBody = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

stepTimer = new Timer(0.025 * 1000);
trace(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
stepTimer.start();
}


Note that lines 14 and 20, above, have changed, now that the wheel body and timer are defined elsewhere.

Try it now:

0 0
0 0.00625
0 0.018750000000000003
0 0.037500000000000006
0 0.0625
0 0.09375
0 0.13125
0 0.17500000000000002
0 0.22500000000000003
0 0.28125000000000006
0 0.34375000000000006
0 0.4125000000000001
0 0.4875000000000001
0 0.5687500000000001


Hooray, it’s falling forever! Okay, that’s enough analysing the numbers; let’s make something visual.

## Step 7: Draw!

We’ve got all these coordinates, so why not join the dots?

Replace the traces with the code to draw a line from the wheel’s old position to its new one:

private function onTick(a_event:TimerEvent):void
{
graphics.moveTo(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
world.Step(0.025, 10, 10);
graphics.lineTo(wheelBody.GetPosition().x, wheelBody.GetPosition().y);
}


In order to see the line, we’ll need to set its lineStyle:

private function getStarted():void
{

//...

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


Now run the SWF. You’ll see a red line accelerating down the left edge. I’ve added some trickery to my SWF that means it won’t do anything until you click it, so you can check it out below:

Great! So, the wheel is free-falling, and getting faster due to gravity, as it should be. We should leave its vertical speed alone so that gravity can do its work, but we can manually alter its initial horizontal speed to make the line’s shape a little more interesting:

private function getStarted():void
{

//...

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


Remember that a b2Vec2 looks like an arrow, so, in this case, the starting velocity is going to look like an arrow pointing directly to the right, as if we had just shot it out of a cannon from the top of a cliff. Our world has no air resistance (because there’s no air!) so there’s absolutely nothing to slow it down — though, thanks to gravity, it is speeding up vertically.

Sounds confusing, but it should be clear once you run the SWF:

We’ve just inadvertently drawn a parabola. So… that’s neat, I guess?

## Step 9: The Illusion of Movement

Okay, okay, maybe you’re not as thrilled to see a curved red line as I am. If we’re going to simulate a world, we should make the objects look like, well, objects, right? So instead of seeing a line that traces the wheel’s position through space, we should make it look as if the wheel is actually moving through space.

We can do this by repeatedly drawing and erasing a circle, centered on the wheel’s location:

private function onTick(a_event:TimerEvent):void
{
graphics.clear();
graphics.lineStyle(3, 0xff0000);
world.Step(0.025, 10, 10);
graphics.drawCircle(wheelBody.GetPosition().x, wheelBody.GetPosition().y, 5);
}


We have to specify the line style in onTick() now, because graphics.clear() resets it, as well as erasing all the graphics from the screen. Note that I’ve set the radius of the circle to 5, which is the same as the radius of the circleShape we created earlier.

Try this SWF:

I think it’s pretty obvious what the next step should be…

## Step 10: Grounded

This infinite world of nothingness doesn’t lend itself to many exciting situations. Sure, we could add new wheels, but without any ground or walls, they’d never do anything interesting.

We’ll create some solid objects that the wheel can collide with, starting with a big flat piece of ground. For this, we’ll use a rectangle.

Remember the objects we need to create a body?

• A body definition, which is like a template for creating…
• A body, which has a mass and a position, but doesn’t have…
• A shape, which could be as simple as a circle, that must be connected to a body using…
• A fixture, which is created using…
• A fixture definition which is another template, like the body definition.

You know how to do this for a circular body; now we need to make a rectangular one:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBody = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var groundBodyDef:b2BodyDef = new b2BodyDef();
var groundBody:b2Body = world.CreateBody(groundBodyDef);
var groundShape:b2PolygonShape = new b2PolygonShape();
groundShape.SetAsBox(stage.stageWidth, 1);
var groundFixtureDef:b2FixtureDef = new b2FixtureDef();
groundFixtureDef.shape = groundShape;
var groundFixture:b2Fixture = groundBody.CreateFixture(groundFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


It’s mostly the same, except that, where in creating a circular body we passed the desired radius to the b2CircleShape() constructor, here we must pass the desired width and height of the rectangle to the b2PolygonShape.SetAsBox() function. (Actually, we pass the desired half-width and half-height, so the box will be twice as wide as the stage and two pixels tall, but that’s fine.) Remember that all bodies are static by default, so we don’t have to worry about the ground falling away. You’ll need to import Box2D.Collision.Shapes.b2PolygonShape for this to work.

By default, any new shape will be created at (0, 0), so we need to specify that the ground should be created at the bottom of the stage. We could manually alter the position of the ground body once it’s been created, just as we manually altered the velocity of the wheel body, but it’s neater if we set the position as part of the ground’s body definition:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBody = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var groundBodyDef:b2BodyDef = new b2BodyDef();
groundBodyDef.position.Set(0, stage.stageHeight);
var groundBody:b2Body = world.CreateBody(groundBodyDef);
var groundShape:b2PolygonShape = new b2PolygonShape();
groundShape.SetAsBox(stage.stageWidth, 1);
var groundFixtureDef:b2FixtureDef = new b2FixtureDef();
groundFixtureDef.shape = groundShape;
var groundFixture:b2Fixture = groundBody.CreateFixture(groundFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


Make sure you set this before passing the body definition to world.CreateBody(), or the changes will be ignored.

Now test the SWF:

We can’t see the ground because we haven’t drawn it, but Box2D still simulates it, so we see its effect: the wheel collides with it and rolls to the side.

## Step 11: Set Some Boundaries

We’re going to add more wheels in the next step, but first, let’s make this a completely enclosed space, with a ground, a ceiling, and two walls.

I’d like you to have a go at this yourself; create three more rectangular bodies of the right sizes and in the right positions. It’ll be easiest to start with the one on the right, since the wheel is going to collide with it. To test the others, fiddle about with the initial velocity.

You’ll need to change the wheel’s initial position, or it’ll overlap the left wall and the ceiling when they’re created. You can do this in the same way that you set the position of the rectangular objects, through the position.Set() method of the body definition.

Good luck! If you get stuck, check out my code below:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(10, 10);
wheelBody = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var groundBodyDef:b2BodyDef = new b2BodyDef();
groundBodyDef.position.Set(0, stage.stageHeight);
var groundBody:b2Body = world.CreateBody(groundBodyDef);
var groundShape:b2PolygonShape = new b2PolygonShape();
groundShape.SetAsBox(stage.stageWidth, 1);
var groundFixtureDef:b2FixtureDef = new b2FixtureDef();
groundFixtureDef.shape = groundShape;
var groundFixture:b2Fixture = groundBody.CreateFixture(groundFixtureDef);

var rightWallBodyDef:b2BodyDef = new b2BodyDef();
rightWallBodyDef.position.Set(stage.stageWidth, 0);
var rightWallBody:b2Body = world.CreateBody(rightWallBodyDef);
var rightWallShape:b2PolygonShape = new b2PolygonShape();
rightWallShape.SetAsBox(1, stage.stageHeight);
var rightWallFixtureDef:b2FixtureDef = new b2FixtureDef();
rightWallFixtureDef.shape = rightWallShape;
var rightWallFixture:b2Fixture = rightWallBody.CreateFixture(rightWallFixtureDef);

var leftWallBodyDef:b2BodyDef = new b2BodyDef();
leftWallBodyDef.position.Set(0, 0);
var leftWallBody:b2Body = world.CreateBody(leftWallBodyDef);
var leftWallShape:b2PolygonShape = new b2PolygonShape();
leftWallShape.SetAsBox(1, stage.stageHeight);
var leftWallFixtureDef:b2FixtureDef = new b2FixtureDef();
leftWallFixtureDef.shape = leftWallShape;
var leftWallFixture:b2Fixture = leftWallBody.CreateFixture(leftWallFixtureDef);

var ceilingBodyDef:b2BodyDef = new b2BodyDef();
ceilingBodyDef.position.Set(0, 0);
var ceilingBody:b2Body = world.CreateBody(ceilingBodyDef);
var ceilingShape:b2PolygonShape = new b2PolygonShape();
ceilingShape.SetAsBox(stage.stageWidth, 1);
var ceilingFixtureDef:b2FixtureDef = new b2FixtureDef();
ceilingFixtureDef.shape = ceilingShape;
var ceilingFixture:b2Fixture = ceilingBody.CreateFixture(ceilingFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


And the result:

Nice work.

## Step 12: Create an Array

Now we’re ready to add more bodies, slam them together, and see what happens.

We could create them all invididually, like I did with the rectangles, but it’d be neater to use an array to hold them all, and a single function to create them.

So, first, let’s create that array, with a single element: the existing wheel.

public var world:b2World;
//public var wheelBody:b2Body; <-- delete this line
public var wheelArray:Array;
public var stepTimer:Timer;

//...

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

wheelArray = new Array();

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(10, 10);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

wheelArray.push(wheelBody);

//...

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}

private function onTick(a_event:TimerEvent):void
{
graphics.clear();
graphics.lineStyle(3, 0xff0000);
world.Step(0.025, 10, 10);

for each (var wheelBody:b2Body in wheelArray)
{
graphics.drawCircle(wheelBody.GetPosition().x, wheelBody.GetPosition().y, 5);
}
}


If this works, your SWF will act exactly the same as it did before.

## Step 13: Add One More Wheel

To test this out properly, we can add an extra wheel — just one for now! Copy and paste the code for creating the wheel and change parts of it so the wheels aren’t exactly the same:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

wheelArray = new Array();

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(10, 10);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

wheelArray.push(wheelBody);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(100, 200);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

wheelArray.push(wheelBody);

//... create boundaries here

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}



You’ll get a bunch of warnings about duplicate variable definitions, but it should still compile, depending on your settings:

The first wheel drops straight down, without an initial sideways velocity. This makes perfect sense when you look at the code; we’re calling wheelBody.SetLinearVelocity() in the wrong place. Move it up:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);

wheelArray = new Array();

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(10, 10);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(50, 0);
wheelBody.SetLinearVelocity(startingVelocity);

wheelArray.push(wheelBody);

var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(100, 200);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(-100, 0);
wheelBody.SetLinearVelocity(startingVelocity);

wheelArray.push(wheelBody);

//... create boundaries here

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


Okay! That’s working well. We can wrap all that wheel creation code up in a function, now.

## Step 14: Wheel Generator

To create this wheel generation function, you can basically copy and paste all the code we’ve been using. Here’s mine:

private function createWheel(radius:Number, startX:Number, startY:Number, velocityX:Number, velocityY:Number):void
{
var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(startX, startY);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(velocityX, velocityY);
wheelBody.SetLinearVelocity(startingVelocity);

wheelArray.push(wheelBody);
}


I’ve added some parameters so that we can specify the customisable properties of the wheels. While we’re at it, I suggest we move all of the boundary creation code to a separate function, just to keep things tidy:

private function createBoundaries():void
{
}


Now we can rewrite the entire getStarted() function like so:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);
wheelArray = new Array();

createWheel(5, 10, 10, 50, 0);
createWheel(5, 100, 200, -25, 0);

createBoundaries();

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


Try it out! Again, the SWF should act the same as it did before.

## Step 15: Automatic Wheels

Now that we’ve simplified the wheel generation, we can make lots of them without much difficulty or mess:

private function getStarted():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);
wheelArray = new Array();

for (var i:int = 0; i < 20; i++)
{
createWheel(
Math.random() * 10,
Math.random() * (stage.stageWidth - 20) + 10,
Math.random() * (stage.stageHeight - 20) + 10,
(Math.random() * 100) - 50,
0
);
}

createBoundaries();

stepTimer = new Timer(0.025 * 1000);
graphics.lineStyle(3, 0xff0000);
stepTimer.start();
}


This will create twenty wheels, each with a radius of between 0 and 10, a position of anywhere between (10, 10) and (stageWidth-10, stageHeight-10), and a horizontal speed of anywhere between -50 and +50. Try it out!

It almost works, but something’s wrong. Let’s figure out what’s going on.

## Step 16: Spoiler — It’s the Radius

Check out this image from when I ran the SWF:

Some of the wheels are sunk into the ground or wall, and some are overlapping each other. It’s really weird. And on a related note, didn’t we set the radii of the wheels to be anywhere between 0 and 10? Why are they all the same?

As you’ve probably figured out, they’re the same because we hard coded the radius of the circle to draw in the onTick() event handler function. Oops.

Unfortunately we can’t just use wheelBody.radius to find the radius of the wheel; remember that the body doesn’t have a shape, but rather is connected to a shape through a fixture. To find the radius, then, we have to do something like this:

var wheelFixture:b2Fixture = wheelBody.GetFixtureList();
var wheelShape:b2CircleShape = wheelFixture.GetShape() as b2CircleShape;


Fortunately we can simplify this to (wheelBody.GetFixtureList().GetShape() as b2CircleShape).GetRadius(); let’s use this in onTick():

private function onTick(a_event:TimerEvent):void
{
graphics.clear();
graphics.lineStyle(3, 0xff0000);
world.Step(0.025, 10, 10);

for each (var wheelBody:b2Body in wheelArray)
{
graphics.drawCircle(
wheelBody.GetPosition().x,
wheelBody.GetPosition().y,
);

}
}


How’s that?

Ah, much better!

## Step 17: Have a Little Fun

The simulation is a little dull at the moment; the wheels just roll a little bit and then stop. Boring. Let’s liven things up a bit by changing them from metal wheels to air-filled rubber tyres.

To do this, we can use a property called the coefficient of restitution. This is physics-talk for “bounciness”; the coefficient of restitution of an object shows how much it will bounce back after colliding with another object. Typically, this takes a value between 0 and 1, where 0 means it stops dead as soon as it touches another object, and 1 means it bounces back without losing any energy.

By default, all Box2D bodies have a coefficient of restitution of 0; let’s liven things up by setting it a bit higher:

private function createWheel(radius:Number, startX:Number, startY:Number, velocityX:Number, velocityY:Number):void
{
var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(startX, startY);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
wheelFixtureDef.restitution = (Math.random() * 0.5) + 0.5;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(velocityX, velocityY);
wheelBody.SetLinearVelocity(startingVelocity);

wheelArray.push(wheelBody);
}


This will set the coefficient of restitution of each wheel to a random value between 0.5 and 1. Note that this is a property of the fixture definition, rather than the shape or the body definition.

Let’s see what happens:

That’s more like it! What else can we set?

## Step 18: Other Properties

We can also set the friction (how rough or smooth the outer surface is; a polished steel wheel will have less friction than a rough stone one) and the density (how heavy the body would be compared to another of the same size and shape; stone is denser than wood).

The friction coefficient should be between 0 and 1, where 0 means extremely smooth and 1 means extremely rough, and is 0.2 by default. The density can be any value you like, and is 1 by default. (Well, for static bodies, it’s 0, but it doesn’t really matter to them as they don’t move anyway.)

Let’s mess around with these values and see what happens:

private function createWheel(radius:Number, startX:Number, startY:Number, velocityX:Number, velocityY:Number):void
{
var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(startX, startY);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
wheelFixtureDef.restitution = (Math.random() * 0.5) + 0.5;
wheelFixtureDef.friction = (Math.random() * 1.0);
wheelFixtureDef.density = Math.random() * 20;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(velocityX, velocityY);
wheelBody.SetLinearVelocity(startingVelocity);

wheelArray.push(wheelBody);
}


The result:

All good. Feel free to add parameters for restitution, friction, and density to the createWheel() function if you want a bit more control.

There’s something that’s bugging me, though…

## Step 19: Heavy, Man

…Why does everything feel so floaty?

Seriously, it’s like the whole world is moving through treacle. But there’s no air resistance, let alone molasses resistance; gravity is at a sensible level; and the time step is matched to the timer’s tick duration — what’s the issue?

If you’re a scientist, you’ve probably noticed that I haven’t mentioned any units in the whole tutorial. The first wheel’s radius was just “5″ — not “5 inches” or whatever. We’ve just been working in pixels. But Box2D is a physics engine, and so it uses actual physical units. That wheel had a radius of five meters, not five pixels; that’s roughly sixteen feet, not far off the height of an average house. Most wheels aren’t that height, although there are exceptions, as this Flickr photo from Monochrome shows:

Even then, the tires in that photo have a radius of about 2.5 meters; we’d normally expect a wheel’s radius to be somewhere between a few centimetres and half a meter. This means that every Box2D object we’ve created is much bigger than it appears on the screen, and — as anyone who’s watched Honey I Shrunk The Kids knows — bigger objects move in slow motion.

So, we can get a much less floaty simulation by changing the radius of the wheels that we create:

for (var i:int = 0; i < 20; i++)
{
createWheel(
Math.random() * 0.5,
Math.random() * (stage.stageWidth - 20) + 10,
Math.random() * (stage.stageHeight - 20) + 10,
(Math.random() * 100) - 50,
0
);
}


The resulting SWF feels a lot more realistic, but at the same time, the wheels are all drawn so tiny that it feels like we’re watching from half a mile away:

There’s a common trick that Box2D developers use here…

## Step 20: Set the Scale Factor

To recap: Box2D uses meters, but Flash uses pixels. Therefore, a wheel of 0.5 meters in radius is drawn as a tiny circle, just over a pixel wide.

When you read it like that, perhaps the solution seems obvious: we need to scale up the conversion between meters and pixels, so that one meter is drawn as, let’s say, 20 pixels.

Modify the graphics.drawCircle() call in onTick() to reflect this new scale factor:

private function onTick(a_event:TimerEvent):void
{
graphics.clear();
graphics.lineStyle(3, 0xff0000);
world.Step(0.025, 10, 10);

for each (var wheelBody:b2Body in wheelArray)
{
graphics.drawCircle(
wheelBody.GetPosition().x,
wheelBody.GetPosition().y,
);

}
}


Does that work?

Um, no. We’re back to floatiness, plus the wheels aren’t colliding with each other any more.

Ah, but, this is misleading. The graphical representations of the wheels appear to be overlapping, but actually, they’re not. See, we can’t just use this scale factor for the radii of the wheels and leave it at that; we have to use it for all lengths and distances — and that includes the x- and y-positions of the wheels. So, try this:

private function onTick(a_event:TimerEvent):void
{
graphics.clear();
graphics.lineStyle(3, 0xff0000);
world.Step(0.025, 10, 10);

for each (var wheelBody:b2Body in wheelArray)
{
graphics.drawCircle(
wheelBody.GetPosition().x * 20,
wheelBody.GetPosition().y * 20,
);

}
}


Actually, hold on — let’s use a public variable instead of hard coding the number 20:

public var scaleFactor:Number = 20;		//pixels per meter

//...

private function onTick(a_event:TimerEvent):void
{
graphics.clear();
graphics.lineStyle(3, 0xff0000);
world.Step(0.025, 10, 10);

for each (var wheelBody:b2Body in wheelArray)
{
graphics.drawCircle(
wheelBody.GetPosition().x * scaleFactor,
wheelBody.GetPosition().y * scaleFactor,
);

}
}


Try the SWF now, and… hmm. Just a blank white canvas. Let’s see what’s going on under the hood:

for each (var wheelBody:b2Body in wheelArray)
{
trace(wheelBody.GetPosition().x * 20, wheelBody.GetPosition().y * 20);
graphics.drawCircle(
wheelBody.GetPosition().x * scaleFactor,
wheelBody.GetPosition().y * scaleFactor,
);

}


Result:

2113.750333013013 5770.15641567111
9375.355269713327 3047.2614786848426
1777.8544335393235 7079.051908224821
5187.372552766465 3558.7625446990132
918.4206030098721 1295.5237261280417
6346.797422436066 4702.557933263481
5711.968449363485 6922.446605682373
3969.2852629581466 493.93064894527197
288.0119406618178 2824.054687216878
7364.996945206076 7429.401991263032
6689.968886575662 6163.817259043455
3496.4873051736504 3063.40289388597
7230.636887997389 1294.561620734632
5069.327887007967 7544.009161673486
7484.348242566921 3492.7868475466967
3882.391231972724 6486.211738668382
1641.0604398231953 2738.4121247828007
9631.735268328339 3224.4683633819222


Whoa! Those numbers are wayyy too big. But that makes sense — they’re 20 times bigger than they used to be.

Think about when we create the wheels — and specifically, when we set their initial positions:

createWheel(
Math.random() * 0.5,
Math.random() * (stage.stageWidth - 20) + 10,
Math.random() * (stage.stageHeight - 20) + 10,
(Math.random() * 100) - 50,
0
);


My stage is 500x400px. When I wasn’t using a scale factor, a new wheel’s x-position could be anywhere from 10px to 490px from the left of the stage. This was the same as being anywhere from 10 meters to 490 meters from the left of the stage, because each meter was represented as a single pixel long. But now, each meter is represented by twenty pixels — so a new wheel’s x-position could be anywhere from 200px to 9800px from the left of the stage! No wonder we’re not seeing any of them.

To fix this, we’ll use the scale factor in the code that creates a new wheel:

private function createWheel(radius:Number, startX:Number, startY:Number, velocityX:Number, velocityY:Number):void
{
var wheelBodyDef:b2BodyDef = new b2BodyDef();
wheelBodyDef.type = b2Body.b2_dynamicBody;
wheelBodyDef.position.Set(startX / scaleFactor, startY / scaleFactor);
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
wheelFixtureDef.restitution = (Math.random() * 0.5) + 0.5;
wheelFixtureDef.friction = (Math.random() * 1.0);
wheelFixtureDef.density = Math.random() * 20;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

var startingVelocity:b2Vec2 = new b2Vec2(velocityX, velocityY);
wheelBody.SetLinearVelocity(startingVelocity);

wheelArray.push(wheelBody);
}


Does it make sense to you that we’re dividing it, rather than multiplying it? Remember, Box2D uses meters, Flash uses pixels, and our scale factor is in pixels/meter.

Try the SWF now:

Much better — but the right wall and ground appear to have disappeared.

…Have you already guessed what’s happening?

It’s because, again, the distances are specified in meters, and we haven’t applied the scale factor. So rather than the right wall being 500px from the left edge, it’s 500 meters, or 10,000px. Again, we need to divide our distances by the scale factor to take this into account.

If you wrote this code yourself, I’m sure you can figure out how to alter it yourself :) Otherwise, here’s mine:

private function createBoundaries():void
{
var groundBodyDef:b2BodyDef = new b2BodyDef();
groundBodyDef.position.Set(0, stage.stageHeight / scaleFactor);
var groundBody:b2Body = world.CreateBody(groundBodyDef);
var groundShape:b2PolygonShape = new b2PolygonShape();
groundShape.SetAsBox(stage.stageWidth / scaleFactor, 1 / scaleFactor);
var groundFixtureDef:b2FixtureDef = new b2FixtureDef();
groundFixtureDef.shape = groundShape;
var groundFixture:b2Fixture = groundBody.CreateFixture(groundFixtureDef);

var rightWallBodyDef:b2BodyDef = new b2BodyDef();
rightWallBodyDef.position.Set(stage.stageWidth / scaleFactor, 0);
var rightWallBody:b2Body = world.CreateBody(rightWallBodyDef);
var rightWallShape:b2PolygonShape = new b2PolygonShape();
rightWallShape.SetAsBox(1 / scaleFactor, stage.stageHeight / scaleFactor);
var rightWallFixtureDef:b2FixtureDef = new b2FixtureDef();
rightWallFixtureDef.shape = rightWallShape;
var rightWallFixture:b2Fixture = rightWallBody.CreateFixture(rightWallFixtureDef);

var leftWallBodyDef:b2BodyDef = new b2BodyDef();
leftWallBodyDef.position.Set(0, 0);
var leftWallBody:b2Body = world.CreateBody(leftWallBodyDef);
var leftWallShape:b2PolygonShape = new b2PolygonShape();
leftWallShape.SetAsBox(1 / scaleFactor, stage.stageHeight / scaleFactor);
var leftWallFixtureDef:b2FixtureDef = new b2FixtureDef();
leftWallFixtureDef.shape = leftWallShape;
var leftWallFixture:b2Fixture = leftWallBody.CreateFixture(leftWallFixtureDef);

var ceilingBodyDef:b2BodyDef = new b2BodyDef();
ceilingBodyDef.position.Set(0, 0);
var ceilingBody:b2Body = world.CreateBody(ceilingBodyDef);
var ceilingShape:b2PolygonShape = new b2PolygonShape();
ceilingShape.SetAsBox(stage.stageWidth / scaleFactor, 1 / scaleFactor);
var ceilingFixtureDef:b2FixtureDef = new b2FixtureDef();
ceilingFixtureDef.shape = ceilingShape;
var ceilingFixture:b2Fixture = ceilingBody.CreateFixture(ceilingFixtureDef);
}


Try it now:

Excellent! And since the scale factor is soft-coded, you could try increasing it:

## Conclusion

Congratulations! If you’ve followed this far, then you understand the very important basic concepts of Box2D. (If you didn’t follow this far, then post a comment explaining where you got stuck, and I’ll help you out.) Okay, the final SWF might not look like much, but don’t be fooled; you’ve given yourself an excellent framework for what you’ll learn next.

Speaking of what’s next… what do you want to learn? I’ve got plenty of ideas, and I’m happy to continue this series in whatever direction I’d like to explore, but it’d be cool to know what you think. Do you want to make a physics puzzler? A platformer? A side-scrolling racing game? Are there any core concepts you’d like to focus on, like creating joints?

The next tutorial in this series will most likely be about rendering objects using other methods than the built-in drawing methods — in particular we’ll look at using DisplayObjects, either drawn through Flash or imported as Bitmaps. We’ll also create some actual boxes, because it’s pretty weird to have done an entire Box2D tutorial without any.

You can vote on tutorial ideas through our Google Moderator page at http://bit.ly/Box2DFlashTutorialIdeas, or submit a brand new one, if nobody’s thought of it yet. Looking forward to seeing what you suggest!

Other parts in this series:Box2D for Flash and AS3: Bitmaps and Boxes»

• tibbi

Hello, at the 6th step, the trace in onTick gives error in flashdevelop:

[Fault] exception, information=TypeError: Error #1009: Cannot access a property or method of a null object reference.

• tibbi

actually getting that error at the 7th step too, at adding graphics.moveTo.. I hate that error :/

• http://michaeljameswilliams.com/ Michael James Williams

Hmm… did you make your wheelBody a public variable? And, if so, did you change the line in getStarted() from var wheelBody:b2Body = (...) to wheelBody = (...)?

• tibbi

oh i see, Ive had a “var wheelBody:b2Body = world.CreateBody(wheelBodyDef);” at getstarted, right under wheelBody = world.CreateBody(wheelBodyDef);
Havent seen in the 6th step that you deleted it :) my bad, thanks

• http://michaeljameswilliams.com/ Michael James Williams

Goodgood :) I’ll make it clearer in the tutorial that that’s what you’re supposed to do.

• tibbi

I wish syntax highlighter worked like github, so you could show deleting lines too, not just adding :p

• tibbi

and since Im in a spammy mood now… you have a bug at
rightWallShape.SetAsBox(1, stage.stageWidth);

it works well for you as your width > height, but it didnt work for me :p should be
rightWallShape.SetAsBox(1, stage.stageHeight);

left side is ok

• http://michaeljameswilliams.com/ Michael James Williams

Oh wow, nicely spotted! Thanks, I’ve fixed that now :)

• James

Been looking forward to this series. I would love to see a Platformer developed using the Box 2d.

Thanks

• http://michaeljameswilliams.com/ Michael James Williams

At the moment, platformer is the most popular choice of game on the Google Moderator page :)

• http://www.mehmetdemirel.com mehmet

Great tutorial on box2d Michael. Keep delivering more box2d tutorials. Box2d is meant for the game development but would love to see how this can be used on a regular site to get more interest.

• http://michaeljameswilliams.com/ Michael James Williams

Thanks! I think this is a great example of Box2D being used on a regular site like you said: http://www.youtube.com/wariolandshakeit2008. (Click and drag things once the video finishes.)

• http://www.mehmetdemirel.com mehmet

Sick find Michael.

• http://snaptin.com Ian Yates
Staff

Genius!

• http://michaeljameswilliams.com/ Michael James Williams

It was even more impressive when it first came out, because that’s exactly what YouTube looked like!

• Zync

Great tutorial. Highlighted a lot of good info that the docs don’t explain that well.
What do you think about QuickB2? (http://code.google.com/p/quickb2/) as a quickbox wrapper. Seems to cut down on a lot of the mundane setup work.

• http://michaeljameswilliams.com/ Michael James Williams

Cheers :)

Is QuickB2 the same as QuickBox2D? We published a couple of tutorials about that last year; I really like the idea, though at the same time I get a perverse enjoyment out of doing the setup myself.

The QuickB2 demos are very impressive; I particularly like the soft-bodies. We’ll have to commission a tutorial on that in the future!

• Zync

QuickB2 is similar to QuickBox2D but different coder, slightly better abstraction with a lot more features like soft bodies. You can access the low level Box2D setup work with QuickB2 as well (something you couldn’t really do easily in QuickBox2D) so it can do the best of both worlds. :)

• http://michaeljameswilliams.com/ Michael James Williams

Oh, that sounds great! Is it possible to migrate an existing Box2D project over to QuickB2?

• Zync

I haven’t used Box2D natively as much mostly cos the setup work for just creating a simple object always did my head in :P But don’t see why not. Where you make a wheel with:

var wheelBodyDef:b2BodyDef = new b2BodyDef();
var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
var circleShape:b2CircleShape = new b2CircleShape(5);
var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
wheelFixtureDef.shape = circleShape;
var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);

You can boil that down to (roughly):

var wheelBody:qb2CircleShape=qb2Stock.newCircleShape(new amPoint2d(10,10), 20,1);

• http://michaeljameswilliams.com/ Michael James Williams

Nice. Thanks :) In that case, once I’ve got a few parts of this series done, I’ll probably go back and redo some of them using QuickB2.

• tal

We would love to see next things like
how body changes its startingVelocity
by using drag and drop of a body

how do drag and drop a body
how do you attach to its body other bodies

thats really great!!!

• http://michaeljameswilliams.com/ Michael James Williams

Great ideas!

• Amlaks

Just wanted to say, this a really great tutorial. I never usually put anything on these but was really impressed, even made me chuckle in places. Thanks so much got me using physics in my Flash games.

Amy

• http://michaeljameswilliams.com/ Michael James Williams

Wow, thanks Amy! Glad you like it :)

• http://gurka.se/ Tim

Very well-written and just enough humor. Great job!

I’m struggling to come up with any negative critique, but that second-wheel paste really made me cringe.

• http://michaeljameswilliams.com/ Michael James Williams

Thanks :)

What do you mean — was it because of the wasted code?

• Patrik Sweden

GREAT TUTORIAL! Really awesome. Thanks for helping me with box2d!

But what happend to the code… I like it better with white background? Can i change back? :)

• http://michaeljameswilliams.com/ Michael James Williams

Thanks!

Oh, just trying a different colour scheme for a few days to see how people like it.

• foul

Hello. Excellent tutorial about box2d (and is the only one understandable I’ve seen so far). I haven’t completed it yet but at step 10 the b2PolygonShape is not imported :

import Box2D.Collision.Shapes.b2PolygonShape;

• http://michaeljameswilliams.com/ Michael James Williams

Thanks! I’ve corrected that Step now :)

• http://sacheras3.blogspot.com sacheras3

Hi man and hi active.tutsplus. let me congratulations abouts this tutorial is amazing. Thanks for your help to learn more and be better. I like this tutorial and hope you put more about this topic special for make games.
On this moment i can not buy your member but when i can sure a pay this for be members active.tutsplus.

regards.

Sacheras3

• Hilmy

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Main/onTick()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

• http://michaeljameswilliams.com/ Michael James Williams

What part of the tutorial are you at when you get this? Also, try this Quick Tip.

• Hilmy

at step 6

• Hilmy

whooaa, it’s fixed now, thanks :D

• http://michaeljameswilliams.com/ Michael James Williams

Great!

• Matt

Fantastic tutorial Michael, I’ve been struggling with the basic concepts of box2d for a while now and this really helped me along.

Matt

• http://michaeljameswilliams.com/ Michael James Williams

Thanks Matt, glad you found it useful!

• Pingback: First Alpha « Circus Mice

• http://www.discoblimp.com/ dorkbot

Beside side scrolling games, is Box2D practical for overhead games? A game that needs physics for hitting objects, but doesn’t need gravity, maybe just friction and mass?

Thanks for the great tutorial!

• http://michaeljameswilliams.com/ Michael James Williams

If all you need is some aspects of Newtonian mechanics, as you’ve described, you can probably roll your own without too much complication. Take a look at Shiu’s tutorials for great examples.

• Damian

Awesome tutorial! Just finished going through it & I felt like I have a solid base for going further with Box2D. Thanks!

• http://www.timepass9.com maria

thanx, very helpfull, i love to work on box2d.

• kabeer

thanks, really helpfull, i like the way in which you write, thanks a lot, keep writing

• thawfeek

Great tutorial mike.but i got stuck making the ground and walls. i can’t figured out why we need to use the scale factor on making the walls and grounds .

• ZePioo

Thanks for that tuto, but it seems it doesnt work well for me..
At step 7, I do draw the line representing the wheel fallin, but there is no acceleration as on your online exemple, then when I add the startingVelocity nothin happen, the line doesnt make a parabola, it just keeps fallin down..
I even copy&paste the code of the tuto but it still doesn’t work..
I run on MacBookPro with flash CS6, have you any idea ?

• 112

This is a really good tutorial. Thank You!

• Yusuf

Thank you so much for the entire tutorial. It’s so perfect that I couldn’t get stuck anywhere.

• li

so nice，Thanks.

• Olli

Great tutorial. Feels good to know the basics of box2d. Now I can go on. Thanks!

• KG

Excellent tutorial for beginners. Probably the best one on net.

• Geekfella

First couple of steps need to be more detailed. For an absolute beginner like me, you skip exactly the point I need, and because of that, I already have mistakes at step 3… But for the rest, it looks exactly what I’m looking for,.. Very frustrating, but I’m sure, very good tutorial!