2016-04-03 129 views
1

我在JPanel中有一个动画,它通过javax.swing.Timer自行更新。这个定时器可以被构造成具有毫秒的延迟,该延迟必须是整数。如果我要每秒更新JPanel 60次,我会将延迟设置为1000/60 =〜16.6666。但是,这种延迟必须是整数,所以我可以选择舍入或舍入。对于16毫秒的延迟,动画将以每秒62.5帧更新。四舍五入达到17毫秒的延迟将产生58.824的帧速率。Java定时器Swing准确地60 fps

我该如何去准备每秒60帧的帧速率?

在此先感谢。

+1

系统定时器通常具有〜15ms的分辨率。所以,你不可能得到你想要的精确分辨率。 –

+1

即使系统定时器不准确,它应该随时间推移平均误差(如果我的逻辑没有错误)并且仍然给出相同的,不希望的帧速率(在上面)。 – olta8

回答

1

我看到两个选项可以帮助你。他们最终以相同的方式达到同样的目的,但代码或多或少是一般的。我还没有找到任何工具可以帮助你,所以它需要一点点工作。

的第一个选择是做这样的事情:

/** 
* Called by the timer when the next iteration is due. Assume that 
* this happens at the right moment. 
*/ 
public void onTimerUpdate() { 
    updateAnimation(); 

    // Compute the next point in time that corresponds to the 
    // frame rate you want. 
    long nextScheduledTimestamp = getNextTimestampInNanos(); 

    long nanos = System.timeNanos(); 
    timer.schedule(task, convertToMillis(nextScheduledTimestamp - nanos)); 
} 

第二个选项是让你得到你的java.util.Timer中的副本: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java

和重写是位毫秒特异性。在其OpenJDK的执行没有什么显示,其分辨率为毫秒的特定,所以你应该能够Object.wait(millis, nanos)更换Object.wait(millis)电话: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait(long,%20int)

有趣的文章,只是为了好玩:https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks

0

它几乎没有那样复杂那!您可以轻松地完成重绘()或任何其他方法,你需要调用正好60倍存在第二个具有一个最大的环

while(true) { 
    repaint(); 
    try { 
     Thread.sleep(1000/60); 
    } catch (InterruptedException e) { 
    } 
} 

我把这个在我的脚本的主要方法,但基本上它是一个无限循环因为true总是等于true,所以它调用repaint,告诉循环为一个框架休眠,然后再次调用repaint。并且1000/60睡眠将导致这个循环被准确地称为每秒60次