在没有循环依赖的情况下提高 JavaFX KeyFrame 速度?

Increase JavaFX KeyFrame speed without cyclic dependency?

我正在尝试使用 JavaFX 创建 Snake 克隆。游戏的要求之一是有一种能量食物,可以增加蛇的速度。

对于我的游戏循环,我使用一个 Timeline 和一个 KeyFrame 作为游戏刻度。每个游戏 object 都渲染到 Canvas.

蛇在 21x21 的网格中移动,每个单元格的长度为 40px。在我的实现中,蛇每次移动一个单元格(按设计)。每个 body 段基本上在当前方向上移动 40px。这意味着蛇的速度由游戏的滴答持续时间决定。

为了增加蛇的速度,我必须更改关键帧的持续时间,这会更新游戏状态并绘制到 canvas。为此,我停止了时间线,删除了关键帧,并添加了一个持续时间较短的新关键帧。

问题是,为了做到这一点,我必须在 Game class 中调用一个方法,其中包含游戏循环,来自它的一个依赖项(例如 State class).

private final Timeline loop = new Timeline();
    public void setGameSpeed(GameSpeed speed) {
        createLoop(speed.value);
    }
    private void createLoop(double duration) {
        if (loop.getStatus().equals(RUNNING)) {
            loop.stop();
        }

        if (loop.getKeyFrames().size() > 0) {
            loop.getKeyFrames().removeAll(loop.getKeyFrames());
        }

        loop.getKeyFrames().add(new KeyFrame(Duration.seconds(duration), e -> {
            state.update();
            renderer.draw();
        }));
        loop.play();
    }

到目前为止我想出了两个解决方案。我可以让时间线和相关方法是静态的,或者将“游戏”的实例传递给相应的依赖项。

有没有更优雅的方法来做到这一点?

一种选择是利用回调将委托方法传递给 State。或者类似地使用观察者模式通知 Game 状态变化导致调用相应的方法。

另一种选择是让 Game 定期阅读 State 的 属性 以了解何时更改游戏速度。这样 State 仍然不知道 Game