【发布时间】:2018-09-24 08:47:14
【问题描述】:
我正在使用 JavaFX 开发游戏,现在我正在尝试创建一个加载屏幕,因为加载资产需要一些时间。我创建了一个显示多个进度条的 LoadingPane 类,我确信它可以工作。但是,在下面的代码中,加载窗格在 loadAssets 函数之后才会可见,即使我事先添加了它。当我运行下面的代码时,我会看到一个空白阶段,显示资产加载所需的时间,然后是一个带有已完成进度条的屏幕。
我找不到任何有类似问题的人,或者任何类型的刷新或更新功能来强制场景在继续程序之前显示加载窗格。
注意:我删除了一些设置键盘输入处理的无关代码。
public class Main extends Application{
Pane root = new Pane();
Scene mainScene = new Scene(root, Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT, Color.BLACK);
static LoadingPane loadingPane = new LoadingPane(3);
private static int loadingIndex = 0;
public static void main(String[] args) {
if(Constants.DEBUG_MODE)
System.out.println("WARNING: Game has launched in debug mode!");
launch(args);
}
public static void updateProgress(double percent){
loadingPane.setBarLength(loadingIndex, percent);
}
public static void loadAssets(){
RoomLoader.createRooms();
updateProgress(1.0);
loadingIndex++;
ProjectileLoader.load("imgs/projectiles/");
ProjectileLoader.load(Constants.BATTLE_IMAGES_FILEPATH);
updateProgress(1.0);
loadingIndex++;
BattleLoader.createBattles();
updateProgress(1.0);
loadingIndex++;
}
public static void updateProgress(double percent){
loadingPane.setBarLength(loadingIndex, percent);
}
@Override
public void start(final Stage primaryStage) {
//root.getChildren().add(new javafx.scene.image.ImageView(new Image("imgs/loading.png")));
root.setLayoutX(0);
primaryStage.setScene(mainScene);
primaryStage.show();
primaryStage.toFront();
primaryStage.setTitle("Branch");
primaryStage.setResizable(false);
//primaryStage.getIcons().add(new Image("core/imgs/soul/red.png"));
//This allows the closing of the primaryStage to end the program
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>(){
@Override
public void handle(WindowEvent t) {
System.exit(0);
}
});
root.resize(Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT);
primaryStage.getIcons().add(new Image("imgs/icon.png"));
//End GUI setup
//The problem lines
root.getChildren().add(loadingPane);
//refresh root?
loadAssets();
}
}
编辑:工作代码 对于遇到类似问题的任何人,以下是我用来使其工作的代码:
我替换了这个:
//The problem lines
root.getChildren().add(loadingPane);
//refresh root?
loadAssets();
有了这个:
root.getChildren().add (loadingPane);
Task<Integer> loadingTask = new Task<Integer>() {
@Override protected Integer call() throws Exception {
loadAssets();
return 1;
}
};
loadingTask.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
@Override
public void handle(WorkerStateEvent t){
loadingPane.setVisible(false);
load(); //note: this function sets up the actual game
//updating the GUI, adding game elements, etc
}
});
new Thread(loadingTask).start();
我不能说这是解决此问题的最佳方法,但我可以说它有效。祝你好运!
【问题讨论】:
-
您需要在单独的线程中运行更新方法。
-
成功了,谢谢!你知道是什么原因造成的吗?
-
嗯。我认为代码的工作方式是[一些代码 -> 调用更新 GUI -> GUI 更新 -> 回到你在代码中的位置]。这不是 FX 的工作原理吗?
-
我添加了一个答案,您可以选择它作为接受的答案。