1

グッドプラクティスについて質問がありました。私は簡単なゲームを作っています、そして、私はいくつかのスプライトをいじっています。

スプライトクラスがあります。そのクラスには、数ミリ秒ごとに実行されるタイマーがあります。

これでList<Creatures>、「Creatures」の全員がアニメーションを実行するためのSpriteオブジェクトを取得しました。つまり、すべてのクリーチャーが同じことをするタイマーを持っているということです。

それを変更して、リストを反復処理するタイマーを1つ作成し、「クリーチャー」ごとにアニメーションを作成する関数を呼び出すことにしました。

良い習慣は何ですか?

  1. すべての「クリーチャー」に独自のタイマーを与えます。
  2. リストで反復するフォームに1つの「大きな」タイマーを作成し、各オブジェクトからアニメーションを作成している関数を呼び出します。
  3. 別の方法
4

3 に答える 3

5

それらがすべて同じ間隔で実行される場合、1つの大きなタイマーが間違いなく進むべき道です。

それらが異なる間隔で実行されている場合でも、1つの大きなタイマー(どのサブハンドラーが起動するかを決定するロジックを備えた)が依然として最適であることがよくあります。

一部のライブラリはこのロジックを内部的に追加し、OSに単一のタイマーのみを要求します。使用しているタイマー(.NETには少なくとも4つあります)を正確に指定していないので、集中タイマーを自分で使用することをお勧めします。

于 2012-04-10T21:15:48.163 に答える
5

スプライトクラスがあります。そのクラスには、数ミリ秒ごとに実行されるタイマーがあります。

残念ながら、実際にはそうではありません。(高性能ではない)システムクロックの解像度によって制限されます。これは、約15ミリ秒です。したがって、必要に応じて1の間隔を設定できますが、実際にはそれは得られません。

トピックに戻ると、ゲームの場合、すべてが同じクロックで実行される必要があります。ティックごとに、ゲームの論理状態(位置など)を更新し、次に表示(アニメーションフレーム、画面へのブリットなど)を更新するループがあります。オブジェクトを並行して更新しているときにオブジェクトの状態を調整することが非常に困難になるため、異なるタイマーでオブジェクトを使用すると、問題が発生する可能性があります。

また、更新速度を正規化して、更新が速すぎたり遅すぎたりしないようにする必要があることも理解してください(フレームのレンダリングにかかる​​時間によって異なります)。最後の更新と新しい更新の間のデルタを確認し、それに応じて行動する必要があります。

于 2012-04-10T21:16:08.420 に答える
1

最善の策は、最後のループの反復から経過した時間を追跡し、その経過時間を更新する必要のあるすべてのエンティティに渡すゲームループを実装することです。

たとえば、OpenTkは、ゲームループを通過するたびに発生するいくつかのイベント(OnUpdateFrame、OnRenderFrameなど)を実装します。

これらの各イベントには、Timeの単一のプロパティを持つFrameEventArgsタイプの引数が渡されます。

/// <summary>
/// Gets a <see cref="System.Double"/> that indicates how many seconds of time elapsed since the previous event.
/// </summary>
public double Time 
{
    get { return elapsed; }
    internal set
    {
        if (value <= 0)
            throw new ArgumentOutOfRangeException();
        elapsed = value;
    }
}

経過時間に基づいて、スプライトでレンダリングするアニメーションフレームを把握できます。

追加の利点は、この時間が経過したときに、現在実行している1秒あたりのフレーム数を把握し、それに基づいて決定を下すことができることです(フレームのレンダリングをスキップする、レンダリングの複雑さを軽減するなど)。

于 2012-04-10T21:26:07.797 に答える