Java 2Dゲームプログラミング:ゲームループを作るためのさまざまなアプローチ


10

私はJavaゲームプログラミングに不慣れですが、ゲームループを作成するためのいくつかの異なるアプローチを見てきたので、読むほど、混乱します。1. Timerクラスを使用する標準的なアプローチ(少ないようです)正確)。2. System.nanoTimeを使用するより正確なアプローチ。3. scheduleAtFixedRateを使用する単純なアプローチ。

一般的にどちらを優先する必要があり、各アプローチの利点と欠点はどこにありますか?事前に情報をありがとうございました。

回答:


7

基本的なゲームループの場合、whileループを実行します。このループ内で、nanoTime()を使用して時間を取得し、最後のフレームから経過した時間を判断して、ゲーム状態を更新してレンダリングします。

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29を使用すると、経過時間をポーリングできます。基本的に...

public static void main(String [ ] args)
{
    long current_frame_time = system.nanoTime();
    long last_frame_time = current_frame_time;

    while(gameIsRunning)
    {
        last_frame_time = current_frame_time;
        current_frame_time = system.nanoTime();

        long timeTaken = current_frame_time - last_frame_time;

        //update and render game here
    }
}

この基本的な方法は、たとえばhttp://www.koonsolo.com/news/dewitters-gameloop/http://gafferongames.com/game-physics/fix-your-timestep/で改善できます

または、タイマーを作成し、このタイマーを設定して、更新を実行し、Xミリ秒ごとにレンダリングすることもできます。しかし、そのようなゲームループを構築することにはいくつかの欠点があります。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.htmlによれば、「各Timerオブジェクトに対応するのは、すべてのタイマーの実行に使用される単一のバックグラウンドスレッドです。タスクを順番に実行します。タイマータスクはすばやく完了する必要があります。タイマータスクが完了するまでに時間がかかる場合は、タイマーのタスク実行スレッドを「占有」します。これにより、後続のタスクの実行が遅延し、「束になる」ことがあります。怒らタスクが最終的に完了したとき(および場合)を矢継ぎ早に実行されます。

よるとhttp://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util.Date,%20long%29: " 固定レート実行では、各実行は最初の実行のスケジュールされた実行時間を基準にしてスケジュールされます。実行が何らかの理由(ガベージコレクションや他のバックグラウンドアクティビティなど)で遅延した場合、2つ以上の実行が連続して発生します「追いつく。」に長い目で見れば、実行の頻度は、(はObject.waitを(長い)正確な基礎となるシステムクロックを想定)指定された期間のちょうど逆数のだろう。

通常、ゲームループにかかる時間は事前にわからないため、Xミリ秒ごとに(ターゲットフレームレートに応じて)ゲームループを実行するようにタイマーを設定すると、いくつかのフレームがまとまり、フレームがフレームがスケジュールされたときではなく終了しました。それが起こるとき...なぜそもそもタイマーを使うのですか?

誤解しないでください。タイマーは悪いクラスではありませんが、通常、定期的または特定の時間に実行する必要がある小さなタスクに適しています。たとえば、メールクライアントは5ごとに新着メールをチェックする場合があります。分、またはカウンターは、レースの開始前にカウントダウンを表示するために毎秒減少する場合があります。


問題はゲームループに関するものだったので、awt / swing情報はトピックから外れています。ただし、質問の関連性がなく混乱を招く行があるため、その情報は関連性があると思われたため、削除しました。
ジョッキング

質問に加えられた変更を反映するように回答を調整しました。
Exilyth 2013

7

メインループをタイマーに入れません。むしろ、すべてのフレームを処理する「while」ループを作成し、何らかのタイムキーピング機能(JavaではSystem.nanoTimeのように聞こえる)を使用して、最後のフレーム/最後の反復から経過した時間を計算しますループ。

特定の言語(JavaScript、ActionScriptなど)はここでは例外です。これらの言語は、フックする暗黙のメインループがある環境(ブラウザ、Flash Playerなど)内で動作しますが、その例外はJavaには適用されません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.