1
votes

So right now I'm trying to make a game where you keep running right and have to jump over obstacles. I've made it so that the ground is made out of two big blocks, and when you are a fourth of the way on the second block the first block get moved in front of the second block. This is my code for this.

    public void updateGround(){
    if(player.getPosition().x >= blocks[1].getGeneratePoint()){
        //swap the blocks in the array
        Block tempblock = blocks[0];

        blocks[0] = blocks[1];
        blocks[1] = tempblock;

        Body body1 = blocks[0].getBody();
        blocks[1].getBody().setTransform(body1.getPosition().x+(gBlockSize*2)/B2DVars.PPM,
                0,0);
    }
}

I wanted to stress test this so I made the block size kinda small and just left it running but I notice after awhile my guy stops running. I realised by using the b2drenderer and other testing that somehow the player is making contact with the second block and it stops right where the second block begins.

Is this some sort of bug or did I do something wrong? I know for sure that neither ground block change their y value or their angles cause their set to be 0 and I have even tried making it so that the ground block go into eachother, but the player still stop where the second block begins.

3

3 Answers

3
votes

this is well known problem of Box2d - there is problem on two bodies contact point - it often behaves like one of them is a little big higher (even if they have same sizes and positions) and is connected with box2d precision.

The best idea to avoid this situation is creating ground using ChainShape

Simple code example how-to is:

    //float[] vertices - array with vertices of shape: [x1, y1, x2, y2...]
    Vector2[] worldVertices = new Vector2[vertices.length / 2];

    for (int i = 0; i < vertices.length / 2; ++i) {
        worldVertices[i] = new Vector2();
        worldVertices[i].x = vertices[i * 2] / PPM;
        worldVertices[i].y = vertices[i * 2 + 1] / PPM;
    }

    ChainShape chain = new ChainShape(); 
    chain.createChain(worldVertices);

You can also read about it here: http://www.box2d.org/manual.html

Regards, MichaƂ

0
votes

One thing to consider is precision. If you run this over a very long time float inaccuracies pile up and things start behaving a bit odd. Generally, if you are going to make something run in a direction for an infinite amount of time, at some point it is good to 'shift' the entire world over back into smaller number ranges where inaccuracies aren't as prevalent.

You will especially see this if you are performing these actions with 'transforms' rather than explicitly setting exacting values for your characters.

Try introducing a world shift and see if that cleans it up for you :)

Conversely, if that doesn't work, try introducing a slight overlap of the boxes edges. Often boundary conditions can experience some issues when you work with 'overly precise' systems.

0
votes

Solution 1 if you use a box for the player:

If you whant to keep the boxes use a polygon like in this picture:

example

This way your player cant get stuck in a edge of a box and gets pushed up insted of coliding with the edge.

Solution 2

Very simple just use a circle for the "feet" of your player.