Unfortunately, XNA does not directly offer this functionality.
Therefore I wrote this very simple event-driven class that does exactly that:
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; namespace XNASingleStroke { public class SingleKeyStroke : GameComponent { public event EventHandler<KeyDownEventArgs> KeyDown = delegate { }; private int pressedKeys; public SingleKeyStroke(Game game) : base(game) { } public override void Update(GameTime gameTime) { var pressed = Keyboard.GetState().GetPressedKeys(); var keys = 0; foreach (var key in pressed) { var num = 1 << (int)key; keys |= num; if ((pressedKeys & num) != num) { KeyDown(this, new KeyDownEventArgs(key)); } } pressedKeys = keys; base.Update(gameTime); } } }
And this is KeyDownEventArgs that's used in the event handler:
using System; using Microsoft.Xna.Framework.Input; namespace XNASingleStroke { public class KeyDownEventArgs:EventArgs { public Keys Key { get; set; } public KeyDownEventArgs(Keys key) { Key = key; } } }
Usage is also very simple:
protected override void Initialize() { // ... SingleKeyStroke singleStroke = new SingleKeyStroke(this); //where 'this' is your Game singleStroke.KeyDown += (o, e) => { switch (e.Key) { case Keys.Space:Console.WriteLine("Space was pressed"); break; case Keys.Enter:Console.WriteLine("Enter was pressed"); break; } }; Components.Add(singleStroke); }