0

私はRTSゲームを書いていますが、ユーザーアクションを「コマンド」にカプセル化したいです。コマンドにより、次のことが可能になります。

  • ネットワークを介して他のプレイヤーにユーザーアクションを送信するので、他のプレイヤーが何をしているのかを誰もが知っています
  • 再生機能を有効にするためにユーザーアクションをファイルに記録する
  • 不正行為(の1つの形式)を防ぐために、実行前に各アクションを検証します
  • 分類アクション。たとえば、UIの変更のみを行うアクション(カメラの移動)、ゲームの状態を変更するアクション(ユニットの移動)、マップエディターのみが発行できるアクション(地形の変更)など。

また、最小限のオーバーヘッドを追加する必要があります。このため、リフレクションの使用は避けたいと思います。これまでのところ、私が思いついた最高のものは悪いものです。なぜなら、私は必然的に巨大なswitchステートメントになってしまうからです。

enum CommandType {
    MoveCamera,
    ChangeTerrain
}

// Base class for all commands (public fields used for brevity)
abstract class Command {
    protected Command(CommandType type) {
        Type = type;
    }
    public CommandType Type;
}

class CommandMoveCamera : Command {
    public CommandMoveCamera() : base(CommandType.MoveCamera) {}
    public int DeltaX;
    public int DeltaY;
}

class CommandChangeTerrain : Command {
    public CommandChangeTerrain() : base(CommandType.ChangeTerrain) {}
    public int NewTerrainType;
    public int X;
    public int Y;
}

class Game {
    Queue<Command> m_commands;
    void Update() {
        // Example of adding a command
        m_commands.Enqueue(new CommandMoveCamera { DeltaX = -10, DeltaY = 0 });

        // Processing commands
        while (m_commands.Count > 0) {
            var c = m_commands.Dequeue();
            switch(c.Type) {
            case CommandType.MoveCamera:
                var command = (CommandMoveCamera)c;
                MoveCamera(c.DeltaX, c.DeltaY);
                break;
            case CommandType.ChangeTerrain:
                var command = (CommandChangeTerrain)c;
                ChangeTerrain(c.X, c.Y, c.NewTerrainType);
                break;
            }
        }
    }
}

言語はC#です。私の質問は、要件を満たし、異なるタイプのコマンドごとに分岐するために巨大なswitchステートメントに依存することを回避する方法でこのシステムを実装する方法は何でしょうか?

ありがとうございました。

4

2 に答える 2

0

いくつかのアイデアがあります。On<Event>まず、コマンドの種類ごとにメソッドを公開できます。次に、パラメータのCommandように、抽象メソッドを に追加します。その後、各コマンドの実装は、適切なメソッドを呼び出すことができます(コマンドに関連するその他のロジックを含む)。列挙型はもう必要ありません。ExecuteGameGame

もう 1 つの考え方は多少似ていますが、デリゲートを使用します。コマンドの種類ごとにデリゲートを定義し、コマンドの実装ごとに、このデリゲートを使用するイベントを公開します。次に、Commandabstract に、Execute実装時に適切なイベントを発生させる method を含めることができます。Game各イベントを作成するときは、そのコマンドを処理するメンバーにイベントを委任するだけです。

于 2012-04-08T00:28:59.153 に答える
0

私は少し前にゲームエンジンに対して非常に似たようなことをしました。私は実際にいくつかの異なるバージョンを試しましたが、私が思いついたのはこのようなものでした.

  • すべてのコマンドは Command インターフェースを実装します (これはシリアライズ可能であることを意味します)
  • すべてのコマンドは CommandRegistry に登録する必要があるため、CommandRegistry には各コマンドの一意の ID があります。

次に、ネットワーク経由でコマンドを送信するには、CommandRegistry にコマンドをシリアル化するように依頼します。コマンドをシリアル化し、その ID を追加します。受信側の CommandRegistry は Id を読み取り、適切なタイプの Command を作成してから、残りのデータから自分自身を逆シリアル化するように要求します。

この基本的なセットアップは C++ と Go の両方で行ったので、C# でも問題なく動作するはずです。

于 2012-04-08T00:12:01.057 に答える