Проблема в том, что каждый раз, когда срабатывает KeyFrame
, вы сбрасываете флаг moved
.Это требует, чтобы пользователь инициировал как минимум 2 KEY_PRESSED
события между кадрами, чтобы получить направление изменения.
Предполагая, что вы хотите запретить пользователю изменять направление перед первым кадром, вы должны удалить отрицание вif
условие.(В зависимости от того, чего вы пытаетесь достичь с помощью флага, вам может потребоваться другое исправление).
scene.setOnKeyPressed(event -> {
if (moved) {
switch (event.getCode()) {
case W:
if (direction != Direction.DOWN)
direction = Direction.UP;
break;
case S:
if (direction != Direction.UP)
direction = Direction.DOWN;
break;
case A:
if (direction != Direction.RIGHT)
direction = Direction.LEFT;
break;
case D:
if (direction != Direction.LEFT)
direction = Direction.RIGHT;
break;
default:
break;
}
}
});
Также есть несколько вещей, которые можно улучшить в коде с помощью Map
и добавление свойств к перечислению Direction
.
public enum Direction {
UP(0, -1), RIGHT(1, 0), DOWN(0, 1), LEFT(-1, 0);
private final int dx;
private final int dy;
private Direction(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
/**
* Tests, if 2 directions are parallel (i.e. both either on the x or the y axis).<br>
* Note: Depends on the order of the enum constants
* @param other the direction to compare with
* @return true, if the directions are parallel, false otherwise
*/
public boolean isParallel(Direction other) {
return ((ordinal() - other.ordinal()) & 1) == 0;
}
}
В KeyFrame
...
double tailX = tail.getTranslateX();
double tailY = tail.getTranslateY();
Node head = snake.get(0);
tail.setTranslateX(head.getTranslateX() + BLOCK_SIZE * direction.dx);
tail.setTranslateY(head.getTranslateY() + BLOCK_SIZE * direction.dy);
moved = true;
...
final Map<KeyCode, Direction> keyMapping = new EnumMap<>(KeyCode.class);
keyMapping.put(KeyCode.W, Direction.UP);
keyMapping.put(KeyCode.S, Direction.DOWN);
keyMapping.put(KeyCode.A, Direction.LEFT);
keyMapping.put(KeyCode.D, Direction.RIGHT);
Scene scene = new Scene(createContent());
scene.setOnKeyPressed(event -> {
if (moved) {
Direction newDirection = keyMapping.get(event.getCode());
if (newDirection != null && !direction.isParallel(newDirection)) {
direction = newDirection;
}
}
});