Debugging movement/collision code in 2d tile game

Hello, I’m working on a top down 2d game and am having some problems with collision detection. Here is a basic screenshot.

https://dl.dropboxusercontent.com/u/24222531/game1.png

My issue involves buggy movement. If I spam movement keys near a wall, I can pass through and get stuck. I think my problem may be related to multiple threads, but I am not sure.

I have a text file grid of integers read in for collision, 1 = not passable, 0 = passable. My checkCollision function checks the proposed new player position for a collision, and disallows that movement if there is a tile.

I use a overridden Keymanager classhttp://pastebin.java-gaming.org/b9854254086 to alter Player’s public variables UP, DOWN, LEFT, RIGHT to transfer keyboard to game logic.

Here is the player tick class:


public class Player {
**SNIP SNIP**
public void tick() {
        if (moving) {
            updatePlayerPosition();
        }

        if (sprinting) {
            moveSpeed = SPRINT; // 16
        } else {
            moveSpeed = WALK; // 8
        }

        if (!moving) {
            if (up) {
                moveUp();
            }
            if (down) {
                moveDown();
            }
            if (right) {
                moveRight();
            }
            if (left) {
                moveLeft();
            }

        }


Here I update the player movement if they are still in the process of moving from one tile to another. http://pastebin.java-gaming.org/9854530468e

private void updatePlayerPosition() {
       
        switch (facing) {
            case "north":
                if (!detectCollision(tileX, tileY - 1)) {
                    northAnimator.update(System.currentTimeMillis());
                    y -= moveSpeed;
                    if (y % 32 == 0) {
                        moving = false;
                        tileY = (int) pixelsToTileY(y);
                    }
                }
                break;
            case "south":
*SNIPSNIP*
        }
    }

This simply changes facing direction, sets moving to true, and lets the above method handle the rest. http://pastebin.java-gaming.org/4506e684f89

private void moveUp() { // move player up
        // if not facing north, make facing north

        if (!facing.equals("north")) {
            facing = "north";
        } else {

            // else, detect collision in the direction            
            if (!detectCollision(tileX, tileY - 1)) {
                moving = true;
            }
        }
    }

Somewhere in here there is a bug going on. I know the detectcollision method is working properly as I debugged it with println’s. It seems that sometimes, while I am actively “Moving”, my direction can change and place me in a wall. Note that this code has double collision checking, I tried with one and it simply let me into impassable walls, with two checks i actually get stuck in the wall and cant move at all.

Can anyone help me out here. Is there a simpler way of getting animated tile movement?

You shouldn’t need multithreading for a simple 2D game.

Multithreading is a nightmare and introduces lots of problems. It’s probably best you don’t use it unless you’re absolutely certain you need it.

You are most likely dealing with rounding issues with the player’s position when checking against the tile coordinates on the map.

I’m doing stuff like this to start up my game, not sure if this is multithreading or just one thread getting started up?

public class TileGame extends Canvas implements Runnable {

public synchronized void start() {
        if (running) {
            return;
        }
        running = true;
        gameThread = new Thread(this);
        gameThread.start();}
@Override
    public void run() {
*snipsnip*

    }


On second thought, I dont think it is multithreaded. I kinda followed a tutorial for the basic game loop stuff, and I think all this just starts up one thread for the game.

Here you go, a full proof tutorial on collision within tiles.

Thank you, I will review this.

Is that theChernoProject? If it is, I have to say he’s an ok programmer, but one thing that has always bugged me is his use of threads. You don’t need to manually create a thread just to start a game. There is absolutely (as far as I know) no advantage to it, and it really isn’t a good design.

You need to create a separate thread for your game when you’re using JFrame. If you don’t, you will have problems with JFrame.

The great tutorial maker arrives! I was just reading your tutorial linked above! Thanks for it, I’m just fiddling with the LWJGL keyboard stuff there.

Also, how would I go about making a seperate thread for my jframe? I have no experience with threads really.
Here is my main, which pretty much just makes a frame and launches it. I assume I would have to modify this?

public static void main(String[] args) {
       TileGame game = new TileGame();
        game.setPreferredSize(new Dimension(TileGame.WIDTH * TileGame.SCALE, TileGame.HEIGHT * TileGame.SCALE));
        game.setMaximumSize(new Dimension(TileGame.WIDTH * TileGame.SCALE, TileGame.HEIGHT * TileGame.SCALE));
        game.setMinimumSize(new Dimension(TileGame.WIDTH * TileGame.SCALE, TileGame.HEIGHT * TileGame.SCALE));

        JFrame frame = new JFrame("Autumn Cornucopia");
        frame.setSize(TileGame.WIDTH * TileGame.SCALE, TileGame.HEIGHT * TileGame.SCALE);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(game);
        frame.setLocationRelativeTo(null);
        frame.requestFocus();
        frame.toFront();

        frame.setVisible(true);

        //gsm = new GameStateManager();
        //gsm.start();
        game.start();
    }
    

Ok, regarding the initial problem:

Thanks to the tutorial, I figured it out. In the end I ran into a simple semantics problem.
The code above references a “CanMove” method which checks a tile to see if the player can move there, while my collision layer was using the term “DetectCollision”.

It took me a bit to figure out that (CanMove = true) != (DetectCollision = true). One says “yes you can move there”, the other says “yes there is a collision”.

Now I am trying to alter this new movement method so I can have similar movement as before. IE: Press button,ignore input, move player image a few pixels, repeat for X ticks until centered on a tile, allow input again.

Also! I noticed a slight bug in the tutorial code, which was mentioned. Even if the player wasnt moving, it continued to call the CanMove functions a total of 10+ times every tick.