Javaな日々

NO JAVA, NO LIFE.

フレームレートを固定する

久しぶりにコンピュータ倶楽部に顔を出してみたら学祭で展示するゲーム制作の進度がやばいらしく,ゲームとか作ったことのない自分がJava音ゲーを開発している子のところにヘルプに行った.
音ゲーはフレームレート(fps)を固定しないと譜面がずれて大変なことになるらしい(当たり前).

方法

画面描画をwhileループで回していると,計算量や環境,処理時間の差によってフレームレートが変化する.ここで,処理時間+αの時間毎にループするようにしてループ毎の時間を均一化,つまりフレームレートを固定する.
例えばフレームレートを60fpsで固定するときは

1000[ms] / 60[frame] = 16.666…[ms/frame]

1ループにかかる時間が16.666…msとなるように処理の後にsleepするようにする.

以下,参考サイトで見つけたJavaでの実装例.
ところどころで小数点以下の値による誤差を小さくするためにビット演算(高速なため)が使われている.

long error = 0;  
int fps = 60;  
long idealSleep = (1000 << 16) / fps;  
long oldTime;  
long newTime = System.currentTimeMillis() << 16;  

while (true) {  
    oldTime = newTime;  
    
    // ここに1フレームの処理を書く
      
    newTime = System.currentTimeMillis() << 16;  
    long sleepTime = idealSleep - (newTime - oldTime) - error;
    if (sleepTime < 0x20000) sleepTime = 0x20000;
    oldTime = newTime;
    Thread.sleep(sleepTime >> 16);
    newTime = System.currentTimeMillis() << 16;
    error = newTime - oldTime - sleepTime;
}