Java Snake Bug:快速改变方向时会发生

时间:2018-04-28 14:25:33

标签: java

在我的Snake代码中,如果蛇当前正在向左移动,然后我按向上或向下,然后很快按下右键,游戏就结束了。我知道它发生的原因,但我不知道如何解决它。也许我应该为最后一个方向宣布一个新变量,然后将它与新方向进行比较,以确定蛇是否应转向新方向?我不知道如何解决它。有人可以帮我解决问题吗? : - )

以下是相关代码。

//Judge the keyboard input
public void changeDirection(Direction newDirection) {
    if (snakeDirection.compatibleWith(newDirection)) {
        snakeDirection = newDirection;
    }

Direction.java

public enum Direction {

    UP(0),
    RIGHT(1),
    DOWN(2),
    LEFT(3);

    private final int directionCode;

    Direction(int directionCode) {
        this.directionCode = directionCode;
    }

    private int directionCode() {
        return directionCode;
    }

    //
    public boolean compatibleWith(Direction direction) {
        return (this.directionCode() + direction.directionCode()) % 2 == 1;
    }
}

GameController.java

public class GameController implements Runnable, KeyListener {
    private final Grid grid;
    private final GameView gameView;

    boolean running;

    public GameController(Grid grid, GameView gameView) {
        this.grid = grid;
        this.gameView = gameView;
        this.running = true;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();

        switch (keyCode) {
            case KeyEvent.VK_UP:
                grid.changeDirection(Direction.UP);
                break;
            case KeyEvent.VK_DOWN:
                grid.changeDirection(Direction.DOWN);
                break;
            case KeyEvent.VK_LEFT:
                grid.changeDirection(Direction.LEFT);
                break;
            case KeyEvent.VK_RIGHT:
                grid.changeDirection(Direction.RIGHT);
                break;
            case KeyEvent.VK_ENTER:
                if (running == false) {
                    grid.init();
                    running = true;
                    new Thread(this).start();
                }
                break;
            case KeyEvent.VK_SPACE:
                if (running) {
                    running = false;
                } else {
                    running = true;
                    new Thread(this).start();
                }
                break;
            default:
                break;
        }




    }

    // the Thread
    public void run() {

        while (running) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                break;
            }

            // your code here
            if (grid.nextRound()) {
                gameView.draw();
            } else {

                gameView.showGameOverMessage();
                break;
            }


        }

        running = false;

    }

2 个答案:

答案 0 :(得分:0)

你真的需要一个新的变量。您的snakeDirection是您希望在下一个时间步中使用的方向,并将其与newDirection进行比较,只有在使用时才有帮助。完成一个步骤后,您需要设置lastUsedDirection

一些评论

您可以directionCode替换ordinal()

您应该只启动一个线程,并让它在running=false时跳过该操作。使用构造函数允许使用deamon=true启动它,这样您就可以在不首先终止游戏的情况下终止游戏。不要让它终止。当您按SPACE多次足够快时,当前代码可能会运行多个线程。

小心你在多个线程中使用的变量。只要一个线程只读取变量而另一个只写入它,它就足以使用volatile。你甚至可能不这样做,然后它可能发生一个线程永远不会看到另一个线程所做的写入(这不是理论;这确实发生了,可能不是你的情况)。

答案 1 :(得分:0)

只需检查头部的xy位置以及“颈部”。
我的意思是:

  neck
   |
   | xxxx     
   | x      <--- The snake  
  HNxx      
  |           
  |           
 head

如果一个轴上的位置相同,则不应转动 这是一个实际的例子(它是C ++,但Java有类似的语法,所以这应该不是问题)。

void Snake::setDirection(char dir) {
    switch (direction) {
        case Snake::NORTH:
            if (dir == Snake::SOUTH) return;
            if (body.size() > 1 && body[0]->y == body[1]->y) return;
            break;
        case Snake::SOUTH:
            if (dir == Snake::NORTH) return;
            if (body.size() > 1 && body[0]->y == body[1]->y) return;
            break;
        case Snake::EAST:
            if (dir == Snake::WEST) return;
            if (body.size() > 1 && body[0]->x == body[1]->x) return;
            break;
        case Snake::WEST:
            if (dir == Snake::EAST) return;
            if (body.size() > 1 && body[0]->x == body[1]->x) return;
            break;
    }
    direction = dir;
}

bodystd::vector,其中包含所有蛇段,directionSnake类变量。