How do you get numeric keyboard input?

I know I can read the keyboard for individual keypresses, but I need to get a numeric value (specifically a time) from a user. What I specifically need is a TimeSpan value from the user.

One idea I had was to make kind of a steampunk clock display with up and down arrows for the hours and minutes. Is there any way in XNA/MonoGame just to get a string from a user? How do people handle like getting a user’s name for example?

Thanks for any suggestions.

One way you could get numeric text input is by watching for the right key inputs. If one of the number keys is down on the current frame and was up during the last frame, then it was just pressed and should be registered as a number input. The enum values for the number keys are Keys.D0 through Keys.D9 for the keys above the letters, and Keys.NumPad0 through Keys.NumPad9 for the number pad keys.

Store the KeyboardState at the end of the frame as something like previousKeyboardState so you can compare that to the current state on the next frame.

KeyboardState previousKeyboardState;
public void Update
{
    KeyboardState currentKeyboardState = Keyboard.GetState();
    if (currentKeyboardState.IsKeyDown(Keys.D0) && previousKeyboardState.IsKeyUp(Keys.D0))
            // 0 key was pressed
    // ...and so on
    previousKeyboardState = currentKeyboardState;
}

If you find that laborious, you could try using Keyboard.GetState().GetPressedKeys() to get an array of all the keys that are down on the current frame, but you may want to pass an array to that method to avoid allocating a new array each time, and you’d want to keep a previousKeys array around so you can see what keys were down on the previous frame, so that you don’t re-input keys that were already down during the previous frame.

There’s probably also some helper code for getting text input out there that someone’s already written, I don’t know.

1 Like

My preferred way is through text input. Looking at specific keys runs issues when people have different keyboard layouts. MonoGame offers this mechanism instead:

Window.TextInput += ProcessTextInput;

// ...

private void ProcessTextInput(object sender, TextInputEventArgs e) {
    // Do something with 'e'. In this case, you can check if it's a number.
}

You would call the first line once perhaps at the start of your game.

Edit: https://docs.microsoft.com/en-us/dotnet/api/system.char.isnumber?view=net-6.0

1 Like

I need to get a TimeSpan from the user repeatedly during the game. Will this work inside Update()?

Just to confirm, from your opening post, it sounded like you want to code a textbox that only accepts numbers. Then if in the textbox the player inputs “1337” you want to turn that into a timespan.

Here is an example of how I code a textbox:

Line 100 is where I’d put a check to make sure the character is a digit.

Don’t look too hard at the rest of the code, that’s some stuff from my UI library but you can do something similar. If that’s what you want.

The advantage is that this would handle keys from the number row, the numpad, etc in any keyboard layout. Some layouts require pressing shift to input a number. My way can handle that.

Thanks a lot!
I have to say the people in the MonoGame forum are so much friendlier and more helpful than the Stack Overflow crowd that’s always quick to say how stupid you are.

1 Like

Well, that’s a lot easier. I think I knew about that event at some point, but completely forgot.

That code is an event, so it doesn’t need to be in the Update loop. The Window.TextInput event is triggered any time the user types anything, so the code to process the user’s text input runs on an as-needed basis instead of once every frame. You can just have some sort of Boolean flag in the method that subscribes to the event, set the flag to true whenever you’re waiting for text input, and set it to false when you’re not, and when you’re not waiting for text input just break out of the subscribed method early.

Stack Overflow is a very different place from a traditional forum. They’re not looking for open discussion, they’re looking for “canonical” answers and stuff. Here, we’re a lot more chill.

I’m not personally a fan of the Stack Exchange network of websites for a number of reasons.

1 Like