I have a strange issue where my Box2D is not being positioned on the player correctly. Down is the picture:
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.
Answer
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.
No comments:
Post a Comment