Search code examples
javaandroidlibgdxbox2d

LibGdx Box2d collison not matching up with sprite


I am making a game as a project for a college class. when my main character (the tree) hits the ground, it stops short of the ground

screenshot 1

and when the player lands on the little platform that gap is even bigger

screenshot 2

my code for creating the body of the character and and ground is this

public static Body createBody(int x, int y, float width, float height, boolean isStatic){
        Body body;

        BodyDef def = new BodyDef();

        if(isStatic){
            def.type = BodyDef.BodyType.StaticBody;
        }
        else {
            def.type = BodyDef.BodyType.DynamicBody;
        }


        def.position.set(x / PPM , y / PPM);

        // returns a World object    
        body = GlobalWorld.getInstance().createBody(def);

        PolygonShape shape = new PolygonShape();

        shape.setAsBox(width / 2 / PPM, height / 2 / PPM);

        body.createFixture(shape, 1.0f);

        shape.dispose();
        return body;
}

The code for the ground is in it's own class

public class Material {
    private Texture image;
    private Body body;
    private Sprite sprite;

    public Material(Texture t, int x, int y, int w, int h){
        image = t;
        sprite = new Sprite(t);
        body = BoxBuilder.createBody(x, y, w, h, true);
        body.setUserData("Ground");
    }

    public void draw(){
        // returns a SpriteBatch
        SpriteBatch batch = GlobalBatch.getInstance();
        sprite.setPosition(body.getPosition().x * PPM, body.getPosition().y * PPM);
        batch.begin();
        sprite.draw(batch);
        batch.end();
    }

    public void dispose(){
        image.dispose();
    }
}

the code for drawing the ground

public void draw(){
     for(Material m : worldObjects){
        m.draw();
     }
}

my code for drawing the character

public void create(){
    // do stuff

    // global vars
    body = createBody(0, 480, 313, 260, false);

    texture = new Texture("tree.PNG");
    sprite = new Sprite(texture);

    // do stuff
}

public void render(){
    // do stuff
    sprite.setPosition(body.getPosition().x*PPM, body.getPosition().y*PPM);
    batch.begin()
    sprite.draw(batch)
    batch.end()
    // do stuff
}

and PPM(Pixel per Meter) is

public static final float PPM = 32;

I don't know what is the problem here, I want the character to land on the ground, not land above it. So if someone could tell me what's causing this or point me to a good tutorial for learning more about box2d I'd appreciate it.


Solution

  • When we create body with PolygonShape then body is at the center of that Polygon so when draw with body position it starts drawing from center of PolygonShape so we need to draw at left bottom corner.

    In Material class

    replace

    sprite.setPosition(body.getPosition().x * PPM, body.getPosition().y * PPM);
    

    with

    sprite.setPosition(body.getPosition().x*PPM-sprite.getWidth()/2,body.getPosition().y-sprite.getHeight()/2);
    sprite.setRotation(body.getAngle()*MathUtils.radDeg);
    

    And for Character draw also change

    sprite.setPosition(body.getPosition().x*PPM, body.getPosition().y*PPM);
    

    with

    sprite.setPosition(body.getPosition().x*PPM-sprite.getWidth()/2, body.getPosition().y*PPM-sprite.getHeight()/2);
    sprite.setRotation(body.getAngle()*MathUtils.radDeg);
    

    As I see in your code you're not setting size of Sprite in Material class as well as for Character so set width and height.

    In Material Class

    sprite = new Sprite(t);
    sprite.setSize(w,h); 
    

    And for Character

    body = createBody(0, 480, 313, 260, false);
    texture = new Texture("tree.PNG");
    sprite = new Sprite(texture);
    sprite.setSize(313,260);