在Snake中向上移动意味着你只能向左和向右转。如果你向左移动,你只能向上和向下翻转等。目前我有一个问题,如果我当前正在向左移动(例如),然后我按下向上或向下,然后非常快速按下右键,蛇将保持在同一水平并自行撞击(虽然我还没有添加碰撞检测)。我觉得我需要一些缓冲区(比如,如果我按下UP它就不会接受任何输入,直到运动完成,然后我可以按下RIGHT等等。)我几乎是一个新手所以我感谢任何帮助并为我的愚蠢道歉: - )
发生了{p> This。My Snake是SnakeParts的一个ArrayList(具有变量x,y和size的对象),并且通过在前面添加一个新的SnakePart然后在后面删除一个来完成移动。
以下是相关代码(我不认为我应该调用Thread.sleep(),但当时我还不知道其他任何方式):
Board.java:
public void keyPressed(KeyEvent e) {
int keyPressed = e.getKeyCode();
switch (keyPressed) {
case KeyEvent.VK_UP:
controller.setDirection(1); // UP
break;
case KeyEvent.VK_DOWN:
controller.setDirection(2); // DOWN
break;
case KeyEvent.VK_LEFT:
controller.setDirection(3); // LEFT
break;
case KeyEvent.VK_RIGHT:
controller.setDirection(4); // RIGHT
break;
}
}
Controller.java:
public void gameLoop() {
while (!isWon) {
moveSnake();
checkCollision();
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
}
board.repaint();
}
}
public void setDirection(int direction) {
switch (direction) {
case 1: // UP
if (this.direction != 2) // If not going DOWN.
this.direction = direction;
break;
case 2: // DOWN
if (this.direction != 1) // If not going UP.
this.direction = direction;
break;
case 3: // LEFT
if (this.direction != 4) // If not going RIGHT.
this.direction = direction;
break;
case 4: // RIGHT
if (this.direction != 3) // If not going LEFT.
this.direction = direction;
break;
}
}
private void moveSnake() {
switch (direction) { // Add new part in front.
case 1:
snake.add(0, new SnakePart(snake.get(0).getX(), snake.get(0).getY() - (Board.SNAKE_SIZE + 1), Board.SNAKE_SIZE));
break;
case 2:
snake.add(0, new SnakePart(snake.get(0).getX(), snake.get(0).getY() + (Board.SNAKE_SIZE + 1), Board.SNAKE_SIZE));
break;
case 3:
snake.add(0, new SnakePart(snake.get(0).getX() - (Board.SNAKE_SIZE + 1), snake.get(0).getY(), Board.SNAKE_SIZE));
break;
case 4:
snake.add(0, new SnakePart(snake.get(0).getX() + (Board.SNAKE_SIZE + 1), snake.get(0).getY(), Board.SNAKE_SIZE));
break;
}
snake.remove(snake.size() - 1); // Remove last part.
}
SnakePart.java:
public SnakePart(int x, int y, int size) {
this.x = x;
this.y = y;
this.size = size;
}
答案 0 :(得分:4)
向控制器添加一个名为oldDirection的变量。并将其设置为0。
在moveSnake()中添加一行
this.oldDirction = this.direction
在setDirection()中将您的检查更改为
if (this.oldDirection != 3) // If not going LEFT.
也尽量不使用幻数,而是使用枚举
public enum Direction {
Up, Down, Left, Right
}
答案 1 :(得分:1)
您需要一个消息队列。标志不起作用,因为这意味着将忽略新的按键。这是代码:
public Queue<Integer> directions;
public void gameLoop() {
directions=new LinkedList<Integer>();
while (!isWon) {
updateInput();
moveSnake();
checkCollision();
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
}
board.repaint();
}
}
public void setDirection(int dir) {
directions.add(dir);
}
public void updateInput() {
if(directions.isEmpty())
return;
switch (directions.remove()) {
case 1: // UP
if (this.direction != 2) // If not going DOWN.
this.direction = direction;
break;
case 2: // DOWN
if (this.direction != 1) // If not going UP.
this.direction = direction;
break;
case 3: // LEFT
if (this.direction != 4) // If not going RIGHT.
this.direction = direction;
break;
case 4: // RIGHT
if (this.direction != 3) // If not going LEFT.
this.direction = direction;
break;
}
}
private void moveSnake() {
switch (direction) { // Add new part in front.
case 1:
snake.add(0, new SnakePart(snake.get(0).getX(), snake.get(0).getY() - (Board.SNAKE_SIZE + 1), Board.SNAKE_SIZE));
break;
case 2:
snake.add(0, new SnakePart(snake.get(0).getX(), snake.get(0).getY() + (Board.SNAKE_SIZE + 1), Board.SNAKE_SIZE));
break;
case 3:
snake.add(0, new SnakePart(snake.get(0).getX() - (Board.SNAKE_SIZE + 1), snake.get(0).getY(), Board.SNAKE_SIZE));
break;
case 4:
snake.add(0, new SnakePart(snake.get(0).getX() + (Board.SNAKE_SIZE + 1), snake.get(0).getY(), Board.SNAKE_SIZE));
break;
}
snake.remove(snake.size() - 1); // Remove last part.
}
答案 2 :(得分:0)
创建一个整数:
public int keyDelay = 0;
每按一次键,将该整数设置为大于零的值:
keyDelay = 8;
你必须尝试一下才能找到合适的价值,如果它太低,这个修补程序就无法工作,如果它太高你就不能在你改变方向后的一段时间内再次改变方向。
如果值超过零,则每个tick(游戏循环周期)都会递减值:
if (keyDelay > 0)
keyDelay--;
现在进行最后一步,确保只有在keyDelay为零时才能更改方向。一种简单的方法是将整个setDirection方法包装在if语句中:
if (keyDelay == 0) {
// Set direction
}
答案 3 :(得分:0)
有一个标记bool willMoveSoon = false;
在setDirection()
包含willMoveSoon = true;
在keyPressed()
中将您的整个功能包裹在if (!willMoveSoon) { ... }
中 - 这会在您等待移动蛇时忽略按键
在moveSnake()
包含willMoveSoon = false;