java - 如何在 JavaFX 中异步显示从左到右移动的文本?
问题描述
我正在使用 JavaFX 做一个小游戏。我需要显示从“words.txt”读取的文本并从左到右为它们设置动画。我可以做同样的事情,但它们都同时出现。我希望延迟添加它们(例如 Thread.sleep()),但我不知道如何使用 JavaFX 做到这一点。
这是我的GameView.java
:
package views;
import java.util.Random;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import javafx.animation.AnimationTimer;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import models.InfoLabel;
public class GameView {
// Declare final properties as private.
private static final int GAME_WIDTH = 800;
private static final int GAME_HEIGHT = 600;
private static final String BACKGROUND_IMAGE = "/deep_blue.png";
// Main game properties.
private AnchorPane gamePane;
private Scene gameScene;
private Stage gameStage;
private AnimationTimer gameTimer;
private Stage menuStage;
private int angle;
private GridPane gridPane1;
private GridPane gridPane2;
private InfoLabel infoLabel;
private Text text1;
private Text[] texts;
private ArrayList<String> words;
Random positionGenerator;
public GameView() {
intializeStage();
positionGenerator = new Random();
}
private void intializeStage() {
loadWords();
gamePane = new AnchorPane();
gameScene = new Scene(gamePane, GAME_WIDTH, GAME_HEIGHT);
gameStage = new Stage();
gameStage.setScene(gameScene);
}
private void loadWords() {
words = new ArrayList<>();
BufferedReader br;
try {
br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/words.txt"), "UTF-8"));
while (br.ready()) {
words.add(br.readLine());
}
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Collections.shuffle(words);
}
// Helper function to close the menu stage and show up the
// game stage. Here, we need to re-define everything.
public void createGame(Stage menuStage) {
this.menuStage = menuStage;
this.menuStage.hide();
createBackground();
createGame();
createGameLoop();
gameStage.show();
}
private void createGame() {
text1 = new Text("Hello, World");
text1.setFont(Font.font(16));
text1.setFill(Color.WHITE);
setNewElementPosition(text1);
gamePane.getChildren().add(text1);
// This is how I add the text components
texts = new Text[words.size()];
for (int i = 0; i < texts.length; i++) {
texts[i] = new Text(words.get(i));
texts[i].setFont(Font.font(16));
texts[i].setFill(Color.WHITE);
setNewElementPosition(texts[i]);
gamePane.getChildren().add(texts[i]);
}
infoLabel = new InfoLabel("POINTS: 00");
infoLabel.setLayoutX(650);
infoLabel.setLayoutY(20);
gamePane.getChildren().add(infoLabel);
}
private void setNewElementPosition(Text text) {
text.setLayoutX(-positionGenerator.nextInt(1000));
text.setLayoutY(positionGenerator.nextInt(400) + 100);
}
private void createBackground() {
gridPane1 = new GridPane();
gridPane2 = new GridPane();
for (int i = 0; i < 12; i++) {
ImageView backgroundImage1 = new ImageView(BACKGROUND_IMAGE);
ImageView backgroundImage2 = new ImageView(BACKGROUND_IMAGE);
GridPane.setConstraints(backgroundImage1, i / 3, i % 3);
GridPane.setConstraints(backgroundImage2, i / 3, i % 3);
gridPane1.getChildren().add(backgroundImage1);
gridPane2.getChildren().add(backgroundImage2);
}
gridPane2.setLayoutX(-1024);
gamePane.getChildren().addAll(gridPane1, gridPane2);
}
private void moveBackground() {
gridPane1.setLayoutX(gridPane1.getLayoutX() + 1);
gridPane2.setLayoutX(gridPane2.getLayoutX() + 1);
if (gridPane1.getLayoutX() >= 1024) {
gridPane1.setLayoutX(-1024);
}
if (gridPane2.getLayoutX() >= 1024) {
gridPane2.setLayoutX(-1024);
}
}
private void moveGameElement() {
text1.setLayoutX(text1.getLayoutX() + 5);
if (text1.getLayoutX() >= 1024) {
text1.setLayoutX(-1024);
text1.setLayoutY(positionGenerator.nextInt(400));
}
for (int i = 0; i < texts.length; i++) {
texts[i].setLayoutX(texts[i].getLayoutX() + 5);
}
}
private void createGameLoop() {
gameTimer = new AnimationTimer() {
@Override
public void handle(long now) {
moveBackground();
moveGameElement();
}
};
gameTimer.start();
}
}
源代码可以在这里找到:https ://github.com/richardnguyen99/type-racing
我运行它的方式(块代码中的注释)是使用 for 循环并将所有单词映射到 JavaFX 中的文本组件。它的问题是加载时间非常长,并且单词同时出现并且它们相互碰撞。那么有什么办法像我的问题一样吗?另外,如果您可以就您在我的代码库中找到的其他内容给我一些建议并想要更正它,请告诉我。
谢谢!
解决方案
推荐阅读
- c# - 从Service获取数据时,非静态字段需要对象引用
- laravel - 加载资源失败:加载 laravel css 文件时出现 net::ERR_CONTENT_DECODING_FAILED 错误
- mongodb - 将子对象提取到 MongoDB 聚合中的数组中
- javascript - 如何通过按下按钮 [javascript] [Gjs] 从 St.ScrollView 中删除演员并添加其他演员
- javascript - 默认 Rails 5.2.1.1 内容安全策略(CSP)“style-src 'unsafe-inline'”被违反
- postgresql - 多边形搜索中的点太慢
- python - 如何创建包含数字范围的矩阵?
- c++ - 什么时候允许推导 initializer_list?
- python - 我应该如何在这个类的函数之间传递变量?
- php - Cloudflare $_SERVER["HTTP_CF_IPCOUNTRY"] 从未发送