代码之家  ›  专栏  ›  技术社区  ›  Alex

键盘C WPF的多个输入

  •  2
  • Alex  · 技术社区  · 14 年前

    我正在用wpf写俄罗斯方块的克隆体。如果我按住右箭头键,则当前工件向右移动。为了便于播放,我希望允许用户按另一个键(即f键)并旋转移动的部件 不用先松开右箭头键 . 目前,当我这样做时,工件停止移动。

    我的第一个基本尝试是

    Window_PreviewKeyDown(object sender, KeyEventArgs e)
    

    然后向控制器层发送消息。

    我如何构造我的输入监听代码以允许这样做?

    我的当前代码 Here

    4 回复  |  直到 14 年前
        1
  •  2
  •   Jakob    14 年前

    也应该存在一个keyup事件,通过同时使用keydown和keyup,您可以实现所需的效果。有几种方法可以做到。

    一种方法是让keydown事件启动一个重复动作,然后让keydup取消它。

    另一个方法是存储某些密钥是否被按住。保留一个关键点列表,并在关键点向下时将其打开,在关键点向上时将其关闭。在游戏主循环中,您将触发与当前关闭的所有键对应的事件。

    一个例子:

    bool[] heldDown = new bool[256]; // One index for the keycode of each key
    
    void Window_PreviewKeyDown(object sender, KeyEventArgs e) {
        heldDown[e.KeyCode] = true;
    }    
    void Window_PreviewKeyUp(object sender, KeyEventArgs e) {
        heldDown[e.KeyCode] = false;
    }    
    

    然后,在主循环中执行“heldown”,并为被按住的每个有意义的键触发事件:

    if (heldDown[Key.F])
        MainController.TriggerPieceEvent(Constants.PieceEvents.RotateClockwise);
    if (heldDown[Key.Left])
        MainController.TriggerPieceEvent(Constants.PieceEvents.ShiftLeft);
    // etc...
    
        2
  •  3
  •   Hans Passant    14 年前

    你依靠自动重复键来保持工件移动。这不合适,用户的键盘重复延迟是可变的,会影响游戏的可玩性。当你发现,当按下另一个键时,它停止自动重复。

    通过将每个游戏对象设置为运动状态来解决此问题。使用keydown事件更改它。如果运动状态值仍然与关键点匹配,则返回keyup事件以重置它。在游戏循环中,根据运动状态更新游戏对象的位置。你会以固定的速度,由计时器触发。

    运动状态也应显示“坠落”。你现在可以简单地使游戏更困难,随着水平的进展,通过减少计时器的速度。碎片落得更快。而且键盘的响应能力更强,用户仍有机会赢得一个级别。

        3
  •  1
  •   mihi    14 年前

    Windows将只对您按下的最后一个键重复事件。此外,首先重复按键之前的延迟,以及重复按键的速率,取决于通常为键入而不是为游戏而优化的设置。因此,对于游戏来说,最好完全忽略它们,并有自己的方法来实现“重复”键。

    基本上,你必须保持你感兴趣的键的状态(按下或释放),并在收到keydown或keydup事件时更改它们。然后,在某种计时器中,您将必须检查状态,并为在该时刻关闭的每个键触发事件。如果计时器发生在控制器层或ui中,则取决于您的体系结构 :-)

    您可以添加额外的检查,比如当左键和右键同时按下时忽略这两个键,否则工件将重复地向左和向右跳跃。

        4
  •  1
  •   NibblyPig    14 年前

    你需要国家。创建一些变量,如“rightarrowpressed”和“rotatebuttonpressed”

    在key_down中,检查按键是否按下,如果按下,则将相应的变量设置为true。

    在key_up中,执行相同操作,但将其设置为false。

    现在,在任何一点上,您都可以查看这两个变量,并查看按下了哪些键。