Handling a Keyboard properly XNA
Well I was looking on the net for a way to do KeyBoard handling in XNA, what I found: if ( key.OldState && ! key.NewState) then processkey( )
While this works fine if you finger type, it does not work as a keyboard should.
When you PRESS a key the key should come up not when you let go thus
using the old method if you type fast you'll find out that some keys
you press and let go of faster than others hence causing problems.
Another problem is when you hold a key it will ever only process 1x,
what if you should want multiple Key Presses without pressing it multiple times like space and backspace
We need some way to monitor the information we will need. I propose a Key_Press class as follows:
public class Key_Press
{
public Key_Press(uint currentFrame)
{
time = TimeSpan.Zero;
frame_Pressed = currentFrame;
}
public TimeSpan time;
public uint frame_Pressed; //feel free to use bool but i prefer this.
}
The following should be called from the Update method of XNA
public uint frame_Number = 0;
public Dictionary key2KeyPress = new Dictionary();
Keys[] pressed_Key = Keyboard.GetState().GetPressedKeys();
for (int q = 0; q < pressed_Key.Length; q++)
{
if (!key2KeyPress.ContainsKey(pressed_Key[q])) //if key isnt supportedsupport it.
key2KeyPress.Add(pressed_Key[q], new Key_Press(frame_Number));
Key_Press pk = key2KeyPress[pressed_Key[q]];
if (pk.frame_Pressed + 1 == frame_Number) //key down.
{
pk.time += gameTime.ElapsedRealTime;
pk.frame_Pressed = frame_Number;
if (pk.time.Milliseconds > 400)
I_WAS_PRESSED(pressed_Key[q]);
}
else //key press
{
pk.time = TimeSpan.Zero;
pk.frame_Pressed = frame_Number;
I_WAS_PRESSED(pressed_Key[q]);
}
}
All done. And a much nicer keyboard to work with for typing anyway. Of course you still need to add modifiers so you can tell the difference between Shift-A and just A for e.g. But the goal of this article is simplicity.
Working Source