Let’s get physical

Yair Barak
3 min readJan 29, 2017

One of the most complicated things to master in game developing, is using physical engine correctly. In this post I’ll try to explain (and demonstrate) how to use Box2d physical world, with libGDX.

Theory

We gonna create our own world: define forces, gravity (we can have 9.81, but it’s not a must..) — everything.

Inside this world we create bodies. Body has settings like a “real” body in real world — shape, mass, velocity, etc.

There are 3 types of bodies:

  • Dynamic — react to all forces.
  • Static — doesn’t react to forces, so it’s imovable.
  • Kinematic — doesn’t react to forces, but you can move it.

Each of those has its own role in a game. For example, Super Mario: Mario is dynamic body, the tubes are static, and moving platforms are kinematic.

Let’s Code

Create a new libGDX project. Name it Box2dExample. Check “Box2d” in extensions. Load the project in your IDE.

In core module go to Box2dExample.java, and add these members to the class:

The class for creating a Box2d world called (surprisingly) World. For easy debugging we’ll use Box2DDebugRenderer — which will render the outlines of all bodies in our World.

Add to “create” method this code:

To create a new world you only need 2 parameters: gravity vector (in our example it’s a real-world like), and a flag indicates acting on non-active bodies or not (better not, for performance).

That was easy. Now let’s move on to bodies. Start with static body:

To create body, we first need BodyDef — which defines its shape and position.

Define a shape you want to use (remember to dispose after!), and a FixtureDef — all the features the body will have (friction, density, etc).

Same way with dynamic body:

restitution” means, on collision with another body — how much force will return. If it set to 1 the ball will go up and down forever.

Add this to “render” method:

To update World we need to call “step” each rendering.

After executing that’s what we’ll get:

Box2DDebugRenderer draw each body’s type in a different color. Green for static, etc.

Looks good, no? But… it moves slowly. Too much slowly.

We need to consider the measurement scale Box2d uses. When we defined our world with 9.81 meter per second — we didn’t define “how much” is a meter. By default in Box2d, each pixel is a meter. Meaning, what we see here is a 40-meters (diameter) ball falling on a surface 20-meter high. It make sense.

But it’s still not comfortable to work like that. We need to set how many pixels will be considered as one meter, and draw accordingly.

Add a new variable called PPM — Pixels Per Meter:

Each place we refer to size/position on screen — we’ll divide by PPM. Divide also the size of b2dCam — the camera we use for Box2DDebugRenderer.

This is what we get:

Much better.

What To Do With It

In real game, of course, you won’t use Box2DDebugRenderer for presenting your bodies. We keep track of all the bodies in our world, and render shapes accordingly (remember to multiply back by PPM!). While debugging we’ll use 2 cameras — one for real shapes drawing, and one for Box2DDebugRenderer. After we see the drawings match, we can “turn off” the debugging camera.

Here is a full example of lot of falling balls:

This is the outcome (it’s in debug mode. Notice how to shapes match exactly to outlines):

Originally posted here (hebrew).

--

--

Yair Barak

Geek, programmer, husband and father, in no particular order.