4

「スペースインベーダー」のようなシンプルなゲームに取り組んでいて、問題が発生しました。ユーザーに、左から右に好きなだけ移動できるようにすると同時に、「スペースバー」を使用して撮影できるようにしようとしています。

私の問題は、1つ以上のキーを押すと、1つの関数しか実行されないということです。

ここで私が試したいくつかのもの:

  1. キーをに保存するList<Keys>(しかし、関数を実行するための良い方法が見つからず、すべてが乱雑になります)

    2.次のようなkey_downイベントの通常の処理:

    protected void Form1_keysDown(object obj, KeyEventArgs e)
    {
        (e.KeyData == Keys.Space)
            spaceShip.FireBullets();
    
        if (e.KeyCode == Keys.Left)
            spaceShip.MoveLeft();
    
        if (e.KeyCode == Keys.Right)
            spaceShip.MoveRight();
     }
    

私の質問は次のとおりです。これを機能させるための良い方法は何ですか?

(私の英語でごめんなさい)

4

1 に答える 1

7

キーを押したままにすると、キーボードコントローラーがキーを繰り返すことに依存しています。別のキーを押すと、それは機能しなくなります。これには別のアプローチが必要です。

まず、NotMoving、MovingLeft、MovingRightなどの値で宇宙船のモーション状態を示す列挙型が必要です。そのタイプの変数をクラスに追加します。KeyDownイベントとKeyUpイベントの両方が必要になります。たとえば、Keys.LeftのKeyDownを取得したら、変数をMovingLeftに設定します。Keys.LeftのKeyUpイベントを取得したら、最初に状態変数がまだMovingLeftであるかどうかを確認し、残っている場合はNotMovingに変更します。

ゲームループで、変数値を使用して宇宙船を移動します。いくつかのサンプルコード:

    private enum ShipMotionState { NotMoving, MovingLeft, MovingRight };
    private ShipMotionState shipMotion = ShipMotionState.NotMoving;

    protected override void OnKeyDown(KeyEventArgs e) {
        if (e.KeyData == Keys.Left)  shipMotion = ShipMotionState.MovingLeft;
        if (e.KeyData == Keys.Right) shipMotion = ShipMotionState.MovingRight;
        base.OnKeyDown(e);
    }
    protected override void OnKeyUp(KeyEventArgs e) {
        if ((e.KeyData == Keys.Left  && shipMotion == ShipMotionState.MovingLeft) ||
            (e.KeyData == Keys.Right && shipMotion == ShipMotionState.MovingRight) {
            shipMotion = ShipMotionState.NotMoving;
        }
        base.OnKeyUp(e);
    }

    private void GameLoop_Tick(object sender, EventArgs e) {
        if (shipMotion == ShipMotionState.MovingLeft)  spaceShip.MoveLeft();
        if (shipMotion == ShipMotionState.MovingRight) spaceShip.MoveRight();
        // etc..
    }
于 2012-04-08T15:06:00.367 に答える