0
votes

I am using LibGDX and Box2d to build my first Android game. Yay!

But I am having some serious problems with Box2d.

I have a simple stage with a rectangular Box2d body at the bottom representing the ground, and two other rectangular Box2d bodies both at the left and right representing the walls.

A Screenshot

Another Screenshot

I also have a box. This box can be touched and it moves using applyLinearImpulse, like if it was kicked. It is a DynamicBody.

What happens is that in my draw() code of the Box object, the Box2d body of the Box object is giving me a wrong value for the X axis. The value for the Y axis is fine.

Those blue "dots" on the screenshots are small textures that I printed on the box edges that body.getPosition() give me. Note how in one screenshot the dots are aligned with the actual DebugRenderer rectangle and in the other they are not.

This is what is happening: when the box moves, the alignment is lost in the movement.

The collision between the box, the ground and the walls occur precisely considering the area that the DebugRenderer renders. But body.getPosition() and fixture.testPoint() considers that area inside those blue dots.

So, somehow, Box2d is "maintaining" these two areas for the same body.

I thought that this could be some kind of "loss of precision" between my conversions of pixels and meters (I am scaling by 100 times) but the Y axis uses the same technique and it's fine.

So, I thought that I might be missing something.

Edit 1

I am converting from Box coordinates to World coordinates. If you see the blue debug sprites in the screenshots, they form the box almost perfectly.

public static final float WORLD_TO_BOX = 0.01f;
public static final float BOX_TO_WORLD = 100f;

The box render code:

public void draw(Batch batch, float alpha) {
    x = (body.getPosition().x - width/2) * TheBox.BOX_TO_WORLD;
    y = (body.getPosition().y - height/2) * TheBox.BOX_TO_WORLD;

    float xend = (body.getPosition().x + width/2) * TheBox.BOX_TO_WORLD;
    float yend = (body.getPosition().y + height/2) * TheBox.BOX_TO_WORLD;

    batch.draw(texture, x, y);
    batch.draw(texture, x, yend);
    batch.draw(texture, xend, yend);
    batch.draw(texture, xend, y);
}

Edit 2

I am starting to suspect the camera. I got the DebugRenderer and a scene2d Stage. Here is the code:

My screen resolution (Nexus 5, and it's portrait):

public static final int SCREEN_WIDTH = 1080;
public static final int SCREEN_HEIGHT = 1920;

At the startup:

// ...
    stage = new Stage(SCREEN_WIDTH, SCREEN_HEIGHT, true);

    camera = new OrthographicCamera();
    camera.setToOrtho(false, SCREEN_WIDTH, SCREEN_HEIGHT);

    debugMatrix = camera.combined.cpy();
    debugMatrix.scale(BOX_TO_WORLD, BOX_TO_WORLD, 1.0f);
    debugRenderer = new Box2DDebugRenderer();
// ...

Now, the render() code:

public void render() {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    camera.update();

    world.step(1/45f, 6, 6);
    world.clearForces();

    stage.act(Gdx.graphics.getDeltaTime());
    stage.draw();

    debugRenderer.render(world, debugMatrix);
}
1
Box2D uses it's own coordinate system. Are you converting from Box2D's coordinate system to libGDX's coordinate system before drawing?kabb
Yes, I edited the question.xrash
I don't think loss of precision is the issue because a similar conversion scale works fine for me. Are you using an OrthographicCamera?user3312130
Yes, I got an OrtographicCamera setup.xrash
Please use the Box2dDebugRenderer to draw your box2d bodies and so on, don't do it yourself. See if this renderer procuces the same offset.noone

1 Answers

1
votes

Looks like the answer to that one was fairly simple:

    stage.setCamera(camera);

I was not setting the OrthographicCamera to the stage, so the stage was using some kind of default camera that wasn't aligned with my stuff.

It had nothing to do with Box2d in the end. Box2d was returning healthy values, but theses values were corresponding to wrong places in my screen because of the wrong stage resolution.