与AnimationTimer和Transition相比有所不同

时间:2017-05-12 03:09:38

标签: java animation javafx

考虑以下代码:

import java.util.ArrayDeque;

import javafx.animation.AnimationTimer;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.util.Duration;

public class FrameTest extends Application
{
    private static final int SUBFRAMES = 1;
    private static final int FRAME_SAMPLE = 10;
    private long prevTime;
    private long frame;
    private ArrayDeque<Long> frameTimes = new ArrayDeque<>();
    private double fps;
    private int subframe;

    public static void main(String[] args)
    {
        Application.launch(args);
    }


    public void frameTick()
    {

        long time = System.nanoTime();
        if (prevTime != -1)
        {
            while (frameTimes.size() > FRAME_SAMPLE - 1)
                frameTimes.remove();
            frameTimes.add(time - prevTime);
            double fps = 0;
            for (long ftime : frameTimes)
                fps += ftime * 1e-9;
            fps = frameTimes.size() / fps;
            this.fps = fps;
            System.out.printf("%.9f\n", fps);
        }
        prevTime = time;

    }



    @Override
    public void start(Stage primaryStage) throws Exception
    {
        Transition trans = new Transition()
        {
            {
                setCycleCount(INDEFINITE);
                setCycleDuration(Duration.ONE);
            }

            @Override
            protected void interpolate(double frac)
            {
                frameTick();
            }
        };

        AnimationTimer timer = new AnimationTimer()
        {

            @Override
            public void handle(long now)
            {
                frameTick();
            }
        };

        //Comment out either one
        trans.play();
        //timer.start();
    }
}

它基本上计算动画计时器的帧速率与转换。

当我使用javafx.animation.Transition运行此FPS计算器时,它会吐出大约600~100000 fps(大范围)。当我使用AnimationTimer进行测试时,它大约在60fps左右。

只是好奇,这两种方法之间的内部区别是什么造成了如此贬低的结果?

1 个答案:

答案 0 :(得分:2)

通过转换,您不会测量实际帧速率;您只是测量interpolate被调用的频率。场景仍将仅以Prism渲染机制限制的速率渲染(默认情况下,其上限为60fps)。

因此,如果您的interpolate方法实际更改了场景图,则并非所有这些更改都会在场景中实现。

相比之下,AnimationTimer的{​​{1}}方法实际上是作为场景渲染的一部分调用的:所以保证每帧只执行一次。