加载 in/displaying FXML 时避免动画中的短暂卡顿

Avoiding short stutter in animation when loading in/displaying FXML

当加载新的 FXML 并设置 BorderPane 的中心时,应用程序的简短 'freeze' 将停止现有动画,无论是来自时间轴还是来自图像视图中的 gif .我正在使用此代码更改 centerView:

 @FXML
    public void handleChangeView(ActionEvent event) {
        Task<Parent> loadTask = new Task<>() {
            @Override
            public Parent call() throws IOException {

                String changeButtonID = ((ToggleButton) event.getSource()).getId();
                Parent newOne = getFxmls().get(changeButtonID);

                if (newOne == null) {
                    FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/" + changeButtonID + ".fxml"));
                    newOne = loader.load();
                    getFxmls().put(changeButtonID, newOne);
                }
                return newOne ;
            }
        };

        loadTask.setOnSucceeded(e -> {
                    getMainUI().setCenter(loadTask.getValue());
        });

        loadTask.setOnFailed(e -> loadTask.getException().printStackTrace());

        Thread thread = new Thread(loadTask);
        thread.start();
    }

虽然这样做可以保持 UI 在加载时保持响应,但当中心舞台首次显示时,会出现明显的滞后。查看 CPU 个人资料:

我不确定延迟是来自初始化函数 运行 还是元素加载。这是程序的 gif,您可以看到可见的延迟:

通过在 VLC 中加载它并逐帧进行,在 30 fps 视频中延迟看起来是 5 或 6 帧,这意味着大约 200 毫秒的延迟,这意味着动画冻结超过 50 毫秒左右初始化方法。 (也许整个加载方法都卡住了动画?)

问题是,在这期间是否可以保持动画流畅?

//********* 编辑 **********//

所以我检查了项目并尽可能多地删除了方法和类,将整个游戏减少到 6 个最小 类。我在按下字符按钮('you' 按钮)时仍有延迟。有了这样一个最小的例子,我就不知道可能出了什么问题。我已将其上传到 google 驱动器,供任何人查看。

https://drive.google.com/open?id=17A-PB2517bPJc8Dek-yp2wGXsjTyTj1d

您的代码 "wrong" 没有任何内容(至少在这个问题上)。

您遇到的问题也与 FXML 的加载无关(非常慢并且您已正确处理 FX-Thread)。

出现口吃的原因如下:

  • 相对 character.fxml
  • 中的大层次结构
  • 很多 CSS(删除 main.css,您会注意到;卡顿稍微不那么突出)
  • 动态改变场景图(运行时 adding/removing 个节点)

每次用某个大节点替换 mainViewcenter 时,都会导致 JavaFx 运行时完全重新布局并(至少)重新设置该节点的样式。这发生在 FX-Thread 上,因此您注意到卡顿。

一种可能的缓解方法是经典的游戏开发技术:尽可能多地预分配。 只需在启动期间加载一次所有必需的 FMXL,然后将它们放入场景图中。然后在您的点击处理程序中,将您想要的节点的可见性或 (Z-) 位置更改为 show/hide。 例如,这是 StackPane 的一个很好的用例。

我稍微调整了您的代码以证明我的意思: Prototype

查看这些资源以了解更多信息: