Search code examples
javalibgdxbox2d

libgdx box2d, texture/body not in correct place when created at an angle


When I create a Body and draw a Texture where that body is, if the angle is set to 0.0f, it appears exactly where expected. Upright and at the centre x and y of the Player (the black circle). When this angle changes, the x and y of the texture appear to be completely off. In fact they tend to be off the screen as I can only see them visibly sometimes as they fall with the gravity.

Here's the method where I create a new bullet:

private void shoot(final float delta) {
    gameTime += delta;
    final float timeSinceLastShot = gameTime - lastBulletShotTime;
    //5 bullets a second, kerpow
    if (timeSinceLastShot > 0.2f) {
        lastBulletShotTime = gameTime;
        shot.play();

        final float shotX = player.getX() + ((player.getWidth() / 2) - (bulletTexture.getWidth() / 2));
        final float shotY = player.getY() + ((player.getHeight() / 2) - (bulletTexture.getHeight() / 2));

        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(shotX, shotY);

        Body body = world.createBody(bodyDef);
        float angle = player.getRotation() * MathUtils.degreesToRadians;
        body.setTransform(body.getPosition().x, body.getPosition().y, angle);
        System.out.println("angle rad: " + angle);
        bullets.add(body);

        PolygonShape shape = new PolygonShape();
        shape.setAsBox(bulletTexture.getWidth() / 2, bulletTexture.getHeight() / 2);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        fixtureDef.density = 1f;
        Fixture fixture = body.createFixture(fixtureDef);

        shape.dispose();
    }
}

And here's the part of the render method where I loop and draw the bullets:

for (Body bullet : bullets) {
            final float x = bullet.getPosition().x;
            final float y = bullet.getPosition().y;
            final float originX = x + (bulletTexture.getWidth() / 2);
            final float originY = y + (bulletTexture.getHeight() / 2);
            final float width = bulletTexture.getWidth();
            final float height = bulletTexture.getHeight();
            final float scaleX = 1.0f;
            final float scaleY = 1.0f;
            final float rotation = bullet.getAngle() * MathUtils.radiansToDegrees;
            final int sourceX = 0;
            final int sourceY = 0;
            final int sourceWidth = bulletTexture.getTextureData().getWidth();
            final int sourceHeight = bulletTexture.getTextureData().getHeight();
            final boolean flipX = false;
            final boolean flipY = false;

            batch.draw(bulletTexture,
                    x, y,
                    originX, originY,
                    width, height,
                    scaleX, scaleY,
                    rotation,
                    sourceX, sourceY,
                    sourceWidth, sourceHeight,
                    flipX, flipY);
        }

Any tips for what I'm doing wrong? I want the bullets to always start at the centre of the Player Circle, but also at the correct angle. I then intend to add some velocity so they 'shoot'.

The full code can be found here on Github https://github.com/SamRuffleColes/PlayerCircle/blob/master/core/src/es/rufflecol/sam/playercircle/PlayerCircle.java

I've also attached a screenshot, everything has fallen a little with the gravity between shooting and taking this, but the bottom left bullets appeared in the right place initially, while all the others have fallen from off the screen (some others which I 'shot' were never visible).

screenshot


Solution

  • My mistake was with the originX and originY. Corrected to the below, it now works:

    final float originX = bulletTexture.getWidth() / 2;
    final float originY = bulletTexture.getHeight() / 2;