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
\$\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\$
  • \$\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\$ – Fahir M Mar 29 '16 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.