首页 > 解决方案 > 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()
    }

}

标签: javajavafx

解决方案


我发现您的代码与教程中的代码不同。

if (!moved)
     return;

switch (event.getCode()) {
     .
     .
     .
}
moved = false;

在您的代码中,缺少 if(!moved) 之后的 return 语句。我试图将它添加到我的代码中,然后它对我有用。

希望这可以解决您的问题。干杯马耳他


推荐阅读