1

C#でGDI+を使用して簡単なゲームを作成しています。

まず、ゲームループとレンダリングループが必要です。これらを2つの別々のスレッドに分割することにしました。動作しているようで、非常に高速に実行されますが、ここで質問しているのは、ゲームループにタイマーを使用して、特定のフレームレートで実行させるためです。

これには明らかに、アクターの移動速度を確認できるという利点があります。しかし、Unity3DのUpdate関数のように、私のゲームループはできるだけ速く実行されます。アクターが常に同じ速度で移動するようにするには、移動速度にフレームのデルタ時間(各フレーム間の時間)を掛けるだけです。

私のレンダリングループも可能な限り高速に実行されます。これは良いゲームループですか、なぜですか、なぜそうではありませんか?

// Constructor
public FormDisplay()
{
    // Create a thread object, passing in the GameLoop method
    var gameThread = new Thread(this.GameLoop);

    // Start the game thread
    gameThread.Start();

    // Create a thread object, passing in the GameLoop method
    var renderThread = new Thread(this.RenderLoop);

    // Start the render thread
    renderThread.Start();
}

private void GameLoop()
{
    while (true)
    {
        // TODO: Insert Game Logic
    }
}

private void RenderLoop()
{
    while (true)
    {
        // TODO: Insert Render Logic
    }
}
4

2 に答える 2

1

画面のリフレッシュレートを制限要因として考慮する必要があります。画面が1秒間に100回しか更新されない場合、アクターを1秒間に300回移動しても意味がありません。

同様に、モニターのリフレッシュレートが100 Hzしかない場合に、画面を1秒間に300回レンダリングすると、ティアリングが発生する可能性があります。これは、バッファが画面に表示されているときにフレームバッファを更新すると発生します。そのため、アクターの上半分が古い場所に表示され、下半分が新しい場所に表示されます。

ちらつきを減らすことについての良い記事は、スタックオーバーフローの質問です。GDI+とC++でちらつきを減らします

理想的には、一般的なゲームループとして、ゲームスレッドは、次の画面更新のためにレンダリングスレッドに渡すリストを処理および構築する必要があります(つまり、常に次の表示フレームを処理しています)。次に、両方のスレッドが次のフレームを待ちます。もちろん、これは、それがいつ発生するかを知る必要があることを意味します。GDI+を使用したレンダリングを見つけることはできないと思います。

于 2012-11-08T13:48:48.173 に答える
1

ライブラリ自体(または.NET GUI)がスレッドをどのように使用するかを理解せずに、自分のスレッドの管理に直接ジャンプするという考えは、悪い考えのように思われます。

スレッド化が必要になると確信していますが、自分で明示的に管理する必要があるかどうかはわかりません。基盤となるライブラリにそれを処理させ、メインUIスレッドとの間で作業をプッシュします。

于 2012-11-08T13:53:09.857 に答える