尝试使用箭头键使形状在一个方向上连续移动

时间:2019-06-07 23:27:47

标签: javafx

我正在尝试制作蛇游戏,我在使用JavaFX方面还很陌生。我遇到的问题是,当我使用switch语句根据箭头键更改方向时,它们的矩形仅在按下键时才会移动。我想要的是矩形,它会一直按所按的方向移动,直到按下另一个键为止。我肯定有一个简单的解决方法,对不起,我还是编码和javaFX的新手。

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Mess extends Application {

    private Stage window;
    private final int WIDTH = 500;
    private final int HEIGHT = 500;

    private Direction snakeDir = Direction.RIGHT;

    private int snake_W = 20;
    private int snake_H = 20;
    private Rectangle snake = new Rectangle(snake_W, snake_H);

    private boolean running;
    private boolean snakeUp = false;
    private boolean snakeRight = true;

    private Timeline timeLine = new Timeline();

    enum Direction {
        LEFT,RIGHT,UP,DOWN,NONE;
    }

    private Parent createContent() {
        Pane root = new Pane();
        root.setPrefSize(WIDTH,HEIGHT);

        snake.setTranslateX((WIDTH / 4) - (snake.getWidth() / 2));
        snake.setTranslateY(HEIGHT / 6);

        KeyFrame keyFrame = new KeyFrame(Duration.millis(16), e -> {
            if(!running) {return;}

            switch(snakeDir) {
                case UP:
                    snake.setTranslateX(snake.getTranslateX());
                    snake.setTranslateY(snake.getTranslateY() - 4);
                    break;
                case DOWN:
                    snake.setTranslateX(snake.getTranslateX());
                    snake.setTranslateY(snake.getTranslateY() + 4);
                    break;
                case LEFT:
                    snake.setTranslateX(snake.getTranslateX() - 4);
                    snake.setTranslateY(snake.getTranslateY());
                    break;
                case RIGHT:
                    snake.setTranslateX(snake.getTranslateX() + 4);
                    snake.setTranslateY(snake.getTranslateY());
                    break;
            }

        });

        timeLine.getKeyFrames().add(keyFrame);
        timeLine.setCycleCount(Animation.INDEFINITE);

        root.getChildren().addAll(snake);

        return root;
    }

    private void startGame() {
        running = true;
        timeLine.play();
    }

    private void stopGame() {
        timeLine.stop();
        running = false;
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        window = primaryStage;

        Scene mainScene = new Scene(createContent(),WIDTH,HEIGHT);

        mainScene.setOnKeyPressed(e -> {
            switch(e.getCode()) {
                case UP:
                    snakeDir = Direction.UP;
                    break;
                case DOWN:
                    snakeDir = Direction.DOWN;
                    break;
                case LEFT:
                    snakeDir = Direction.LEFT;
                    break;
                case RIGHT:
                    snakeDir = Direction.RIGHT;
                    break;
            }
        });

        mainScene.setOnKeyReleased(e -> {
           switch(e.getCode()) {
               case UP:
               case DOWN:
               case LEFT:
               case RIGHT:
                   snakeDir = Direction.NONE;
                   break;
           }
        });

        window.setTitle("Snake");
        window.setScene(mainScene);
        window.show();
        startGame();
    }
}

我希望矩形在按箭头键的方向上连续移动。实际结果是,当按下一个键时,它会移动一次并停止。

1 个答案:

答案 0 :(得分:2)

以下是我整理的一些代码,可以帮助您入门。按下按钮以启动Timeline。按左右箭头键移动圆圈。 Timeline每16毫秒循环一次。接近60 FPS。对于这样的游戏,我将更改其值使其达到40 FPS。 Here是宝贵的资源。 Here是另一个。

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 *
 * @author guest_account
 */
public class JavaFXApplication1 extends Application {
    String input = "";

    @Override
    public void start(Stage primaryStage) {
        Circle circle = new Circle(700 / 2, 700 / 2, 15, Color.BLUE);      

        Timeline timeline = new Timeline(new KeyFrame(Duration.millis(16), (ActionEvent event) -> {
            if(input.equals(KeyCode.RIGHT.toString()))
            {
                circle.setCenterX(circle.getCenterX() + 10);
            }
            if(input.equals(KeyCode.LEFT.toString()))
            {
                circle.setCenterX(circle.getCenterX() - 10);
            }
            if(input.equals(KeyCode.UP.toString()))
            {
                circle.setCenterY(circle.getCenterY() - 10);
            }
            if(input.equals(KeyCode.DOWN.toString()))
            {
                circle.setCenterY(circle.getCenterY() + 10);
            }
        }));
        timeline.setCycleCount(Timeline.INDEFINITE);


        Button btn = new Button();
        btn.setText("Play");
        btn.setOnAction((ActionEvent event) -> {
            timeline.play();
            btn.setDisable(true);
        });

        Pane boardRoot = new Pane(circle);
        VBox.setVgrow(boardRoot, Priority.ALWAYS);

        VBox root = new VBox(boardRoot, btn);

        Scene scene = new Scene(root, 700, 700);
        scene.setOnKeyPressed(keyEvent ->{          
            input = keyEvent.getCode().toString();
        });


        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

在6/8/2019评论后更新代码