Well, I'm making a little top-down JRPG and today I was like 'Yeah, I'm gonna bust out this whole map collision thing!'. I failed.


So I went on the internet and looked up 'LibGDX Tiled Map Collision Detection' and found a really neat post about Map Objects so I added in a map object layer and did all that biz and came out with this little method to ensure the player can move freely around the map but at the same time can't exit it but each time I've tried it ends up with a horrible result such as the player moving off the screen. The latest error is that the player gets stuck doing a walk animation and can't move anywhere else!


package com.darkbyte.games.tfa.game.entity.entities;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.objects.RectangleMapObject;
import com.badlogic.gdx.math.Rectangle;
import com.darkbyte.games.tfa.game.entity.Entity;
import com.darkbyte.games.tfa.game.entity.SpriteSheet;
import com.darkbyte.games.tfa.game.world.map.MapManager;
import com.darkbyte.games.tfa.render.Batch;
import com.darkbyte.games.tfa.render.Camera;

public class Player extends Entity {

    // The constructor for the player class
    public Player(String name, SpriteSheet spriteSheet) {
        super(name, spriteSheet);
        direction = Direction.DOWN;
        collisionBox = new Rectangle(x, y, 64, 64);

    // A flag to see if the player is moving
    private boolean isMoving;
    // The variable that holds the state time
    private float stateTime;

    // The player's walking animations
    private Animation[] walkAnimations = {
            spriteSheet.getAnimation(8, 8, 1 / 16f),
            spriteSheet.getAnimation(9, 8, 1 / 16f),
            spriteSheet.getAnimation(10, 8, 1 / 16f),
            spriteSheet.getAnimation(11, 8, 1 / 16f) };
    // The player's static frames
    private TextureRegion[] staticFrames = {
            spriteSheet.getTexture(8, 0),
            spriteSheet.getTexture(9, 0),
            spriteSheet.getTexture(10, 0),
            spriteSheet.getTexture(11, 0) };

    // The render code for the player
    public void render() {
        // Makes the camera follow the player
        Camera.setCameraPosition(x, y);

        // Updates the state time
        stateTime += Gdx.graphics.getDeltaTime();

        // Gets the player's direction, if the player's moving, it sets the
        // current frame to the frame that would be played at the current moment
        // based on the state time
        // If the player isn't moving, it sets the current frame to the static
        // frame associated to the direction
        switch (direction) {
        case UP:
            if(isMoving) {
                currentFrame = walkAnimations[0].getKeyFrame(stateTime, true);
            } else
                currentFrame = staticFrames[0];
        case LEFT:
            if(isMoving) {
                currentFrame = walkAnimations[1].getKeyFrame(stateTime, true);
            } else
                currentFrame = staticFrames[1];
        case DOWN:
            if(isMoving) {
                currentFrame = walkAnimations[2].getKeyFrame(stateTime, true);
            } else
                currentFrame = staticFrames[2];
        case RIGHT:
            if(isMoving) {
                currentFrame = walkAnimations[3].getKeyFrame(stateTime, true);
            } else
                currentFrame = staticFrames[3];

    // The tick code for the player
    public void tick() {
        // The object to represent the bounds of the land on the map
        RectangleMapObject land = (RectangleMapObject) MapManager.getCurrentMap().getMap().getLayers().get("collision").getObjects().get("land");

        // Checks if the player is within the bounds of the map
        if(land.getRectangle().contains(collisionBox)) {
            // If the player is moving but the arrow keys aren't pressed, sets isMoving to false
            isMoving = (isMoving && (Gdx.input.isKeyPressed(Keys.W) || Gdx.input.isKeyPressed(Keys.UP)
                    || Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyPressed(Keys.LEFT)
                    || Gdx.input.isKeyPressed(Keys.S) || Gdx.input.isKeyPressed(Keys.DOWN)
                    || Gdx.input.isKeyPressed(Keys.D) || Gdx.input.isKeyPressed(Keys.RIGHT)));

            // Checks to see if the arrow / WASD keys are pressed and moves the
            // player in the correct direction at the speed of 1.5 pixels/tick
            // (45/second)
            // It also sets the players state to moving and corresponds it's
            // direction to the key pressed
            // Doesn't move if opposing keys are pressed
            if(Gdx.input.isKeyPressed(Keys.W) || Gdx.input.isKeyPressed(Keys.UP)) {
                if(!(Gdx.input.isKeyPressed(Keys.S) || Gdx.input.isKeyPressed(Keys.DOWN))) {
                    direction = Direction.UP;
                    y += 1.5f;
                    isMoving = true;

            if(Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyPressed(Keys.LEFT)) {
                if(!(Gdx.input.isKeyPressed(Keys.D) || Gdx.input.isKeyPressed(Keys.RIGHT))) {
                    direction = Direction.LEFT;
                    isMoving = true;
                    x -= 1.5f;

            if(Gdx.input.isKeyPressed(Keys.S) || Gdx.input.isKeyPressed(Keys.DOWN)) {
                if(!(Gdx.input.isKeyPressed(Keys.W) || Gdx.input.isKeyPressed(Keys.UP))) {
                    direction = Direction.DOWN;
                    y -= 1.5f;
                    isMoving = true;

            if(Gdx.input.isKeyPressed(Keys.D) || Gdx.input.isKeyPressed(Keys.RIGHT)) {
                if(!(Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyPressed(Keys.LEFT))) {
                    direction = Direction.RIGHT;
                    x += 1.5f;
                    isMoving = true;
        } else {
            if(!isMoving) {
                // If the player's just spawned puts the player to the map's spawn point
                x = MapManager.getCurrentMap().getPlayerSpawnX();
                y = MapManager.getCurrentMap().getPlayerSpawnY();
            } else { // If not, it just moves them back till they're no longer out of the map
                if(x > (land.getRectangle().getX() + land.getRectangle().getWidth())) x -= 1.5;
                if(y > (land.getRectangle().getY() + land.getRectangle().getHeight())) y -= 1.5;

        // Synchronises the collision box with the player's x and y position
        collisionBox.x = x;
        collisionBox.y = y;

    // Returns if the player is moving
    public boolean isMoving() {
        return isMoving;

Can you guys make it so that when he reaches the border that he stops but he can still keep moving!

Thanks for reading!


Try it this way :

First of all, create this four variables:
boolean left,right,up,down;
The next thing you wanna do is to create these variables:
boolean canleft,canright,canup,candown;
Now use four collision-boxes instead of one, one one the left side, one on the right, one on the upside and finally one on the downside of your character.
When you check for collision, set at the beginning all the canleft, canright and so on variables to true, and if there is a collision with the left collision box of your character, set canleft to false and the same for all the other boxes.
Now to your keyevents: set left to true, when the key for left is pressed, set it to false if it is released, same for up,down and right.
The last step you wanna do, is moving: Only move your character to the left, if canleft and left are true, the same is for right, up and down.

I hope you get the idea and that I could help at least a bit... Comment below if you need any further explanation

  • \$\begingroup\$ No problem, glad I could help \$\endgroup\$ – PixelKicker Dec 28 '15 at 18:58

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.