1
\$\begingroup\$

I have a strange issue where my Box2D is not being positioned on the player correctly. Down is the picture:

enter image description here

What I find more strange is that the Box2D is positioned correctly on the cloud that is below my player, and I use the same code for both.

The code for creating the body for the player:

public class Player extends Sprite {

public World world;
public Body body;

public Player() {
    super(new Texture(Gdx.files.internal("Player/Player 1.png")));
}

public Player(World world, float x, float y) {
    super(new Texture(Gdx.files.internal("Player/Player 1.png")));
    this.world = world;
    setPosition(x, y);
    createBody();
}

void createBody() {

    BodyDef bodyDef = new BodyDef();

    // dynamic body is affected by other forces e.g. gravity and it has velocity
    // static body is not affected by other forces gravity and it does not have velocity
    // kinematic body is not affected by gravity but it can be manipulated by velocity
    bodyDef.type = BodyDef.BodyType.DynamicBody;

    bodyDef.position.set(getX(), getY());

    // create body in the world using our definition
    body = world.createBody(bodyDef);

    // define the dimensions of the physics shape
    PolygonShape shape = new PolygonShape();

    shape.setAsBox(getWidth() / 2, getHeight() / 2);

    // FixtureDef is a confusing expression for physical properties
    // Basically this is where you, in addition to defining the shape of the body
    // you also define it's properties like density, restitution and others
    // If you are wondering, density and area are used to calculate over all mass
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 1f;

    Fixture fixture = body.createFixture(fixtureDef);

    // shape is disposable now so get rid of it
    shape.dispose();

} // create body

public void updatePlayer() {
    this.setPosition(body.getPosition().x, body.getPosition().y);
}

} // class

The code for creating the body for the cloud:

public class Clouds extends Sprite {

private World world;
private Body body;

public Clouds(World world, float x, float y) {
    super(new Texture(Gdx.files.internal("Clouds/Cloud 1.png")));
    this.world = world;
    setPosition(x - getWidth() / 2, y);
    createClouds();
}

void createClouds() {

    BodyDef bodyDef = new BodyDef();

    // dynamic body is affected by other forces e.g. gravity and it has velocity
    // static body is not affected by other forces gravity and it does not have velocity
    // kinematic body is not affected by gravity but it can be manipulated by velocity
    bodyDef.type = BodyDef.BodyType.StaticBody;

    bodyDef.position.set(this.getX() + getWidth() / 2,
            this.getY() + (getHeight() / 2 - 10));

    // create body in the world using our definition
    body = world.createBody(bodyDef);

    // define the dimensions of the physics shape
    PolygonShape shape = new PolygonShape();

    shape.setAsBox(this.getWidth() / 2, this.getHeight() / 2);

    // FixtureDef is a confusing expression for physical properties
    // Basically this is where you, in addition to defining the shape of the body
    // you also define it's properties like density, restitution and others
    // If you are wondering, density and area are used to calculate over all mass
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 1f;

    Fixture fixture = body.createFixture(fixtureDef);

    // shape is disposable now so get rid of it
    shape.dispose();

} // create body

} // class

And here is where I'm creating the player and the cloud and adding them in my game world:

public class Gameplay implements Screen {

GameMain game;

private OrthographicCamera camera;
private Viewport gameViewport;

Texture bg;

private Hud hud;

private Player player;

private World world;

// delete this later
private Box2DDebugRenderer b2Renderer;

Clouds cloud;

public Gameplay(GameMain game) {

    this.game = game;
    camera = new OrthographicCamera(GameInfo.WIDTH, GameInfo.HEIGHT);

    camera.position.set(GameInfo.WIDTH / 2f,
            GameInfo.HEIGHT / 2f, 0);

    gameViewport = new StretchViewport(GameInfo.WIDTH, GameInfo.HEIGHT, camera);

    bg = new Texture(Gdx.files.internal("Backgrounds/Game BG.png"));
    hud = new Hud(this.game.batch);

    world = new World(new Vector2(0, -98), true);
    b2Renderer = new Box2DDebugRenderer();

    player = new Player(world,
            GameInfo.WIDTH / 2,
            GameInfo.HEIGHT/ 2 + 100);

    cloud = new Clouds(world,
            GameInfo.WIDTH / 2,
            GameInfo.HEIGHT/ 2 - 100);

}

@Override
public void show() {

}

@Override
public void render(float delta) {

    // update the physics world
    world.step(Gdx.graphics.getDeltaTime(), 6, 2);

    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    game.batch.begin();
    game.batch.draw(bg, 0, 0);
    game.batch.draw(cloud, cloud.getX(), cloud.getY());
    game.batch.draw(player, player.getX(), player.getY());
    game.batch.end();

    b2Renderer.render(world, gameViewport.getCamera().combined);

    game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
    hud.stage.draw();

    player.updatePlayer();

}

@Override
public void resize(int width, int height) {
    gameViewport.update(width, height);
}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    bg.dispose();
    world.dispose();
    b2Renderer.dispose();
}

} // class

Is it possible that the issue is with the sprite itself, maybe when the sprite is created in photoshop? Or am I missing something here?

Any help would be greatly appreciated.

P.S. - GameInfo.Width is 480 and GameInfo.Height is 800 if that can help someone figure this out.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Try changing from this bodyDef.position.set(getX(), getY()); to this bodyDef.position.set(getX() + getWidth () / 2.0f, getY() + getHeight () / 2.0f);

When setting the position of the BodyDef for the player.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for taking the time to answer @bornander, I tried what you suggested and the result is the same, which is really strange, exactly the same as in the picture above where I use bodyDef.position.set(getX(), getY()); \$\endgroup\$ Mar 29, 2016 at 5:31
0
\$\begingroup\$

Finally fixed it.

I ended up typing thins:

public void updatePlayer() {
    this.setPosition(body.getPosition().x - getWidth() / 2f,
            body.getPosition().y - getHeight() / 2f);
}

instead of this:

public void updatePlayer() {
    this.setPosition(body.getPosition().x, body.getPosition().y);
}

But its really strange that this code did not work:

bodyDef.position.set(getX(), getY());

or this code did not also work:

bodyDef.position.set(getX() - getWidth() / 2f, 
            getY() - getHeight() / 2);

And whats even more strange the same code worked for the cloud.

But as I said, finally found the solution, thank you all for your help.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .