1

.NET を使用してビデオゲームを開発していますが、コマンドのキューイングを適切に実装して一度に実行する方法に苦労しています。

私のビデオゲームはシンプルで、動く飛行機です。コマンド パターンの私の実装は次のとおりです。次に、これらのコマンドの管理を Player クラスに実装します。

public abstract class ICommand {
        Category CategoryProperty { get; set; }

        public abstract void Execute();
    }

public class MoveAircraftCommand : ICommand
    {
        private Vector2f _velocity;
        Aircraft aircraft;

        public Category CategoryProperty {
            get {
                return Category.PlayerAircraft;
            }
        }

        public MoveAircraftCommand (float vx, float vy, Aircraft v_aircraft) {
            _velocity = new Vector2f(vx, vy);
            aircraft = v_aircraft;
        }

        public override void Execute()
        {
            aircraft.Accelerate(_velocity);
        }
    }

//Then, There is the Player class that binds keys to actions, and actions to Commands.

public class Player
    {
public enum ActionMove {
            MoveLeft,
            MoveRight,
            MoveUp,
            MoveDown,
            ActionCount
        }

private IDictionary<Keyboard.Key, ActionMove> _keyBinding;
private IDictionary<ActionMove,ICommand> _actionBinding;

public Player()
        {
            _keyBinding = new Dictionary<Keyboard.Key, ActionMove>();
            _keyBinding.Add(Keyboard.Key.Left,ActionMove.MoveLeft);
            _keyBinding.Add(Keyboard.Key.Right,ActionMove.MoveRight);
            _keyBinding.Add(Keyboard.Key.Up,ActionMove.MoveUp);
            _keyBinding.Add(Keyboard.Key.Down,ActionMove.MoveDown);

/** Dunno how to bind the actions to commands without instantiating the command, Hard-Coding the parameters at start. Also Yet I don't have instantiated the aircraft object**/
float playerSpeed = 200f;
            _actionBinding.Add(ActionMove.MoveRight,new MoveAircraftCommand(+playerSpeed,0f,aircraft));
            _actionBinding.Add(ActionMove.MoveUp,new MoveAircraftCommand(0f,-playerSpeed, aircraft));
            _actionBinding.Add(ActionMove.MoveDown,new MoveAircraftCommand(0f,+playerSpeed,aircraft));
/** **/

/**This function pushes the Commands to a queue, in order to process them in order at once**/
public void HandleRealTimeInput(CommandQueue commands) {
            foreach (KeyValuePair<Keyboard.Key,ActionMove> entry in _keyBinding) {
                if (Keyboard.IsKeyPressed(entry.Key) && isRealTimeAction(entry.Value)) {
                    commands.Push(_factory.GetCommand(_keyBinding[entry.Key]));
                }
            }
        }

コマンド パターンを適切に実装し、これらのコマンドが必要なときにすべてのパラメーターを使用して適切にインスタンス化するにはどうすればよいですか?

ありがとうございました

4

1 に答える 1

2

ここで重要なのは、コマンド パターンを提示する「標準的な」方法は、規則ではなくガイドラインであることを理解することです。C# にはデリゲートとラムダが組み込まれているため、ICommand などを定義する必要はありません。コマンド クラスを取り除くことで、Player クラスを大幅に簡素化できます。以下は完全ではありませんが、私が言いたいことを示していることを願っています:

public class Player
{
    private Aircraft _aircraft;
    private float _playerSpeed = 200f;

    private readonly IDictionary<Keyboard.Key, ActionMove> _keyBinding =
        new Dictionary<Keyboard.Key, ActionMove>
        {
            { Keyboard.Key.Left,ActionMove.MoveLeft },
            { Keyboard.Key.Right,ActionMove.MoveRight },
            { Keyboard.Key.Up,ActionMove.MoveUp },
            { Keyboard.Key.Down,ActionMove.MoveDown }
        };

    private readonly IDictionary<ActionMove,ICommand> _actionBinding =
        new Dictionary<ActionMove,Action>
        {
            { ActionMove.MoveRight, () => MoveAircraft(_playerSpeed, 0f, _aircraft) },
            { ActionMove.MoveUp, () => MoveAircraft(0f, -_playerSpeed, _aircraft) },
            ...
        };

    public MoveAircraft(float vx, float vy, Aircraft v_aircraft) 
    {
        var velocity = new Vector2f(vx, vy);
        aircraft.Accelerate(_velocity);
    }

    ...
}

主な変更点は、MoveAircraftメソッドをクラスに移動し、ディクショナリのクロージャー ラムダを介して呼び出すこと_actionBindingです。はDictionary<ActionMove,Action>、ActionMove をキーとして持つディクショナリと、パラメータを持たない void メソッドを値として定義します。次に、 eg式は、 and() => MoveAircraft(_playerSpeed, 0f, _aircraft)の現在の値を に渡すパラメータなしの無名の void メソッドを指定します。_playerSpeed_aircraftMoveAircraft

これらのメソッドを呼び出すには、次のようにします。_actionBinding[ActionMove.MoveRight]();

于 2013-10-29T12:23:56.683 に答える