【问题标题】:Regulating the number of executions per second using JavaFX使用 JavaFX 调节每秒的执行次数
【发布时间】:2016-02-08 22:35:17
【问题描述】:

所以现在我正在使用 JavaFX 实现康威的生命游戏。简而言之,在我扩展 AnimationTimer 的类中,在 handle() 方法中,它遍历 2D 数组中的每个单元格并更新每个位置,然后使用 2D 数组中的信息绘制到画布上。

这完全没问题,但问题是它运行得太快了。你无法真正看到画布上发生了什么。在窗口上,我有画布以及一些按钮。我添加了一个 Thread.sleep(1000) 来尝试调节每秒生成/帧,但是这样做会导致窗口无法立即检测到按钮按下。当不告诉线程睡眠时,按钮按下是完全响应的。

有人对如何解决这个问题有任何建议吗?

【问题讨论】:

    标签: java canvas javafx frame-rate


    【解决方案1】:

    你可以使用Timeline,这可能更适合这个。将循环计数设置为Animation.INDEFINITE,并添加一个KeyFrame,其中包含您想要的更新之间的延迟,以及您当前的handle 实现作为框架的onFinished

    final Timeline timeline = new Timeline();
    timeline.setCycleCount(Timeline.INDEFINITE);
    timeline.getKeyFrames().add(
            new KeyFrame(
                    Duration.seconds(1), 
                    event -> handle()
            )
    );
    timeline.play();
    

    或者,您可以尝试将KeyFrame 的延迟设为零,并使用时间轴的targetFrameRate,但我个人从未尝试过。

    编辑:另一种选择是在您的AnimationTimer 中保留一个frameSkip 变量:

    private int frameSkip = 0;
    private final int SKIP = 10;
    
    @Override
    public void handle(long now) {
        frameSkip++;
        if (frameSkip <= SKIP) {
            // Do nothing, wait for next frame;
            return;
        }
        // Every SKIP frames, reset frameSkip and do animation
        frameSkip = 0;
    
        // Do animation...
    }
    

    【讨论】:

    • 作为第二个选项的细微变化,请注意AnimationTimer.handle() 的参数是以纳秒为单位的时间戳。因此,您可以跟踪上次更新,并且仅在经过的时间量大于某个阈值时才执行更新。这比计数可能具有不同间隔的帧更准确。它本质上等同于 Timeline 解决方案 - 选择只是风格问题。
    猜你喜欢
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多