6

我正在尝试实现键盘文本输入以在游戏中聊天、输入角色名称、保存文件名等。

我在弄乱 KeyboardState 试图让最新添加的符号转换成我可以添加到我的输入字符串中的字符,但它似乎以某种顺序对当前按下的键的数组进行排序(我敢打赌它是按键码排序的),所以我不能轻易找到最后按下哪个键将其添加到输入字符串。

是否有一种简单的方法来检测最后按下的文本键(包括按下多个键的情况,因为人们有时会这样做),还是更容易使用一些现有的解决方案?

我正在学习 C# 和 XNA,所以我希望自己能够做到,但最终我希望我的游戏能够正常工作。

4

2 回答 2

6

为了处理文本输入,您需要知道何时按下或释放某个键。不幸的是,XNA 的 KeyboardState 对此并没有真正的帮助,所以你必须自己做。基本上,您只需将当前更新的 PressedKeys 与上一次更新的 PressedKeys 进行比较。

public class KbHandler
{
    private Keys[] lastPressedKeys;

    public KbHandler()
    {
        lastPressedKeys = new Keys[0];
    }

    public void Update()
    {
        KeyboardState kbState = Keyboard.GetState();
        Keys[] pressedKeys = kbState.GetPressedKeys();

        //check if any of the previous update's keys are no longer pressed
        foreach (Keys key in lastPressedKeys)
        {
            if (!pressedKeys.Contains(key))
                OnKeyUp(key);
        }

        //check if the currently pressed keys were already pressed
        foreach (Keys key in pressedKeys)
        {
            if (!lastPressedKeys.Contains(key))
                OnKeyDown(key);
        }

        //save the currently pressed keys so we can compare on the next update
        lastPressedKeys = pressedKeys;
    }

    private void OnKeyDown(Keys key)
    {           
        //do stuff
    }

    private void OnKeyUp(Keys key)
    {
        //do stuff
    }
}

给你的 Game 类一个 KbHandler,并从你的 Game 的 update 方法中调用它的 Update 方法。

(顺便说一句,比较两个数组可能比使用 foreach 和 Contains 更有效,但是要比较的项目很少,我怀疑它是否重要。)

于 2012-04-14T20:23:09.383 回答
0

您可以尝试此处列出的示例

KeyboardState keybState = Keyboard.GetState();
if (keybState.IsKeyDown(Keys.Left)) {
  // process left key
}
if (keybState.IsKeyDown(Keys.Right)) {
  // process right key
}

这将处理同时按下的多个键。如果你想避免这种情况,请else在第二个if(以及后面的)之前添加一个

此外,按住一个键将触发多个键按下事件——如果不需要,您将需要引入一个状态变量,当键按下时翻转,当它没有按下时,根据其状态继续键按下

于 2012-04-14T13:45:14.947 回答