Simple rectangle collision problem (PacMan clone)

I am struggling with some basic rectangle collision in my pacman clone, hoping for some help or simplification.

So I am using libgdx Tiled maps, in which I have made an object layer, and surrounded all the collide-able things with rectangles. My player is also represented as a rectangle, and I use these to handle collision.

Here is my problem graphically (I made debug render classes to help see the problem):

Holding right button, then right + up, when approaching corner.

Holding right button and up button, player now stuck. Must press left, then up, to move up.

Essentially, I have sliding on the walls working, but when I get to a corner, the rectangles mash together and block movement. I want this to slide around the corner, and not get stuck.

I know this is probably something really simple I am overlooking, but I cant quite place my finger on it.

Here is my rough Player movement code:
http://pastebin.java-gaming.org/c3cf63e321b1c

  1. First I add a number to velX or velY based on input.
  2. Then I check the future player rectangle, using the velocities from 1. to determine if the player will collide in the X or Y directions.
  3. Finally, if the player is not colliding in X, move player in X.
  4. If the player is not colliding in Y, move player in Y.

It seems like I need to have code that says “As soon as the player can move up, move up and stop all X movement”, but I cannot figure out how to implement it.

I would greatly appreciate some help with my problem. Thanks.

I have figured out where my problem lies.
In the following code:


        if (!collidingX) {
            position.x += velX / 16;
            playerRect.x += velX;
        }
        if (!collidingY) {
            position.y += velY / 16;
            playerRect.y += velY;
        }

I failed to take into account the situation where (collidingY && collidingX), such as when the player is in a corner. I have tried putting the player back to their previous location, but that just causes a strange jiggle and no real progress.

What about making some kind of “rails” so the player and ghost follow those rails, and you only have to care about collion with ghost, fruits, etc, but no with walls.

Rails can be the “walkable” tiles, so when you press up, you check if there is a walkable tile in the up direction, and same for other direcions. For each tile you will need to know the near walkable tiles.

I ended up solving my problem, and it was quite simple.

I was doing


// check for collisions in X or Y directions
        if(detectCollision(new Rectangle(playerRect.x+velX, playerRect.y, playerRect.width, playerRect.height))){
            collidingX=true;
            velX = 0;
        }
        if(detectCollision(new Rectangle(playerRect.x, playerRect.y+velY, playerRect.width, playerRect.height))){
            collidingY=true;
            velY = 0;
        }        

        if (!collidingX) {
            position.x += velX / 16;
            playerRect.x += velX;
        }
        if (!collidingY) {
            position.y += velY / 16;
            playerRect.y += velY;
        }

When I should be doing


// check for collisions in X or Y directions
        if(detectCollision(new Rectangle(playerRect.x+velX, playerRect.y, playerRect.width, playerRect.height))){
            collidingX=true;
            velX = 0;
        }
        if (!collidingX) {
            position.x += velX / 16;
            playerRect.x += velX;
        }
        if(detectCollision(new Rectangle(playerRect.x, playerRect.y+velY, playerRect.width, playerRect.height))){
            collidingY=true;
            velY = 0;
        }        
       
        if (!collidingY) {
            position.y += velY / 16;
            playerRect.y += velY;
        }

I was doing AABB when I should have been doing ABAB.