0
\$\begingroup\$

I had a problem where the sprite was not positioned on Body correctly which I solved and you can see it here.

After I solved that, I needed to divide everything by PIXELS PER METERS so that I can convert the sizes because of Box2D, but since I did that I have the same problem again, the sprite is not positioned on the Body correctly and it does not follow the body when it moves.

This is the image:

enter image description here

This is the code for the player class:

public class Player extends Sprite {

    public World world;
    public Body body;

    private Texture playerTexture;

    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")));
        playerTexture = getTexture();
     // super(new Texture(Gdx.files.internal("Clouds/Cloud 1.png")));
     // playerTexture = new Texture(Gdx.files.internal("Player/Player 2.png"));
     // setTexture(playerTexture);

        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());
        bodyDef.position.set(getX() / GameInfo.PPM, getY() / GameInfo.PPM);

        // create body in the world using our definition
        body = world.createBody(bodyDef);
        body.setFixedRotation(true);
        // body.setUserData(new Sprite(
        // new Texture(Gdx.files.internal("Player/Player 1.png"))));

        // define the dimensions of the physics shape
        PolygonShape shape = new PolygonShape();
        // shape.setAsBox((getWidth() / 2),
            // (getHeight() / 2));

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

        // 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);
        // fixture.setUserData(new Sprite(playerTexture));

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

        this.setPosition((body.getPosition().x),
                (body.getPosition().y));

        System.out.println("PLAYER position " + this.getX() + " " + this.getY());
        System.out.println("BODY position " + body.getPosition().x
                + " " + body.getPosition().y);

    } // create body

        //    public void drawPlayer(SpriteBatch batch) {
        //        batch.draw(playerTexture, body.getPosition().x,
        //                body.getPosition().y);
        //    }

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

        // this.setPosition(body.getPosition().x / GameInfo.PPM,
        // body.getPosition().y / GameInfo.PPM);
    }

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

    public void movePlayer(float x) {
        body.applyForce(new Vector2(x, 0),
                body.getWorldCenter(), true);
    }

} // class

This is my code for the cloud(which works and its practically the same code):

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));

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

        // 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);

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

        // 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

This is my Gameplay class where I run everything:

public class Gameplay implements Screen {

    GameMain game;

    private OrthographicCamera box2DCamera;
    private OrthographicCamera mainCamera;
    private Viewport gameViewport;

    Texture bg;

    private Hud hud;

    private Player player;

    private World world;

    // delete this later
    private Box2DDebugRenderer b2Renderer;

    Clouds cloud;

    private Array<Body> bodies = new Array<Body>();

    public Gameplay(GameMain game) {

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

        box2DCamera = new OrthographicCamera();
        box2DCamera.setToOrtho(false, GameInfo.WIDTH / GameInfo.PPM,
                GameInfo.HEIGHT / GameInfo.PPM);

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

        mainCamera = new OrthographicCamera(GameInfo.WIDTH, GameInfo.HEIGHT);

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

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

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

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

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

    }

    void handleInput(float deltaTime) {
        if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            player.movePlayer(-7);
        } else if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            player.movePlayer(7);
        }
    }

    void update(float deltaTime) {
        handleInput(deltaTime);
    }

    @Override
    public void show() {

    }

    @Override
    public void render(float delta) {

        update(delta);

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

        // box2DCamera.update();
        // world.step(1 / 60f, 6, 2);
        world.step(Gdx.graphics.getDeltaTime(), 6, 2);

        // player.updatePlayer();

        world.getBodies(bodies);

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

        //        for(Body body : bodies) {
        //            if(body == player.body) {
        //                if(body.getUserData() instanceof Sprite) {
        //                   Sprite jack = (Sprite) body.getUserData();
        //                    jack.setPosition(player.body.getPosition().x,
        //                            player.body.getPosition().y);
        //                    jack.draw(game.batch);
        //                }
        //            }
        //        }


        // player.drawPlayer(game.batch);
        game.batch.draw(player, player.getX(), player.getY());

        // b2Renderer.render(world, box2DCamera.combined);

        game.batch.end();

        b2Renderer.render(world, box2DCamera.combined);

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

        player.updatePlayer();
        // updatePlayer();

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

    }

    @Override
    public void resize(int width, int height) {
        gameViewport.update(width, height);
        // gameViewport.update(width / GameInfo.PPM,
            // height / GameInfo.PPM);
        // gameViewport.setWorldWidth(width / GameInfo.PPM);
        // gameViewport.setWorldHeight(height / GameInfo.PPM);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

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

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

} // class

I'm really confused what is going on here, when I try to move the player he is not following the body and also he is not rendered on the body, but the same code in the Cloud class works for the cloud and the cloud is drawn on the body, I don't get what is going on here.

Any help would be highly appreciated.

\$\endgroup\$
2
\$\begingroup\$

In your createBody function:

this.setPosition((body.getPosition().x),(body.getPosition().y));

Since the x and y position of the body is already divided by PPM you need to either multiply it by PPM again or remove this line completly because you already set the position in the constructor.

\$\endgroup\$
  • \$\begingroup\$ thank you for taking the time to answer, this is the strange thing, when I removed the line this.setPosition((body.getPosition().x),(body.getPosition().y)) and when I also multiplied that by PPM the same thing happened, the player is positioned in the same place, I really don't get what is going on. \$\endgroup\$ – Fahir M Mar 31 '16 at 15:11
0
\$\begingroup\$

This ended up fixing the problem:

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

Calling this in the render function and calling this in the render function:

game.batch.draw(player, player.getX() - player.getWidth() / 2f,
            player.getY() - player.getHeight() / 2f);

I multiplied the body positions by PPM as @ProRed suggested, so thank you @ProRed you helped me to solve it.

\$\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.