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