Box2D uses MKS (meters, kilograms, and seconds) units and radians for angles. You may have trouble working with meters because your game is expressed in terms of pixels. To deal with this in the testbed I have the whole game work in meters and just use an OpenGL viewport transformation to scale the world into screen space.

float lowerX = -25.0f, upperX = 25.0f, lowerY = -5.0f, upperY = 25.0f;
gluOrtho2D(lowerX, upperX, lowerY, upperY);

If your game must work in pixel units then you should convert your length units from pixels to meters when passing values from Box2D. Likewise you should convert the values received from Box2D from meters to pixels. This will improve the stability of the physics simulation.

You have to come up with a reasonable conversion factor. I suggest making this choice based on the size of your characters. Suppose you have determined to use 50 pixels per meter (because your character is 75 pixels tall). Then you can convert from pixels to meters using these formulas:

xMeters = 0.02f * xPixels;
yMeters = 0.02f * yPixels;

In reverse:

xPixels = 50.0f * xMeters;
yPixels = 50.0f * yMeters;

You should consider using MKS units in your game code and just convert to pixels when you render. This will simplify your game logic and reduce the chance for errors since the rendering conversion can be isolated to a small amount of code.

If you use a conversion factor, you should try tweaking it globally to make sure nothing breaks. You can also try adjusting it to improve stability.

5 thoughts on “Pixels

  1. I think this is something good to know if you need it. Having a standard template which will allow you to work with the physics engine in 99% of your projects would be nice.

  2. The best way I have found to use Box2d is exactly as you suggested – use Box2d as your world model then just apply whatever transformation you need to in order to draw your world on the screen.

    If you use MKS for EVERYTHING in your app, then convert ONLY when you are drawing it, the separation (Model to view) is clean and simple.

    For input from a mouse or touch I do the opposite – I convert the location of the touch into a world location and then deal with it.

    I see many examples that seem to constantly convert from pixels to meters because the developer is thinking about it back-to-front.

    What you have is a 1 meter wide spaceship moving at 3 ms-1 – not a 32 pixel wide sprite moving at 96 pixels per second.

    With separation you can (and I have, with PooperPig) entirely change the look of the game (edge on, isometric, 3d, top down etc.) by changing ONLY how it is drawn and leaving Box2d to worry about what is happening in the world.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">