我正在尝试制作蛇游戏,我在使用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();
}
}
我希望矩形在按箭头键的方向上连续移动。实际结果是,当按下一个键时,它会移动一次并停止。
答案 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评论后更新代码