0

So I am trying to implement username system into my game and to do so I need to let the user input their desired username. I created a TextBox class.

EDIT

Upon making a further research on other people's experience with the creation of a TextBox in-game, and their approach I came to the following conclusions:

  • My current code is badly designed because the Microsoft.Xna.Framework.Input.Keys and Microsoft.Xna.Framework.Input.KeyboardState.GetState() were never supposed to be used like this.
  • Because of that, the code is inefficient and would consume huge time and effort to do things that are otherwise insignificant because Windows handles them for you, when using Winforms. I will try to find a possible solution by working with some Win32 functions from the user32.dll. And probably use regexp to validate strings.

Once I have it figured out, I'm going to revisit the current code and see what I can recycle and then, scrap the rest.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Johny P.
  • 648
  • 1
  • 9
  • 31
  • By the way, `nameField.OnFocus += NameField_OnFocus;` is called on every `Update()` call. You can subscribe to an event more than once: in this case, that happens up to 60(?) times per second, and `NameField_OnFocus` will be called the corresponding number of times - easily thousands. You should set the event handler only once, preferably in `LoadContent`. – Petri Laarne Sep 05 '16 at 17:31
  • But then there will be no way for me to check if the mouse is in the rectangle and if it was clicked. – Johny P. Sep 05 '16 at 17:49

1 Answers1

0

I think the input problem is here:

if (MainGame.InputManager.IsKeyPressed(keys))
{
    keys = MainGame.InputManager.PressedKeys;

If I understand correctly, this literally reads "if any of the keys pressed last frame is pressed, then do check for input", which is always false. Removing the if statement should solve the problem in that case.

I don't quite follow how the StringBuilder is used. StringBuilder is meant for string modification with low garbage generation, but you're negating that by calling ToString and updating a duplicate string on every key press. Also, if the string length exceeds maximum length, you're truncating the displayed final string but not content, getting them out of sync. I'd just go with modifying final directly.

Detecting alphanumeric characters is easiest done with char.IsLetterOrDigit.

You can also look into GameWindow.OnTextInput if you want to replicate WinForms behavior.

Petri Laarne
  • 421
  • 3
  • 7
  • How can I access `GameWindow Window` outside of the `Game` class without having to create a new instance of the `Game`? Also by removing the `if` and using a `string` instead of `StringBuilder`, when I press a key it gets drawn 5 times, as if I'm holding it but I'm not. – Johny P. Sep 05 '16 at 16:27
  • You can pass the window as a parameter, or otherwise hook up the event. That is up to your engine design. – Petri Laarne Sep 05 '16 at 17:22
  • I don't see anything immediately obvious with the code, so a couple guesses: Do you assign `prevKeyboardState` correctly? Is `TextBox.Update` somehow called more often than `InputManager` updated? – Petri Laarne Sep 05 '16 at 17:25
  • In `InputManager.Update()` I assign `prevKeyboardstate` like this: `prevKeyboardState = currKeyboardState;`. – Johny P. Sep 05 '16 at 17:51