Eso lo puedes lograr invocando rutinas de la API de windows, en el ejemplo que te he colocado puedes ver como usar la API desde C# (aunque algunas cosas obviamente no estan alli... tendras que preguntar sino lo logras hacer) con estos ajemplos ya puedes hacerte una idea y utilizar la api para lo que quieres realizar...
<!--xc1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>XCODE </td></tr><tr><td id='XCODE'><!--exc1-->
using System;
using System.Runtime.InteropServices;
namespace Engine_Estados
{
public class Entrada_class
{
#region Llamado a funciones de la API
[DllImport("kernel32", SetLastError=true)]
static extern IntPtr GetStdHandle(IntPtr whichHandle);
[DllImport("kernel32", SetLastError=true)]
static extern bool GetConsoleMode(IntPtr handle, out uint mode);
[DllImport("kernel32", SetLastError=true)]
static extern bool SetConsoleMode(IntPtr handle, uint mode);
#endregion
#region Variables para manejo de la API
static readonly IntPtr STD_INPUT_HANDLE = new IntPtr(-10);
private IntPtr hConsoleHandle;
const uint ENABLE_LINE_INPUT = 2;
const uint ENABLE_ECHO_INPUT = 4;
uint modo, nmodo;
#endregion
public Entrada_class()
{
hConsoleHandle = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hConsoleHandle, out modo);
nmodo = modo & ~(ENABLE_LINE_INPUT |ENABLE_ECHO_INPUT);
SetConsoleMode(hConsoleHandle, nmodo);
}
~Entrada_class()
{
SetConsoleMode(hConsoleHandle, modo);
}
public int Leer()
{
return Console.Read();
}
public void Leer(char car)
{
while(Console.Read() != car);
}
public int Leer(bool modoNormal)
{
int ret;
if(modoNormal)
{
SetConsoleMode(hConsoleHandle, modo);
ret = Console.Read();
SetConsoleMode(hConsoleHandle, nmodo);
}
else
ret = Console.Read();
return ret;
}
}
}
<!--xc2--></td></tr></table><div class='postcolor'><!--exc2-->
Ahora si yo fuera tu usaria mejor alguna libreia como DirectX, especificamente DirectInput para poder hacerlo más facilmente y porque ademas incorporan muchas otras funcionalidades que te pueden ser de utilidad.