java - Snake - 按键响应时间慢
问题描述
我做了一个蛇游戏(通过尝试遵循 youtuber 的代码),方向由 WASD 控制。但是,当我按下其中一个键时,什么也没有发生。如果我按住它,它会改变方向,但是会有很大的延迟,可能超过一秒钟。我该如何解决?我查看了我的代码并将其与我多次遵循的 youtube 代码进行了比较,但似乎仍然看不出问题所在。这是我第一次制作游戏,所以我对此很陌生。
这是我尝试关注的视频,如果有帮助的话。
https://www.youtube.com/watch?v=nK6l1uVlunc
package app;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.shape.Rectangle;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage; // Kontrollerer tittel, ikon, synlighet, størrelse, og dekorasjoner
import javafx.util.Duration;
public class App extends Application {
public enum Direction {
UP, DOWN, RIGHT, LEFT;
}
public static final int BLOCK_SIZE = 40;
public static final int APP_W = 20 * BLOCK_SIZE;
public static final int APP_H = 15 * BLOCK_SIZE;
public int score = 0;
public int highScore = 0;
private Direction direction = Direction.RIGHT; // Default spawn-bevegelse: til høyre
private boolean moved = false;
private boolean running = false; // Applikasjonen kjører
private Timeline timeline = new Timeline();
private ObservableList<Node> snake;
private Parent createContent() {
Pane root = new Pane();
root.setPrefSize(APP_W, APP_H);
Group snakeBody = new Group();
snake = snakeBody.getChildren();
Rectangle food = new Rectangle(BLOCK_SIZE, BLOCK_SIZE);
food.setFill(Color.RED);
food.setTranslateX((int)(Math.random() * (APP_W - BLOCK_SIZE)) / BLOCK_SIZE * BLOCK_SIZE);
food.setTranslateY((int)(Math.random() * (APP_H - BLOCK_SIZE)) / BLOCK_SIZE * BLOCK_SIZE);
KeyFrame frame = new KeyFrame(Duration.seconds(0.5), event -> {
if (!running)
return;
boolean toRemove = snake.size() > 1;
Node tail = toRemove ? snake.remove(snake.size()-1) : snake.get(0);
double tailX = tail.getTranslateX();
double tailY = tail.getTranslateY();
switch (direction) {
case UP:
tail.setTranslateX(snake.get(0).getTranslateX());
tail.setTranslateY(snake.get(0).getTranslateY() - BLOCK_SIZE);
break;
case DOWN:
tail.setTranslateX(snake.get(0).getTranslateX());
tail.setTranslateY(snake.get(0).getTranslateY() + BLOCK_SIZE);
break;
case RIGHT:
tail.setTranslateX(snake.get(0).getTranslateX() + BLOCK_SIZE);
tail.setTranslateY(snake.get(0).getTranslateY());
break;
case LEFT:
tail.setTranslateX(snake.get(0).getTranslateX() - BLOCK_SIZE);
tail.setTranslateY(snake.get(0).getTranslateY());
break;
}
moved = true;
if (toRemove)
snake.add(0, tail);
// Kollisjonsdeteksjon
// Krasjer i seg selv
for (Node rect : snake) {
if (rect != tail && tail.getTranslateX() == rect.getTranslateX() && tail.getTranslateY() == rect.getTranslateY()) {
restartGame();
break;
}
}
// Krasjer i kant
if (tail.getTranslateX() < 0 || tail.getTranslateX() >= APP_W || tail.getTranslateY() < 0 || tail.getTranslateY() >= APP_H) {
restartGame();
}
// Legg til mat
if (tail.getTranslateX() == food.getTranslateX() && tail.getTranslateY() == food.getTranslateY()) {
food.setTranslateX((int)(Math.random() * (APP_W - BLOCK_SIZE)) / BLOCK_SIZE * BLOCK_SIZE);
food.setTranslateY((int)(Math.random() * (APP_H - BLOCK_SIZE)) / BLOCK_SIZE * BLOCK_SIZE);
Rectangle rect = new Rectangle(BLOCK_SIZE, BLOCK_SIZE);
rect.setTranslateX(tailX);
rect.setTranslateY(tailY);
snake.add(rect);
}
});
timeline.getKeyFrames().add(frame);
timeline.setCycleCount(Timeline.INDEFINITE);
root.getChildren().addAll(food, snakeBody);
return root;
}
private void restartGame() {
stopGame();
startGame();
}
private void stopGame() {
running = false;
timeline.stop();
snake.clear();
}
private void startGame() {
direction = Direction.RIGHT;
Rectangle head = new Rectangle(BLOCK_SIZE, BLOCK_SIZE);
snake.add(head);
timeline.play();
running = true;
}
@Override
public void start(final Stage primaryStage) throws Exception {
// primaryStage.setTitle("My Application");
// primaryStage.setScene(new Scene(FXMLLoader.load(App.class.getResource("App.fxml"))));
// primaryStage.show();
Scene scene = new Scene(createContent());
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;
}
moved = false;
});
primaryStage.setTitle("Snake");
primaryStage.setScene(scene);
primaryStage.show();
startGame();
}
public static void main(final String[] args) {
App.launch(args); // Kaller init(), start() og så stop()
}
}
解决方案
我发现您的代码与教程中的代码不同。
if (!moved)
return;
switch (event.getCode()) {
.
.
.
}
moved = false;
在您的代码中,缺少 if(!moved) 之后的 return 语句。我试图将它添加到我的代码中,然后它对我有用。
希望这可以解决您的问题。干杯马耳他
推荐阅读
- javascript - 这个灯塔审计有什么问题?我可以从 http://localhost 安装 PWA
- java - 如何获取用户节点内选定用户的用户 ID?
- azure - 如果提供了 DelimitedTextConfiguration,则无法使用查询 Blob 内容 API 查询 Azure Blob 存储
- r - 使用 ggraph 在二分网络中指定节点形状和标签
- javascript - 使用javascript将wmf转换为png
- web-scraping - 如何从 python 请求帖子中获取文本或 json 数据
- node.js - NVM 不能在 ZSH 上工作,但在 Bash 上 - M1 Mac Mini
- matplotlib - 在散点图上绘制水平平均线/平均线
- azure-devops - 如何在 python 脚本中访问秘密变量
- mysql - Xampp localhost/phpmyadmin: (HY000/2006): MySQL 服务器已经消失