Understanding pixels and meters with Box2D and how to select an object with mouse – part 2

Ok, time to learn once for all how does Box2D manages object sizes, and how to set them right when working with AS3

In previous step I used a 90×90 pixel crate.

The problem is Box2D does not works with pixels because it does not have a native pixel render engine. In other words, Box2D does not display anything on the screen, it just calculates position and rotation of all bodies. There is a built-in debug renderer but, as the name suggests, it should be used only for debugging purposes.

That’s why in the Update function (lines 63-72) I have to “manually” place every crate in the right place according to its position and rotation (lines 67-69).

Box2D works in meters, and there is an unwritten rule saying 1 meter = 30 pixels. That’s why at line 16 I have the pixels_in_a_meter variable.

So when I think about the crate, I don’t have to think about it as a 90px crate but a 90/30 = 3 meters crate.

But if you look at lines 47 – 48 you’ll see I am assigning 1.5 (meters) to crate_width and crate_height variables. Why?

Because Box2D to create a box (but you will find the same concept applied to other shapes) uses SetAsBox (line 50) that wants width and height relative to the registration point placed in its center.

So that’s how you should think about pixels when you work with BOX2D:

I hope this will help you saving some time…

  • hey emanuele,
    can you make a tutorial on how to make a game like
    ‘enless zombie rampage’? (by diseased prodcutions)

  • Colin Diam

    hello Sir
    Can you please make tutorial of game like myrethia found on kongregate.com

  • anlik

    Sir,if i make a flash game with two different language version(two .swf file but same game content),then what will happen?
    A.Can I get two Mochi ID?
    B.I have to use one Mochi ID in one version,and the other one is unuseful
    Please tell me:)
    Thanks

  • anlik

    I am studying your tutorial, it is great,thanks to your good work.

  • Pingback: Dragging objects with Box2D Flash : Emanuele Feronato()

  • Pingback: Understanding Box2D debug draw : Emanuele Feronato()

  • Pingback: Understanding custom polygons in Box2D : Emanuele Feronato()

  • Pingback: Box2D: tutorial for the absolute beginners : Emanuele Feronato()

  • jo paul

    i found that box2d world actually works in pixel units.

    ;==================================================
    var worldAABB: b2AABB = new b2AABB ();
    worldAABB.lowerBound.Set (0, 0);
    worldAABB.upperBound.Set (stage.stageWidth, stage.stageHeight);
    _b2World = new b2World (worldAABB, new b2Vec2 (0.0, 10), true);

    // debug draw start
    var m_sprite:Sprite;
    m_sprite = new Sprite();
    addChild(m_sprite);
    var dbgDraw:b2DebugDraw = new b2DebugDraw();
    var dbgSprite:Sprite = new Sprite();
    m_sprite.addChild(dbgSprite);
    dbgDraw.m_sprite=m_sprite;
    dbgDraw.m_drawScale=1;
    dbgDraw.m_alpha=1;
    dbgDraw.m_fillAlpha=0.5;
    dbgDraw.m_lineThickness=1;
    dbgDraw.m_drawFlags=0xFFFFFFFF; _b2World.SetDebugDraw(dbgDraw);

    //flash stage
    var mcCircle: Sprite = new McCircle();//McCircle is a movie clip in the library identified as McCircle
    mcCircle.width = 100;
    mcCircle.height = 100;
    mcCircle.x = 100;
    mcCircle.y = 100;
    addChild (mcCircle);

    //box2d world
    var rect: Rectangle = mcCircle.getBounds (mcCircle);
    var circleDef: b2CircleDef = new b2CircleDef ();
    circleDef.radius = rect.width / 2;
    circleDef.density = 1;
    circleDef.friction = 0.5;
    circleDef.restitution = 1.1;

    var bodyDef: b2BodyDef = new b2BodyDef ();
    bodyDef.position.Set (mcCircle.x, mcCircle.y);
    bodyDef.angle = mc.rotation * (Math.PI / 180);
    bodyDef.userData = mcCircle;

    var body: b2Body = _b2World.CreateBody (bodyDef);
    body.CreateShape (circleDef);
    body.SetMassFromShapes ();
    ;==================================================

    but…calculations from box2d tend to be really slow when its units are set to 1:1 pixel ratio.
    what i do is simply scale all units when inputing into box2d world…then i scale them all up when translating back to flash stage.

    e.g.:
    ;==================================================
    var _scale: Number = 0.1
    var worldAABB: b2AABB = new b2AABB ();
    worldAABB.lowerBound.Set (0, 0);
    worldAABB.upperBound.Set (stage.stageWidth * _scale, stage.stageHeight * _scale);
    _b2World = new b2World (worldAABB, new b2Vec2 (0.0, 10), true);

    // debug draw start
    var m_sprite:Sprite;
    m_sprite = new Sprite();
    addChild(m_sprite);
    var dbgDraw:b2DebugDraw = new b2DebugDraw();
    var dbgSprite:Sprite = new Sprite();
    m_sprite.addChild(dbgSprite);
    dbgDraw.m_sprite=m_sprite;
    dbgDraw.m_drawScale=1/_scale;
    dbgDraw.m_alpha=1;
    dbgDraw.m_fillAlpha=0.5;
    dbgDraw.m_lineThickness=1;
    dbgDraw.m_drawFlags=0xFFFFFFFF; _b2World.SetDebugDraw(dbgDraw);

    ;and…

    ;…
    circleDef.radius = rect.width / 2 * _scale;
    ;…
    bodyDef.position.Set (mcCircle.x * _scale, mcCircle.y * _scale);
    ;…
    ;==================================================

  • REALLY REALLY happy to get that working, thank you so much: ) (your demo on the website doesn’t work as well as the one in the download for me)

    THANK YOU : )

  • thanx a lot,

    regards maria