2008-09-15 8 views
11

私は約10年間ゲームをプログラミングしていません(私の最後の経験はDJGPP + Allegroでした)が、私は週末にXNAをチェックアウトして、どのように形作っているかを見ていきたいと思っていました。ゲームプログラミングとイベントハンドラ

私はかなり感銘を受けたですが、ゲームエンジンをまとめていくと、おそらく基本的な質問があります。

C#のデリゲートとイベントを使って、ゲームをどの程度動かすべきですか?アプリケーションプログラマとして、私は代理人とイベントを頻繁に使用しますが、これに重大なオーバーヘッドがあるかどうかはわかりません。

私のゲームエンジンでは、オブジェクトにアタッチしてオブジェクトに対する相対位置を再計算することができる、「チェースカム」のソートを設計しました。オブジェクトが動くと、チェイスカムを更新する2つの方法があります。

  • ゲームのメインループに「UpdateCameras()」メソッドがあります。
  • イベントハンドラを使用し、chaseカムにobject.OnMovedをサブスクライブします。

私は後者を使用しています。なぜなら、イベントを一緒に連鎖させ、エンジンの大部分をうまく自動化できるからです。突然、巨大で複雑なものは、一握りの3-5行のイベントハンドラに落ちる...その美しさ。

しかし、1ナノ秒ごとに発生するイベントハンドラが大幅に減速する場合は、それを削除してループアプローチを実行します。

アイデア?

答えて

10

イベントをサブスクライバリストと考えると、コードではサブスクライバを登録するだけです。これを達成するために必要な命令数は、CLRレベルでは最小限に抑えられます。

コードを汎用または動的にする場合は、イベントを呼び出す前に何かが購読されているかどうかを確認する必要があります。 C#と.NETのイベント/デリゲートの仕組みは、(CPUに関して)わずかなコストでこれをあなたに提供します。

クロックサイクルが本当に心配なのであれば、ジェネリック/ダイナミックなゲームロジックを書くことは決してありません。これは保守可能/設定可能なコードと完全な速度との間のトレードオフです。

よく書かれているように、私はそれが問題であることを証明できるまで、イベント/代議員を好むだろう。

あなたが本当に知っている唯一の方法は、あなたのコードをプロファイリングすることです。これはどんなゲーム開発でも必要です。

1

XNAは、インタフェース、イベント、および代理人を使用して、何かを書くことを奨励します。これを設定するGameComponent関連のクラスを見てみましょう。

答えは、 "あなたが快適に感じる程度です"。

たとえば、gamecomponentクラスを受け取り、cameracontrollerクラスに継承してGame.Componentコレクションに追加する場合などです。次に、カメラクラスを作成し、カメラクラスに追加することができます。

これを行うと、定期的にカメラコントローラーが呼び出され、適切なカメラまたは複数のカメラを選択してアクティブにすることができます。あまりにも、私はXNAを学習してきた離れて実際の作業から私の余分な時間で ReoCode

1

:ここ

は(彼のチュートリアルのすべて優れている)その一例です。

私見では(またはしないあなたは私の同僚に言わせればそう謙虚)イベントハンドルのオーバーヘッドは、レンダリングなどのゲーム内の他の要素に圧倒されることです。通常の.Netプログラミングでイベントが頻繁に使用されているとすれば、基盤となるコードは最適化されているはずです。

私がUpdateCamerasメソッドに行くのは時期尚早の最適化だと思います。イベントシステムにはおそらくカメラ以外の用途があります。

4

これは、C#でのイベントは、(例えば、のようなWindowsのメッセージキューを)非同期イベントをキューに登録されていないことを認識することが重要です。基本的には関数ポインタのリストです。したがって、イベントを発生させることは、関数ポインタのリストを反復してそれぞれを呼び出すことよりも、パフォーマンスの悪化を意味するものではありません。

これと同時に、イベントは同期的であることを認識しています。あなたのイベントリスナーが遅い場合、クラスを遅らせると、イベントはになります。

1

さておき、あなたがShawn HargreavesAllegroのオリジナル開発者は、

+0

私はそれに気付きました。その小さな小さな世界。 – FlySwat

2

:-) XNAチームの主要な開発者の一人であるここでの主な質問があると思われることを知って興味があるかもしれませんよう: 「何C#デリゲートとイベントの使用に伴うオーバーヘッドですか?

イベントは、通常の関数呼び出しと比較してほとんどオーバーヘッドがありません。

デリゲートを使用すると、暗黙的な隠しガーベッジが作成される可能性があります。特にXBox360では、ゴミは大きなパフォーマンス上の問題となります。

次のコードは、EntityVisitorオブジェクトの形で(60 fpsで)秒あたりのゴミの2000バイトの周りに生成します。

private delegate void SpacialItemVisitor(ISpacialItem item); 

    protected override void Update(GameTime gameTime) 
    { 
     m_quadTree.Visit(ref explosionCircle, ApplyExplosionEffects); 
    } 

    private void ApplyExplosionEffects(ISpacialItem item) 
    { 
    } 

限り、あなたはゴミの生成を避けるように、代表者は、ほとんどの目的のために十分に高速です。隠された危険性のため、私はそれらを避け、代わりにインターフェースを使用することを好みます。

1

パフォーマンスの面でイベントの影響がどのようなものになる前に、まずそれが必要かどうかを評価する必要があります。

あなたが実際にチェイスカムを更新しようとしていると仮定した場合、あなたが探しているものはイベントではありません(イベントはトリックも同様です)が、アバター尤度それはほとんどの時間動くでしょうか?

私は非常に効果的だとわかったアプローチは、階層的な変換を使用することです。これを効率的に実装すれば、そのようなシステムの恩恵を受ける唯一の目的ではないでしょう。目標は、カメラを座標空間内に保つことです。トラッキングしているオブジェクト

カメラがオブジェクトを追跡する速度と方法に弾力性を適用したい場合、そのアプローチは最善ではありません。そのためには、更新呼び出し、参照、および基本的な加速を使用することをお勧めしますそして抵抗物理学。

イベントは時々発生するイベントや、キャラクターが死んでいるようなアプリケーションのさまざまな側面に影響を与えるイベントにとって、より便利です。おそらく、多くの異なるシステムがそのようなイベントを認識し、このような場合には、常に起こっているかどうかを常に確認しなければならないすべてのオブジェクトを追跡することは、イベントを投げて、それが起こったときにのみすべての関心のあるオブジェクトに通知することよりはるかに効果的ではありません。

+1

新しいネクロマンサーが近所に来ました... – Blau

関連する問題