[Box2D] Dynamic body floating over static bodies

I am creating a platformer, and I’m having some trouble understanding/setting Box2D correctly. Right now my issue is that the player, which is constructed using a dynamic body, is stopping in mid-air right above my platforms, which are static bodies. He doesn’t hit the platform. A screenshot of what I mean:

As you can see, the player is floating on top of the platform. If you look closely, you can see a little dot where the corner of the hitbox is colliding with the platform, but no matter what I try I cannot get the player to actually hit the platform. I’ll show my code now.

This is how I create the player:

public static Body getDynamicBody(World world, float x, float y, float width, float height) {
		BodyDef def = new BodyDef();
		def.type = BodyType.DynamicBody;
		def.position.set(x * Game.WORLD_TO_BOX, y * Game.WORLD_TO_BOX);
		
		Body body = world.createBody(def);
		body.setFixedRotation(true);
		
		PolygonShape shape = new PolygonShape();
		shape.setAsBox((width / 2) * Game.WORLD_TO_BOX, (height / 2) * Game.WORLD_TO_BOX);
		
		FixtureDef fixture = new FixtureDef();
		fixture.shape = shape;
		fixture.density = 1;

		body.createFixture(fixture);
		
		shape.dispose();
		
		return body;
	}

And then rendering the player:

@Override
	public void render(SpriteBatch batch) {
		Sprite sprite = (Sprite) body.getUserData();
		sprite.setSize(width, height);
		float width = (sprite.getWidth() / 2) * Game.WORLD_TO_BOX;
		float height = (sprite.getHeight() / 2) * Game.WORLD_TO_BOX;
		sprite.setPosition((body.getPosition().x - width) * Game.BOX_TO_WORLD, (body.getPosition().y - height) * Game.BOX_TO_WORLD);
		sprite.draw(batch);
	}

Here is how I create the platform:

public static Body getStaticBody(World world, float x, float y, float width, float height) {
		BodyDef def = new BodyDef();
		def.position.set(x * Game.WORLD_TO_BOX, y * Game.WORLD_TO_BOX);

		Body body = world.createBody(def);
		
		PolygonShape shape = new PolygonShape();
		shape.setAsBox((width / 2) * Game.WORLD_TO_BOX, (height / 2) * Game.WORLD_TO_BOX);
		body.createFixture(shape, 0.0f);
		
		FixtureDef fixture = new FixtureDef();
		fixture.shape = shape;

		body.createFixture(fixture);
		
		shape.dispose();
		
		return body;
	}

And rendering is the same as the player. I update the Box2D like this:

world.step(1.0f / 60f, 5, 8);

And rendering it:

debugRenderer.render(world, getMain().getDebugCamera().combined.cpy().scale(Game.BOX_TO_WORLD, Game.BOX_TO_WORLD, 1));

Why would my player be floating above the platform?

Not sure if this helps but just from looking at the screenshot I think you might bhave got the rendering wrong. Check if you really take yor actual box2d coordinates and sizes (don’t forget. In box2d you define the an body by its center and the size in half width / half height. I’ve had nearly the exact same problem. Hmm. Just curious. Are the pink rectangles from the box debug renderer or your own. If they are from the debug renderer, then my theory is most likely wrong :wink:

My guess would be that the debugrenderer does not show the Box2D shapes in the correct size. The issue may be this line:

debugRenderer.render(world, getMain().getDebugCamera().combined.cpy().scale(Game.BOX_TO_WORLD, Game.BOX_TO_WORLD, 1));

Normally you would use a matrix for debug rendering that is a scaled version of the game world camera combined matrix. Do you use the debugCamera for rendering the game world, or is it a scaled version of the game world camera already?

If that dot is the collision point, it really does suggest the man is touching the platform, but they’re just being drawn too small. Hard to say from the code, e.g. there seem to be 2 versions of width and height here:

  sprite.setSize(width, height);
  float width = (sprite.getWidth() / 2) * Game.WORLD_TO_BOX;
  float height = (sprite.getHeight() / 2) * Game.WORLD_TO_BOX;

My guess is that he is not even using debug renderer, because I have just used Box2d (Libgdx version) and I don’t think that static and moving bodies have the same colour. (I don’t recall pink colour at all)

@Grunnt So I would use my main camera’s matrix? The debug camera does not render the world, it is there solely for rendering the Box2D debug renderer.

@richierich I also realized I had duplicate variables, but I changed that and nothing changed.

@trollwarrior I am using the debugRenderer, but I agree I don’t know why they both have the same color.

[quote=“opiop65,post:6,topic:51531”]
You should use a scaled version of the main camera matrix. I’m not sure what your debugcamera does and how it is initialized, but maybe there is the problem. This is what I do, and it works fine (and accurate) for me:

In update:

debugMatrix.set(worldView.getCamera().combined).scale(Constants.BOX2D_TO_SCREEN, Constants.BOX2D_TO_SCREEN,1f);

In render:

debugRenderer.render(world, debugMatrix);

[quote=“Grunnt,post:7,topic:51531”]

Well I tried this:

getMain().getDebugCamera().combined.set(getMain().getCamera().combined).scale(Game.BOX_TO_WORLD, Game.BOX_TO_WORLD, 1f);
		debugRenderer.render(world, getMain().getDebugCamera().combined);

But I get the same result as in my OP. My camera does not change position, so there’s not way it’s a camera issue. I am also certain that I am drawing in the correct location. Could this possibly be a Box2D bug? I wonder if my scaling is off somehow?

if it is off by the same margin each time you can just fake the rendering

Hacky much? lol, the thing is this shouldn’t be happening in the first place. It does not happen for anyone else’s project, so using a hacky workaround is a bit meh.

  • I think OP might have solved it, according to his capitalized sentences in chat lol.

I did solve the problem by creating a camera in meters and scaling all my drawing down to a scale of 1 / 100 and positing everything in meters. Everything is fine now!