Making text input in XNA (for entering names, chatting)

10,363

In order to handle text input, you'll need to know when a key is pressed or released. Unfortunately, the XNA's KeyboardState doesn't really help with this, so you have to do it yourself. Basically, you just need to compare the current update's PressedKeys with the PressedKeys from the previous update.

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
    }
}

Give your Game class a KbHandler, and call it's Update method from your Game's update method.

(BTW there is probably a more efficient way to compare two arrays than with foreach and Contains, but with so few items to compare I doubt it will matter.)

Share:
10,363
user1306322
Author by

user1306322

I've come to learn things and teach stuff. And I'm all outta stuff. And don't take anything I say personally, because… I don't give it to you personally! Feel free to improve my posts by editing or commenting. helpful links: http://xbox.create.msdn.com/en-US/education/tutorial/2dgame/getting_started http://jsbeautifier.org/ (also acceptable for C#) http://regex101.com/ I strongly recommend you include in your question all additional details that might help us answer your question properly and completely.

Updated on June 09, 2022

Comments

  • user1306322
    user1306322 almost 2 years

    I'm trying to implement keyboard text input for chatting in game, typing character name, save file name, etc.

    I was messing around with KeyboardState trying to get the newest added symbol to translate in into character that I could add to my input string, but it seems to sort the array of currently pressed keys in some order (I bet it's sorted by keycode), so I can't easily find which key was pressed last to add it to input string.

    Is there an easy way to detect the last pressed text key (including situations when multiple keys are pressed, because people do that sometimes), or is it easier to make use of some existing solutions?

    I'm studying C# and XNA, so I'd like to be able to do it myself, but in the end I want my game to work.

  • user2032201
    user2032201 about 12 years
    Clearly, you can read the others as well: MSDN, e.g. Keys.A instead of Keys.Left
  • user1306322
    user1306322 about 12 years
    I suspected you meant that, and it's not very cool to type an explicit scenario for every possible case, and there are a lot of cases in ascii, let alone unicode. Do you know another way?
  • user2032201
    user2032201 about 12 years
    You can use the approach outlined in this conversation. Basically, you use the toString() method to convert the key pressed to get the value (instead of individual ifs). You will have to handle (incl. discard) the special keys that either have special sense or make no sense from a typing standpoint (e.g. backspace or ESC)
  • user1306322
    user1306322 about 12 years
    But how do I get just one new key at a time? I mean, when I try getting all keys pressed currently, they are sorted not in the order of pressing, so I can't just take last index of that array.
  • user2032201
    user2032201 about 12 years
    I'm not sure I understand: When the user is typing, it is unlikely that they press two keys at the same time (uless it's Shift+A and the like, where order doesn't matter). In the rare case when they do press multiple (letter) keys at once, you can just take any order (or none), your decision.
  • user1306322
    user1306322 about 12 years
    Sometimes you hit several keys by mistake, and the key(s) pressed might read errenously, making it frustrating to erase unwanted characters. I'd like to make this work exactly like in form applications, except without default inputbox control on top of game screen.
  • user2032201
    user2032201 about 12 years
    As the link in my earlier comment pointed out, XNA is not designed for text input, so you will have to make do with what it offers. Another technique I found was to go down to the Windows messaging level: see this thread
  • user1306322
    user1306322 about 12 years
    I've seen several times that using hooks is the last resort, first and foremost because it's a really bad way to do this. I know XNA doesn't support textual input, but still there's gotta be a way to do it without hooks.
  • user1306322
    user1306322 about 12 years
    Thanks, this is the kind of algo I was looking for.