4

私は現在、プレイヤーが異なる部屋の間を移動したり、アイテムを手に取って使用したり、食べ物を食べたりできる、シンプルなコンソールベースのゲームを作成しています。ゲームの現在の状態では、それについてです。

私が助けを必要としているのは:

私のゲームに適した「イベント」クラスを作成します。私がそれを機能させたいのは、すべてのアイテムと部屋をイベントに関連付けることができるようにすることです。

私はこれに慣れていないので、この種の手順に関連する読み物、または以下の点を考慮してクラスを設定するのに最適な方法、または単にこの種を攻撃する方法についての提案をいただければ幸いです。問題の(クラスの設定方法を決定するのに問題がある)

さまざまな種類のイベントを作成できるようにしたいと思います。たとえば、次のようになります。

  • テキストを出力してから、プレーヤーに質問します。プレイヤーが正解した場合は、何かをしてください。

  • テキストを出力し、プレーヤーのインベントリからアイテムを削除してから、プレーヤーを別の部屋に移動します。

私が避けようとしていること:

  • ゲームの全体的なポイントは、優れたクラスデザインを実践することです。したがって、責任駆動設計、凝集度、結合度などが重要な側面です。したがって、私はそれが可能な限り単純で、再利用可能で、独立していることを望んでいます。

  • アイテムまたはルームがEventクラスの特定のメソッドを呼び出すだけになるように、すべてのイベントをハードコーディングする必要があります。

私が今考えていること:

たとえば、次を使用して新しいイベントを作成(および関連付ける)できるように、いくつかのサブクラスを作成します。itemObject.setEvent(new Event(new Question( "introText"、 "outroText"、 "correctAnswer")));

さらに情報が必要な場合はお知らせください。ありがとう!

4

4 に答える 4

2

イベントについて話すとき、オブザーバーパターンが思い浮かびます。あなたのゲームはいくつかのステートマシンによって内部的に提示されていると考えることができます(これはウィキペディアでも調べることができます。SOに慣れていないため、2番目のリンクを自分で追加することはできません)。あるステージから別のステージへの各遷移は、そのイベントの登録済みの監視者に伝達できるイベントです。

例:

USE KEY ON LOCK:キーの取り外しとドアの開放をトリガーします。追加のユーザーインタラクション(ドアの開放)なしで次のイベントに暗黙的に「カスケード」:追加の出口などを持つ部屋をトリガーします。

于 2010-11-23T18:19:57.263 に答える
2

私が検討することの1つは、入力テキストの解析と出力テキストの生成を、基になるドメインモデルから分離することです。あなたの質問は2つを混ぜ合わせているように見えますが、私は問題のテキスト部分をプレゼンテーション層と見なします。

たとえば、ドメインは次のインターフェイスで構成されている可能性があります。

public enum Action { HIT, TALK_TO, EAT, USE };

public interface GameEntity {
  /**
   * Performs the specified action on this GameEntity, passing in zero or
   * more other GameEntity instances as parameters.
   */
  void applyAction(Action action, GameEntity... params);    
}

public interface Item extends GameEntity { }
public interface Person extends GameEntity { }

さらに、入力文字列を処理してドメインレイヤーに対して結果の呼び出しを行う、またはデフォルトの応答「わかりません」を返すTextParserクラスを定義できます。たとえば、「ドアのキーを使用」という入力フレーズは、メソッド呼び出しになります。

key.applyAction(Action.USE, door);
于 2010-11-23T17:59:03.687 に答える
2

ゲームプログラミングの宝石の本は素晴らしいです...少し高価ですが。

GameDevの記事リストでおそらく関連する記事を1つか2つ見つけることができ、おそらく彼らのフォーラムにはいくつかの良いものが埋もれています。

Eventクラスに関しては、ほぼ確実に、いくつかのサブクラス(MoveEvent、InventoryEventなど)を持つ基本クラスが必要です。また、ハードコーディングを本当に避けたい場合は、データファイルでゲームを定義する必要があります。部屋、アイテム、イベント...さらに後で取り組むものすべて。物事を定義するために使用する形式は完全にあなた次第です。これは学習演習であるため、実践的な経験が得られるものをお勧めします。たとえば、使用したことのないXMLパーサーです。解析するのに最も効率的な形式ではありませんが、これはコンソールゲームであるため、そのような問題ではありません。

イベントサブクラスについて私が提案していることの1つは、他のイベントを連鎖させることができる提案です。インターフェースは変更されません。「これをプレイヤーのインベントリに追加し、削除して、ここに移動する」などの操作を実行できます。

于 2010-11-23T18:10:50.733 に答える
1

私は最近、あなたが説明しているものに似たものを実装しました。まず、「Publish」メソッドと「Subscribe」メソッドを持つEventManagerクラスを作成しました。システムが起動すると、ロードされたすべてのアセンブリ(ライブラリ)をスキャンして、IEventListenerインターフェイスを実装するクラスを探します。

/// <summary>
/// A class that intends to listen for specific events to be published by an
/// event manager.
/// <see cref="EventManager"/>
/// </summary>
public interface IEventListener
{
    /// <summary>
    /// Subscribes to the event types that this listener wishes to listen for.
    /// </summary>
    /// <param name="eventManager"></param>
    void RegisterSubscriptions(EventManager eventManager);
}

...そしてそれらのそれぞれでRegisterSubscriptionsメソッドを呼び出します。(どこでも使用されるEventManagerのインスタンスは1つだけです。依存性注入を使用して、シングルトンインスタンスとしてバインドします。)

RegisterSubscriptionsは、指定されたクラスが処理することを目的としたイベントタイプとハンドラーごとにSubscribeメソッドを呼び出すだけです。(私は.NETを使用しているので、イベントとハンドラーの操作は少し簡単ですが、匿名のサブクラスを使用してJavaでも同じことができます。)

典型的なイベントはRoomEnteredのようなものであり、このイベントに関連する引数には、部屋IDと、部屋に関するその他のプロパティが含まれる場合があります。ゲームエンジンは、ユーザーが部屋に入るとこのイベントを公開し、その部屋に適切なイベント引数を提供します。その後、EventManagerクラスは、そのイベントタイプにサブスクライブしている各ハンドラーを呼び出す責任があります。このイベントのハンドラーの1つは、「HandleEnterRoomWithMonsters」である可能性があります。これは、部屋にモンスターがいるかどうかを確認し、それに応じてアクションを実行します。

これは全体的に意味がありますか?このアプローチについて質問がありますか?

于 2010-11-23T18:09:35.413 に答える