入力オブジェクトとゲームオブジェクトの懸念を分離しますか?


20

おそらくすべてのゲームで、開発者は何らかの方法で入力を処理する必要があります。それは、単純なキーボードイベントやマウスイベント、タッチイベント、または加速度計入力などです。この間接的な直接入力は、ゲーム内のオブジェクトに影響を与えます。同じ入力が異なるオブジェクトに影響する場合があります。今、私はこれをモデル化する方法について考えてきました。私がそれを見る方法には、2つの異なるアプローチがあります。

  • ゲームオブジェクト自体に処理させ、イベントをサブスクライブし、独自のメソッドを呼び出します。これには、ゲームオブジェクト自体が、どの入力がどのアクションを引き起こすかを決定できるという利点があります。欠点は、入力コードが「コア」ゲームオブジェクトコードで破損することです。また、ゲームオブジェクトはゲームの残りの状態を認識しないため、入力イベントに基づいて動作しない場合があります。これは正しくないようです。

  • 一般的な入力コントローラーにすべての入力を処理させ、誰がどのイベントを処理するかを決定します。これは懸念をよりよく分離するように見えますが、入力コントローラークラスをゲームオブジェクトに緊密に結合します。誰がどのイベントをどの状態で受信したいかを知る必要があります。これも正しくないようです。

これを処理するためにどのような戦略を使用していますか?

回答:


7

入力イベントをゲームオブジェクトから分離することをお勧めします。これにより、10個のオブジェクトクラスを編集およびデバッグすることなく、入力方法をすばやく変更/アップグレードできます。例は、キーボードのみのコントロールからマウス+キーボードに移行するか、単にキーを再割り当てします。

入力を個々のゲームオブジェクトに密結合するのではなく、ゲームオブジェクトの一意の入力信号ごとに1つのメソッドのみを呼び出し、実行方法を決定させます。

入力コントローラーを使用して、入力状態を追跡します。

Up press event   -> dir = up
Down press event -> dir = down

入力状態が変わるたびに、ゲームオブジェクトを修正する準備ができているかどうかを評価します。

set dir  ->  if gamestate != paused && battlemode == false
             ->  character.changeDir(dir);

必要に応じて、入力コントローラーまたは他のゲームオブジェクトから呼び出すことができるゲームオブジェクトに一般的なメソッドを実装します。

changeDir (dir)
setSpeed (walk/run)

7

MVCアプローチをお勧めします。MVCでは、ゲームオブジェクトはゲームシステムのモデリングを心配するだけでよく、move_leftのような高レベルのインターフェイスを提供します。次に、入力をモデル呼び出しにマッピングすることを心配するコントローラーオブジェクトを用意します。コントロールを簡単に変更できるだけでなく、AIが別のコントローラーであるための優れたインターフェイスを提供します。

2番目のオプションでは、入力コントローラーを2つの部分に分割します。1つは、実際のデバイスタッチ、キーボード、アクセラ、その他の操作を処理し、それらを汎用入力セットにマッピングします。次に、汎用入力をゲーム固有の入力にマップする2番目の部分を用意します。キーボードの上矢印がinput1にマッピングされ、タッチスクリーンの上部に触れるとinput1にもマッピングされるとします。また、入力1をジャンプにマッピングする2番目のピースを作成します。これで、任意のIOデバイスと保存された再生またはAI入力をこの汎用入力システムにマップし、入力1がモデルに何を意味するかをロードする小さなゲーム固有のパーツを持つことができます。


5
このサイトの他の場所では、MVCが一般にゲームに適したパターンではない理由について多くの議論があります。ストーンメタルが説明しているのはMVCですらなく、単なる抽象化です。また、「MVCを使用」は答えではありません。MVCはアーキテクチャのクラス全体の説明であり、関心事を分離する特定の方法(またはそれを行う唯一の方法)ではないためです。

2
MVCは、A)を読むウィキペディアの記事B)動作することが示されているソリューションへのアプローチ方法のバリエーションを提供する必要がありますC)モデルが高レベルのインターフェースを公開する場所での設定方法について言及コントローラーは、低レベルの入力(実際または合成)を高レベルのアクションにマップし、イベントシステムではなくモデルを直接操作します。
ストーンメタル

1

ゲーム(Model)に可能な入力イベントのリストを定義することをお勧めします(共通の基本インターフェイスを持つ列挙型またはオブジェクトとして実装されます)。以下のようなものMovingRightStartedMovingRightStoppedFiredWeapon1Escape、等...

ゲームは、queue入力コード(Controller)が入力イベントで満たすことができるデータ構造(aなど)を定義します。

その後、ゲームはデータ構造をポーリングして入力イベントを取得できます。

このようにして、異なる種類のコントローラーをプラグインしてモデルにフィードすることができます。

  • キーボードのみ
  • キーボード+マウス
  • ジョイスティック
  • タッチスクリーン
  • 人工知能

入力イベントをモデルにプッシュするだけです。


queueこれを保存するデータ型として選択することを除いて、私はあなたの意味を理解していると思う 理由を説明してください。
ロバートマッサ

モデルからの2つの入力イベントポーリングの間に、コントローラーはいくつかのアクションイベントをプッシュした可能性があり、ユーザー入力の順序を維持することが重要です。それが私がFIFOデータ構造を選んだ理由です。実際には、入力が発生した正確な時間を指定する必要がある場合もあります。
Splo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.