ゲーム内イベントを管理する最良の方法は?


13

私は、ゲーム内のイベントが時々起こる必要があるゲームに取り組んでいます。良い例はチュートリアルです。ゲームを開始すると、ゲームのいくつかのポイントでイベントが発生します。

  • 最初の敵に遭遇すると、ゲームは一時停止し、殺す方法についての説明を受け取ります。
  • あなたは最初の敵を殺した、あなたは「良い仕事」メッセージを受け取ります。
  • 新しいアイテム、アイテムの統計ポップアップ付きのメニューを取得します。
  • などなど

私が取り組んでいるゲームは、ゲームのルールがほとんど同じパズルゲームです。したがって、これらのすべてのイベントを別々のレベルでハードコーディングするのは非効率的です。

XMLなどの外部ソースでこれらのイベントを何らかの方法で定義する必要がありますか?次に、XMLを読み取り、レベルのイベント要件を設定するインタープリターを作成しますか?たとえば、2人の敵を殺したときに発生するイベントをどのように定義できるかわかりません。

明確にするために、私はこれを行うのに最適なプログラミング言語またはスクリプト言語を探しているのではなく、これを処理する最適な方法を探しています。

ありがとう!


編集: 私の質問が理解するのはかなり難しかったので、2番目の例:

私が抱えている問題は、ゲーム内のいくつかの追加アクションを常にほぼ同じ手順で実行することです。RPGの戦いのように、誰もがターンを持ち、スキルを選択します-それは常に同じです。しかし、中間にカットシーンを表示したい場合はどうでしょう。カットシーンを含めて、変更されたバトルクラスに渡すためにゲーム構造全体を変更することは、非常に効率が悪いようです。私はこれが通常どのように行われるのだろうと思っています。


8
物事を過度に一般化しようとしないでください。たとえば、チュートリアルは非常に具体的で、さまざまなトリガー/イベントが付属しています。ハードコーディング/スクリプティングに問題はありません。
マイクセンダー

1
@Maik回答IDにそれを+1すると、シンプルで解決された方が、かなり良い日よりも優れています。
ジェームズ

2番目の例では、抽象的なメッセージングシステムが大きな勝利になることを明確にしています。チュートリアルでは、開始時に一度だけ発生するため、ハードコーディングすることができますが、ゲームの全期間中いつでも発生する可能性のある進行中のイベントについては、まったく異なります。
11

まだ少し曖昧です。3つの異なるカットシーンに対して少なくとも3つのトリガーをリストしてください。一般的に答えるのは非常に難しい。基本的に、最適な実装方法を理解するには、共通のパターンを見つける必要があります。
マイクセンダー

なんでしょう?アクションを一時停止して余分な操作を行い、アクションの一時停止を解除しますか?
user712092

回答:


7

これは、ゲーム内のオブジェクト間でイベントが実際に通信される方法に大きく依存します。たとえば、中央メッセージングシステムを使用している場合、特定のメッセージをリッスンし、特定のメッセージを聞くたびにチュートリアルポップアップを作成するチュートリアルモジュールを使用できます。次に、リスニングするメッセージと表示するポップアップを、XMLファイルまたはチュートリアルモジュールで解析されるものに設定できます。ゲームの状態を監視し、ゲームの内容に気付いたときにチュートリアルのポップアップを表示する個別のチュートリアルオブジェクトを用意することで、ゲームについて他に何も変更することなく、チュートリアルオブジェクトを自由に変更できます。(これはObserverパターンですか?すべてのデザインパターンに精通しているわけではありません。)

全体的には、これについて心配する価値があるかどうかは、チュートリアルの複雑さに依存します。コードやレベルにイベントをハードコーディングすることは、ほんの一握りのチュートリアルポップアップにとっては大したことではないように思えます。すべてのトリガーを実行する必要があるのは、TutorialModule.show( "1st_kill")のようなチュートリアルモジュールにメッセージをディスパッチするだけなので、正確に何を念頭に置いて、それが非効率的であると思うかを知りたいのです。


パズルゲームなので、彼のロジックは複数のレベルなどで1つの場所にあるため、このチュートリアルを行う必要があるかどうかを確認することは、すべてのレベルに及ぶものだと思います。正直なところ、パズルゲームの場合、たとえ最もきれいなコードでなくても、これが大ヒットすることはないと思います。日の光をまったく見ないきれいなコードよりも100%優れています;)
ジェームズ

オブザーバーパターンのようなものを考えたことはありません、良い解決策のように聞こえます。試してみます、ありがとう:)
omgnoseat

7

私が理解している設計上の制約は次のとおりです。

  1. コアのゲームプレイコードはレベルの要件を気にせず、それらを処理するコードに結合するべきではありません。

  2. 同時に、それらの要件を満たす特定のイベント(アイテムの取得、敵の殺害など)がいつ発生するかを知るのは、コアゲームプレイコードです。

  3. 異なるレベルには異なる要件セットがあり、それらはどこかで説明する必要があります。

それらを考えると、私はおそらく次のようなことをするでしょう。まず、ゲームレベルを表すクラスを作成します。レベルが持つ特定の要件のセットをカプセル化します。ゲームイベントが発生したときに呼び出すことができるメソッドがあります。

コアゲームプレイコードに現在のレベルオブジェクトへの参照を与えます。ゲームプレイイベントが発生すると、そのメソッドを呼び出してレベルを通知します:enemyKilleditemPickedUpなど

内部的にLevelは、いくつかのことが必要です。

  • 既に発生したイベントを追跡する状態。このようにして、最初の殺された敵と他の敵、特定のアイテムを最初に拾ったことがわかります。
  • LevelRequirementそのレベルに必要な特定の目標セットを記述するオブジェクトのリスト。

レベルを入力するLevelと、適切なを使用してを作成LevelRequirementし、ゲームプレイコードを設定して、そのレベルを設定します。

ゲームイベントが発生するたびに、ゲームプレイはそれをに渡しLevelます。次に、集計データ(殺された敵の総数、殺されたそのタイプの敵など)を計算し、要件オブジェクトを順に調べて、それぞれに集計データを与えます。要件は、それが満たされているかどうかをテストし、もしそうであれば、結果の動作が適切なものを生成します(チュートリアルテキストなどを表示します)

LevelRequirement 基本的に2つのことが必要です:

  1. 要件が満たされているかどうかを判断するテストの説明。あなたの言語がそれを容易にすれば、これは単なる機能になります。(IEは持っているRequirementTypeようなもので列挙型をFIRST_KILLして、大きなswitchものでは、それぞれの種類を確認する方法を知っています。)
  2. 要件が満たされたときに実行するアクション。

これらの要件のセットがどこで記述されているのかという問題がまだあります。XMLまたは別のテキストファイル形式のようなことを行うことができます。次の場合に便利です:

  1. 非プログラマーはオーサリングレベルになります。
  2. 再コンパイルおよび/または再起動せずに要件を変更できるようにしたい。

どちらも当てはまらない場合は、おそらくコードで直接構築するだけです。シンプルな方が常に優れています。


最初の3つのポイントは、私が現在使用している方法の非常に近い説明であり、印象的です!ええ、私が最も苦労しているのは、要件を説明する場所と、それをゲームに変換する方法です(ほとんどの場合、外部のものになるからです)。詳細な説明をありがとう:)
omgnoseat

5

これらのイベントを作成する方法を知っておく必要があると思ったので、投稿の残りの部分はそれについてです、これらのイベントを保存するだけの場合は、何らかのリレーショナルデータベースを使用するか、テキストで記述し、スクリプト言語を使用します(彼は、君は)。:)

必要なのは、発生したイベントを認識し(1)、これらのイベントが要求するアクションを実行することです(メッセージを出力し、キーを押してください...)(2)。また、これらのイベントを1回だけ発生させたい場合もあります(3)。

基本的に、条件を確認してから、いくつかの動作をスケジュールします。

イベントを認識する方法(1)

  • これらの「最初に遭遇した敵」、「新しいアイテムを獲得しました」などのイベントを認識したい
  • 一般的なパーツが発生した場合、「敵に遭遇した」、「アイテムを獲得した」「特定のパーツを最初に確認する」、「新しいアイテムを獲得した」

イベントとは何ですか

より一般的な見方では、このような各イベントは次のもので構成されます。

  • 前提条件、あなたはそれらをチェックします
  • 前提条件が満たされたときに実行されるアクション(たとえば、「最初の敵を殺した!」、「AボタンとBボタンを押してコンボを作成」、「「Enter」を押して続行」、「キーを入力」を要求)

これらのイベントを保存する方法

一部のデータ構造では:

  • 前提条件のリストがある(高水準言語で記述している場合は文字列またはコード)
  • アクションのリストがあります(ストリングである可能性があり、Quakeエンジンはイベントにストリングを使用します)

リレーショナルデータベースに保存することもできますが、必要ないように見えますが、このゲームを大きくしたい場合は、作成する必要があります。

次に、これらの文字列/ものを解析する必要があります。または、PythonやLUAなどのスクリプト言語、またはLISPなどの言語を使用できます。すべての言語を解析して実行できます。:)

ゲームループでこれらのイベントを使用する方法(2)

次の2つのデータ構造が必要です。

  • イベントのキュー(実行予定のイベントはここに配置されます)
  • アクションのキュー(スケジュールされたアクション、イベントは実行されるアクションを意味します)

アルゴリズム:

  • イベント前提条件のいくつかが満たされていることを認識した場合、イベントキューに入れます
  • (3)次に、必要に応じて、このイベントが1回だけ発生することを確認する必要があります。
  • アクションキューが空の場合)イベントキューイベントがある場合アクションを配置しますアクションキューにイベントキューから削除します
  • アクションがあればアクションキューがあなたはそれによって要求されているものをやって起動します
  • そのようなアクションが行われた場合アクションキューます

これらのアクション自体の作成方法(2)

「更新」機能を持つオブジェクトのリストを作成します。これらは、エンティティ(Quakeエンジン)またはアクター(Unrealエンジン)と呼ばれることもあります。

  1. これらのオブジェクトは、アクションキューでの開始が要求されたときに開始します。
  2. これらのオブジェクトは、他のタイマーなどの他のものに使用できます。Quakeでは、これらのエンティティはゲームロジック全体に使用されます。それについての資料を読むことをお勧めします

アクション「何かを言う」

  1. 画面に何かを印刷する
  2. このメッセージを数秒間表示したい
  3. 「更新」:
    • 変数remove_me_afterを作成し、経過した時間でそれを減らします
    • 変数が0の場合、アクションキューからこのアクションを削除します
    • また、このオブジェクトを削除します(または削除するようにスケジュールします...)

アクション「キーが必要」

  1. それはあなたがそれを作りたい方法に依存しますが、あなたはあなたがメッセージを作ると思います
  2. 「更新」」:
    • 必要なキープレスイベントをチェックするだけです
    • キープレスイベントを保持するためにおそらくいくつかの配列/キューが必要です
    • その後、アクションキューから削除してオブジェクトを削除できます

学習する方法


-1正しい、または彼は単に関数を呼び出す、真剣に、OPは特定の条件が満たされたときにメッセージボックスを望んでいるだけ
Maik Semder

それは非常に良い記事ですが、正確には私が探していたものではありません。欲しいものを説明するのに苦労しました。2番目の説明を追加しました。私が抱えている問題は、ゲーム内でいくつかの追加のアクションを常にほぼ同じ手順で実行することです。RPGの戦いのように、誰もがターンを持ち、スキルなどを選びます-それは常に同じです。しかし、中間にカットシーンを表示したい場合はどうでしょう。ゲーム構造全体を変更して、変更されたバトルクラスを渡すためにcutseneを含め、非常に効率が悪いようです。私はこれが通常どのように行われるのだろうか?
-omgnoseat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.