17

私は単純なゲームを書いています。ループが CPU を消費することなく、フレームレートを 60 fps に制限したいと考えています。どうすればいいですか?

4

10 に答える 10

31

ゲーム ループの記事を読むことができます。何かを実装しようとする前に、まずゲーム ループのさまざまな方法論を理解することが非常に重要です。

于 2009-04-21T06:05:28.100 に答える
12

@cherouvimが投稿したゲームループの記事を取り上げ、「ベスト」戦略を採用して、Java Runnable用に書き直そうとしましたが、うまく機能しているようです。

double interpolation = 0;
final int TICKS_PER_SECOND = 25;
final int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
final int MAX_FRAMESKIP = 5;

@Override
public void run() {
    double next_game_tick = System.currentTimeMillis();
    int loops;

    while (true) {
        loops = 0;
        while (System.currentTimeMillis() > next_game_tick
                && loops < MAX_FRAMESKIP) {

            update_game();

            next_game_tick += SKIP_TICKS;
            loops++;
        }

        interpolation = (System.currentTimeMillis() + SKIP_TICKS - next_game_tick
                / (double) SKIP_TICKS);
        display_game(interpolation);
    }
}
于 2013-01-20T03:42:58.270 に答える
5

簡単な答えは、17 ミリ秒ごとに起動するように java.util.Timer を設定し、タイマー イベントで作業を行うことです。

于 2009-04-21T06:59:58.187 に答える
4

これが私がC++で行った方法です...あなたはそれを適応させることができると確信しています。

void capFrameRate(double fps) {
    static double start = 0, diff, wait;
    wait = 1 / fps;
    diff = glfwGetTime() - start;
    if (diff < wait) {
        glfwSleep(wait - diff);
    }
    start = glfwGetTime();
}

capFrameRate(60)ループごとに 1 回呼び出すだけです。スリープするので、貴重なサイクルを無駄にしません。glfwGetTime()プログラムが開始されてからの時間を秒単位で返します...Javaのどこかに同等のものがあると確信しています。

于 2009-04-21T07:20:18.327 に答える
2

Java で FPS を制御するためのタイマーが不正確です。中古で見つけました。独自のタイマーを実装するか、制限付きでリアルタイム FPS を実行する必要があります。ただし、Timer は 100% 正確ではないため、タスクを適切に実行できないため、使用しないでください。

于 2011-04-19T03:37:39.487 に答える
0

System.currentTimeMillis()Javaでは、時間をミリ秒単位で取得するために、の代わりに行うことができますglfwGetTime()

Thread.sleep(time in milliseconds)わからない場合に備えてスレッドを待機させます。スレッドはtryブロック内にある必要があります。

于 2009-11-04T01:36:36.450 に答える
0

私が行ったことは、ループを継続し、最後にアニメーションを実行したときを追跡することです。少なくとも 17 ミリ秒経過している場合は、アニメーション シーケンスを実行します。

このようにして、ユーザー入力を確認し、必要に応じて音符のオン/オフを切り替えることができました。

しかし、これは子供たちに音楽を教えるためのプログラムであり、私のアプリケーションはフルスクリーンであるという点でコンピューターを占有していたため、他のアプリケーションではうまく再生できませんでした。

于 2009-11-04T01:46:11.827 に答える
0

Java Swing を使用している場合、60 fps を達成する最も簡単な方法は、次のように javax.swing.Timer を設定することであり、ゲームを作成する一般的な方法です。

public static int DELAY = 1000/60;

Timer timer = new Timer(DELAY,new ActionListener() {
    public void actionPerformed(ActionEvent event) 
    {
      updateModel();
      repaintScreen();
    }
});

コードのどこかで、このタイマーを繰り返して開始するように設定する必要があります。

timer.setRepeats(true);
timer.start();

1 秒には 1000 ミリ秒があり、これを fps (60) で割り、この遅延 (1000/60 = 16 ミリ秒の切り捨て) でタイマーを設定することにより、ある程度固定されたフレームレートが得られます。これは、上記の updateModel() および repaintScreen() 呼び出しで行う内容に大きく依存するためです。

より予測可能な結果を​​得るには、タイマーで 2 つの呼び出しの時間を計り、60 fps を維持するために 16 ミリ秒以内に終了するようにしてください。メモリのスマートな事前割り当て、オブジェクトの再利用などにより、ガベージ コレクターの影響も軽減できます。しかし、それは別の質問です。

于 2010-08-31T07:06:11.550 に答える