Search code examples
javalibgdx

Near perfect collision in LibGdx Java


I am trying to get the collision in my game to be exactly perfect. What I am testing is if you hit a wall with the player, you come to a stop. I only implemented the collision code for when the player hits the left side of a wall(when the wall is on the right side of the player). Here is the code.

    if(entityOnRight){
        if(player.getPositionCorner(SquareMapTuples.BOTTOM_RIGHT).x -
                ent.getPositionCorner(SquareMapTuples.BOTTOM_LEFT).x > -.9f)
            player.setMovementBooleans(false, false, false, false);
        else
            player.setMovementBooleans(true, false, false, false);
    }

Note: If I go very slow, it will stop the player where I desire it to be stopped, but going fast, it won't do the collision the way I want

Essentially, the code states if the wall is on the right side, it will check the bottom right corner of the rectangle of the player, subtract the bottom left corner of the wall, and check if the distance between the two is 0.001. 0.001 is almost an unnoticeable distance, hence why I used that value. Here is the code for player.setMovementBooleans

public void setMovementBooleans(boolean canMoveRight, boolean canMoveLeft, boolean canMoveUp, boolean canMoveDown){

    this.canMoveRight = canMoveRight;
    if(canMoveRight == false && moveRight)
        vel.x = 0;
}

The canMoveRight boolean in the Player class (not in parameters) is what allows you to be able to move, moveRight is when you are trying to move right. Here is some code that will better explain how these booleans interact:

//If you clicked right arrow key and you're not going 
    //Faster then the max speed

    if(moveRight && !(vel.x >= 3)){
        vel.x += movementSpeed;
    }else if(vel.x >= 0 && !moveRight){
        vel.x -= movementSpeed * 1.5f;
        System.out.println("stopping");
        //Make sure it goes to rest
        if(vel.x - movementSpeed * 1.5f < 0)
            vel.x = 0;
    }

and:

if(Gdx.input.isKeyPressed(Keys.D) && canMoveRight)
        moveRight = true;
    else
        moveRight = false;

So to give a summary, if you click the "D" key, it allows you to start moving. However if the boolean canMoveRight is false, it won't move you. Here is an image showing what happens (The player is yellow, the wall is green)

enter image description here

As you can see, the player goes much further then I want it to. It should stop at this point:

enter image description here

Any help with figuring out how to accomplish this is extremely appreciated!


Solution

  • Maybe the way you tried it is a bit too complicated :-). I suggest a simpler way from scratch: make the map and the player a com.badlogic.gdx.math.Rectangle instance. Now, in the following part of the code you make a check, whether after the move the player would still be inside the map, if yes then allow the move, if not, then don't allow:

    if(Gdx.input.isKeyPressed(Keys.D){
        float requestedX, requestedY;
        //calculate the requested coordinates
        Rectangle newPlayerPositionRectangle = new Rectangle(requestedX, requestedY, player.getWidth(), player.getHeight());
        if (newPlayerPositionRectangle.overlaps(map) {
            //move the player
        } else {
            //move the player only to the edge of the map and stop there
        }
    }