2016-04-03 19 views
1

JPanelにjavax.swing.Timerによって更新されるアニメーションがあります。このタイマーは、整数でなければならないミリ秒単位の遅延を持つように構成できます。毎秒JPanelアップデートを60回実行する場合は、遅延を1000/60 =〜16.6666に設定します。しかし、この遅延はintでなければならないので、切り上げまたは切り捨てのオプションがあります。 16ミリ秒の遅延の場合、アニメーションは毎秒62.5フレームで更新されます。最大17ミリ秒の遅延時間で58.824のフレームレートが得られます。Java Timer Swing Exactly 60 fps

フレームレートを正確に60フレーム/秒にするにはどうすればよいですか?

ありがとうございます。

+1

システムタイマーの分解能は通常〜15msです。とにかく、あなたが望む正確な解像度を得ることはまずありません。 –

+1

システムタイマーが不正確であっても、時間がたつにつれてエラーを平均化し(論理が間違っていない場合)、同じ、望ましくないフレームレート(上記)を与えます。 – olta8

答えて

1

私はあなたに役立つ2つのオプションがあります。彼らは最終的に同じように同じことを達成しますが、コードは多かれ少なかれ一般的です。私はあなたのために仕事をしてくれるツールは見つけていないので、ちょっとした作業が必要です。

最初のオプションは、このような何かを行うことです。 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java

とされているビットを書き換える:あなたはjava.util.Timerのコピーを取得するため

/** 
* 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)); 
} 

2番目のオプションはありますミリ秒に固有です。 、 https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait(long,%20int)

興味深い記事を楽しみのためだけに:OpenJDKのでの実装では何もあなたがObject.wait(millis, nanos)Object.wait(millis)呼び出しを置き換えることができるはずですので、その解像度は、ミリ秒特異的であることを示していhttps://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks

0

それはほど複雑ではありませんそれ!私は私のスクリプトの主な方法でこれを呼び出すが、基本的には無限ループです

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

あなたは簡単に(再描画を実現することができます)か、存在し、単一の最大のループで正確に60回秒を呼び出す必要が任意の他の方法trueは常にtrueとなるため、repaintを呼び出し、フレームに対してスリープするようにループに指示してから、再度repaintを呼び出します。そして、1000/60の睡眠は、このループが正確に1秒間に60回呼び出される結果となる。

関連する問題