在我的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;
}
答案 0 :(得分:0)
你真的需要一个新的变量。您的snakeDirection
是您希望在下一个时间步中使用的方向,并将其与newDirection
进行比较,只有在使用时才有帮助。完成一个步骤后,您需要设置lastUsedDirection
。
您可以directionCode
替换ordinal()
。
您应该只启动一个线程,并让它在running=false
时跳过该操作。使用构造函数允许使用deamon=true
启动它,这样您就可以在不首先终止游戏的情况下终止游戏。不要让它终止。当您按SPACE多次足够快时,当前代码可能会运行多个线程。
小心你在多个线程中使用的变量。只要一个线程只读取变量而另一个只写入它,它就足以使用volatile
。你甚至可能不这样做,然后它可能发生一个线程永远不会看到另一个线程所做的写入(这不是理论;这确实发生了,可能不是你的情况)。
答案 1 :(得分:0)
只需检查头部的x
和y
位置以及“颈部”。
我的意思是:
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;
}
body
是std::vector
,其中包含所有蛇段,direction
是Snake
类变量。