WinForm:多个按键同时按下

4

我正在制作一个类似“太空侵略者”的简单游戏,但遇到了问题。我想让用户能够自由地从左到右移动,并同时可以使用“空格键”进行开火。

我的问题是:当我按下多个键时,只有一个功能运行。

以下是我尝试过的一些方案:

  1. Storing the keys in a List<Keys> (but i didnt find any good way to excute the functions and everything become messy)

    2.normal handling of the key_down event like this:

    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();
     }
    
我的问题是:有什么好方法可以使这个工作起来?(抱歉我的英语)

2
除非必要,否则制作游戏和图形密集型应用程序时应使用XNA或DirectX或其他替代方案,而不是WinForms。它们并不是为了过于动态的应用而设计的,你会在制作过程中遇到很多障碍。例如,XNA有一个名为Keyboard的类,其中包含像IsKeyDown这样的方法,因此可以节省大量时间。 - Ashley Davies
谢谢您的回复。也许将来当我感觉更舒适时,我会转向XNA。 - samy
1个回答

8
您正在依赖键盘控制器在按住按键时重复按键。但当您按下另一个键时,这种方法将停止工作。因此需要采用不同的方法。
首先,您需要一个枚举类型来指示飞船的运动状态,例如NotMoving,MovingLeft和MovingRight等值。将该类型的变量添加到您的类中。 需要同时使用KeyDown和KeyUp事件。例如,当您获得KeyDown事件时,如果按下了Keys.Left,则将变量设置为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..
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接