如何在JavaFx中将游戏的UI与gameloop连接起来
我是初学者。我正在使用JavaFx制作一个简单的2D游戏。我有基本游戏循环的代码。现在我想做一个完整的游戏,在那里我可以打开一个有新游戏,设置等选项的开始窗口。。。另外,我想添加不同的水平和游戏分数和游戏的信息。。。我该怎么做?我可以制作简单的UI窗口。但是我在使用它开始和结束游戏时遇到了问题。我完全搞砸了。。。现在需要帮助:( 我的代码:如何在JavaFx中将游戏的UI与gameloop连接起来,javafx,Javafx,我是初学者。我正在使用JavaFx制作一个简单的2D游戏。我有基本游戏循环的代码。现在我想做一个完整的游戏,在那里我可以打开一个有新游戏,设置等选项的开始窗口。。。另外,我想添加不同的水平和游戏分数和游戏的信息。。。我该怎么做?我可以制作简单的UI窗口。但是我在使用它开始和结束游戏时遇到了问题。我完全搞砸了。。。现在需要帮助:( 我的代码: import java.util.Arrays; import java.util.Collections; import java.util.List;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.input.*;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class ColorRun extends Application {
private static final double KEYBOARD_MOVEMENT_DELTA = 5;
private static final double RECT_WIDTH = 200;
private static final double RECT_HEIGHT = 70;
private static final double RECT_MAX_Y = 800;
private static Rectangle createRectangle(double x) {
Rectangle rect = new Rectangle(x, 0, RECT_WIDTH, RECT_HEIGHT);
rect.setStroke(Color.BLACK);
rect.setArcWidth(10);
rect.setArcHeight(10);
return rect;
}
private final Random random = new Random();
private void randomizeColors(Rectangle[] rects, Circle circle, List<Color>
colors) {
Collections.shuffle(colors, random);
for (int i = 0; i < rects.length; i++) {
rects[i].setFill(colors.get(i));
}
circle.setFill(colors.get(random.nextInt(colors.size())));
}
@Override
public void start(Stage primaryStage) {
List<Color> colors = Arrays.asList(Color.RED, Color.GREEN, Color.BLUE,
Color.YELLOW, Color.GREY);
Circle circle = new Circle(650, 700, 20);
Rectangle[] rectangles = new Rectangle[5];
for (int i = 0; i < rectangles.length; i++) {
rectangles[i] = createRectangle(RECT_WIDTH * i);
}
Pane root = new Pane();
root.setPrefHeight(RECT_MAX_Y);
for (Rectangle rect : rectangles) {
root.getChildren().add(rect);
}
root.getChildren().add(circle);
final double frameDuration = 16;
final double iterationDuration = 4000;
final int framesPerIteration = (int) (iterationDuration / frameDuration + 1);
randomizeColors(rectangles, circle, colors);
Timeline timeline = new Timeline();
class FrameHandler implements EventHandler<ActionEvent> {
KeyCode code;
private int frame = 1;
@Override
public void handle(ActionEvent event) {
if (frame == 0) {
randomizeColors(rectangles, circle, colors); // change colors
when iteration is done
}
// move circle, if key is pressed
if (code != null) {
switch (code) {
case RIGHT:
circle.setCenterX(circle.getCenterX() +
KEYBOARD_MOVEMENT_DELTA);
break;
case LEFT:
circle.setCenterX(circle.getCenterX() -
KEYBOARD_MOVEMENT_DELTA);
break;
}
}
// move rects & check intersection
final Paint color = circle.getFill();
final double cx = circle.getCenterX();
final double cy = circle.getCenterY();
final double r2 = circle.getRadius() * circle.getRadius();
boolean lost = false;
for (Rectangle rect : rectangles) {
rect.setY(frame * RECT_MAX_Y / framesPerIteration);
// check for intersections with rects of wrong color
if (rect.getFill() != color) {
double dy = Math.min(Math.abs(rect.getY() - cy),
Math.abs(rect.getY() + rect.getHeight() - cy));
dy = dy * dy;
if (dy > r2) {
continue; // y-distance too great for intersection
}
if (cx >= rect.getX() && cx <= rect.getX() + rect.getWidth())
{
lost = true;
} else {
double dx = Math.min(Math.abs(rect.getX() - cx),
Math.abs(rect.getX() + rect.getWidth() - cx));
if (dx * dx + dy <= r2) {
lost = true;
}
}
}
}
frame = (frame + 1) % framesPerIteration;
if (lost) {
timeline.stop();
}
}
}
FrameHandler frameHandler = new FrameHandler();
Scene scene = new Scene(root);
// keep track of the state of the arrow keys
scene.setOnKeyPressed(evt -> {
KeyCode code = evt.getCode();
switch (code) {
case RIGHT:
case LEFT:
frameHandler.code = code;
break;
}
});
scene.setOnKeyReleased(evt -> {
KeyCode code = evt.getCode();
if (frameHandler.code == code) {
frameHandler.code = null;
}
});
primaryStage.setScene(scene);
timeline.getKeyFrames()
.add(new KeyFrame(Duration.millis(frameDuration), frameHandler));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入java.util.array;
导入java.util.Collections;
导入java.util.List;
导入java.util.Random;
导入javafx.animation.AnimationTimer;
导入javafx.animation.KeyFrame;
导入javafx.animation.KeyValue;
导入javafx.animation.Timeline;
导入javafx.animation.TranslateTransition;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.*;
导入javafx.scene.control.Label;
导入javafx.scene.input.*;
导入javafx.scene.control.Button;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.scene.paint.paint;
导入javafx.scene.shape.Circle;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
导入javafx.util.Duration;
公共类ColorRun扩展了应用程序{
专用静态最终双键盘_移动_DELTA=5;
专用静态最终双矩形宽度=200;
专用静态最终双矩形高度=70;
专用静态最终双矩形最大Y=800;
专用静态矩形createRectangle(双x){
矩形矩形=新矩形(x,0,矩形宽度,矩形高度);
直接设定行程(颜色为黑色);
矩形设置弧宽(10);
直视下斜视(10);
返回矩形;
}
私有最终随机=新随机();
私有void randomizeColor(矩形[]矩形、圆形、列表
颜色){
集合。洗牌(颜色,随机);
for(int i=0;ir2){
继续;//y距离对于交叉点太大
}
如果(cx>=rect.getX()&&cx{
KeyCode code=evt.getCode();
if(frameHandler.code==代码){
frameHandler.code=null;
}
});
初级阶段。场景(场景);
timeline.getKeyFrames()
.add(新关键帧(Duration.millis(frameDuration),frameHandler));
timeline.setCycleCount(timeline.unfinite);
timeline.play();
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
因此,我测试了该应用程序(对于初学者应用程序来说非常酷),我想我会设置一些按钮来帮助您入门。您应该查看一些关于更高级游戏的教程,我会注意它们的用法(在教程中)设置他们的主屏幕等等,你的问题很难回答,但我不想让你气馁,停止编码。当你遇到堆栈溢出时,试着提出一个确切的问题,说明出了什么问题,除了我不能启动和关闭游戏,试着解决你自己的谷歌代码exa的一些问题看看其他人做了什么,他们是如何解决的,或者教程是如何解决的。也看看谷歌上关于入门游戏应用的一些东西,你很快就会意识到,这可以构造得更好。我不想让这些按钮看起来很好,但只想实现好运和快乐编码的功能
PS我的评论在我添加的内容中
private static final double KEYBOARD_MOVEMENT_DELTA = 5;
private static final double RECT_WIDTH = 200;
private static final double RECT_HEIGHT = 70;
private static final double RECT_MAX_Y = 800;
private static Rectangle createRectangle(double x) {
Rectangle rect = new Rectangle(x, 0, RECT_WIDTH, RECT_HEIGHT);
rect.setStroke(Color.BLACK);
rect.setArcWidth(10);
rect.setArcHeight(10);
return rect;
}
private final Random random = new Random();
private void randomizeColors(Rectangle[] rects, Circle circle, List<Color> colors) {
Collections.shuffle(colors, random);
for (int i = 0; i < rects.length; i++) {
rects[i].setFill(colors.get(i));
}
circle.setFill(colors.get(random.nextInt(colors.size())));
}
@Override
public void start(Stage primaryStage) {
List<Color> colors = Arrays.asList(Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.GREY);
Circle circle = new Circle(650, 700, 20);
Rectangle[] rectangles = new Rectangle[5];
for (int i = 0; i < rectangles.length; i++) {
rectangles[i] = createRectangle(RECT_WIDTH * i);
}
Pane root = new Pane();
root.setPrefHeight(RECT_MAX_Y);
for (Rectangle rect : rectangles) {
root.getChildren().add(rect);
}
root.getChildren().add(circle);
//Here is where I added 2 buttons
//Added Restart Button
Button restartButton = new Button("Restart");
restartButton.setVisible(false); //set to false so you cannot see them when playing
//Added Quit button
Button quitButton = new Button("Quit");
quitButton.setVisible(false);
restartButton.setLayoutY(30);
final double frameDuration = 16;
final double iterationDuration = 4000;
final int framesPerIteration = (int) (iterationDuration / frameDuration + 1);
randomizeColors(rectangles, circle, colors);
Timeline timeline = new Timeline();
class FrameHandler implements EventHandler<ActionEvent> {
private KeyCode code;
private int frame = 1;
public boolean lost = false;
//Here I created a lost action which will run when you lose
private void lostAction(){
timeline.stop();
restartButton.setVisible(true);
quitButton.setVisible(true);
}
@Override
public void handle(ActionEvent event) {
if (frame == 0) {
randomizeColors(rectangles, circle, colors); // change colors when iteration is done
}
// move circle, if key is pressed
if (code != null) {
switch (code) {
case RIGHT:
circle.setCenterX(circle.getCenterX() +
KEYBOARD_MOVEMENT_DELTA);
break;
case LEFT:
circle.setCenterX(circle.getCenterX() -
KEYBOARD_MOVEMENT_DELTA);
break;
}
}
// move rects & check intersection
final Paint color = circle.getFill();
final double cx = circle.getCenterX();
final double cy = circle.getCenterY();
final double r2 = circle.getRadius() * circle.getRadius();
for (Rectangle rect : rectangles) {
rect.setY(frame * RECT_MAX_Y / framesPerIteration);
// check for intersections with rects of wrong color
if (rect.getFill() != color) {
double dy = Math.min(Math.abs(rect.getY() - cy),
Math.abs(rect.getY() + rect.getHeight() - cy));
dy = dy * dy;
if (dy > r2) {
continue; // y-distance too great for intersection
}
if (cx >= rect.getX() && cx <= rect.getX() + rect.getWidth())
{
lost = true;
} else {
double dx = Math.min(Math.abs(rect.getX() - cx),
Math.abs(rect.getX() + rect.getWidth() - cx));
if (dx * dx + dy <= r2) {
lost = true;
}
}
}
}
frame = (frame + 1) % framesPerIteration;
if (lost) {
lostAction();//This was altered to point at lost function
}
}
}
FrameHandler frameHandler = new FrameHandler();
Scene scene = new Scene(root);// keep track of the state of the arrow keys
scene.setOnKeyPressed(evt -> {
KeyCode code = evt.getCode();
switch (code) {
case RIGHT:
case LEFT:
frameHandler.code = code;
break;
}
});
scene.setOnKeyReleased(evt -> {
KeyCode code = evt.getCode();
if (frameHandler.code == code) {
frameHandler.code = null;
}
});
//Here is where I added the actions of the buttons
//Resets variables in order to keep playing
restartButton.setOnAction(event -> {
frameHandler.lost = !frameHandler.lost;
frameHandler.frame=0;
timeline.play();
restartButton.setVisible(false);
quitButton.setVisible(false);
});
//This will let you leave without it you will play forever
quitButton.setOnAction(event -> {
System.exit(0);
});
root.getChildren().addAll(restartButton, quitButton);
primaryStage.setScene(scene);
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(frameDuration), frameHandler));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
primaryStage.show();
}
专用静态最终双键盘\u移动\u增量=5;
专用静态最终双矩形宽度=200;
专用静态最终双矩形高度=70;
专用静态最终双矩形最大Y=800;
专用静态矩形createRectangle(双x){
矩形rect=新矩形(x,0,rect_W