DirectInput keyboard keys get stuck

I've been using the following two methods to collect and poll keyboard:

        public void ProcessInput() // called on each frame render
        {
            Key[] temp = _device.GetPressedKeys();
// _device is DirectInput.Device

            Key[] keys = new Key[temp.Length];
            for( int i = 0; i < keys.Length; i++ )
                keys[ i ] = temp[ i ];
            _lastpressed = keys; // _lastPressed is global Key array
        }

        public bool IsDown( Key k ) // called to see if a key is pressed down
        {
            if (Array.IndexOf( _lastpressed, k ) != -1)
            {
                return true;
            }
            return false;
        }

These methods work pretty well, except when the user tries hitting a number of keys at once. At times, this can cause one (or more) of the keys to become "stuck" down. If I check _device's CurrentKeyboardState, it clearly shows that even the device believes the key is still being pressed down.

The user can fix this by pressing and releasing the "stuck" key again, which seems to update the key correctly. But keys never get stuck on "real" games, and in a frantic situation, the poor guy playing my game is likely going to end up killing himself with this problem.

So how do I ensure that keys don't get stuck Is there a way to explicitly reset the pressed key information, or something I'm using C# and managed directX; I've heard great things about GetAsyncKeyState in C++ but I can't find a C# equivalent...




Answer this question

DirectInput keyboard keys get stuck

  • Super Iain

    Brandon Amoroso wrote:

    Gee, that's annoying. I know keyboards have hardware limits for detecting key presses, but GetCurrentKeyboardState should really get the CURRENT state of the keyboard, without regard to any keypresses it missed earlier.

    Windows doesn't work that way. The keyboard sends messages to Windows, and Windows sends key down and up messages to DirectInput. If these messages get lost somehow, then either Windows or DirectInput idea of what keys are up and down will be wrong.

    As for "real" games, I find that keys do occasionally get "stuck" down when playing them.

    Ross Ridge


  • Tommy Vinson

    double velocity = 0.0;

    //Set the velocity of the sprite based on which keys are pressed

    if (GetAsyncKeyState((int)_leftKey) != 0)

    {

    velocity += -_speed;

    }

    if (GetAsyncKeyState((int)_rightKey) != 0)

    {

    velocity += _speed;

    }

    Velocity.X = (float)velocity;

    Thats for a simple left/right moving sprite - think space invader ship type movement. _leftKey and _rightKey are just values from Forms.Keys

    So I read the keystate directly, if you are storing that state somewhere then I guess there is a chance there is something wrong with the way you store the state.



  • Ling A

    I just tried a very simple app that uses GetAsyncKeyState and no matter what keys I hold down and how much I hammer them I can't repro any kind of stuck down behaviour.

  • Nishad S

    I like the simplicity of this solution, so I've switched over to it.

    However, my keys still get stuck... try it; just hammer away at WSAD and surrounding keys; at least one of them gets stuck eventually.



  • manish_kumar

    DXInput.KeyboardState keys = myKeyboardDevice.GetCurrentKeyboardState();

    if (keys[DXInput.Key.W])

    {

    MyCamera.position.Z += 0.5f;

    }

    if (keys[DXInput.Key.S])

    {

    MyCamera.position.Z -= 0.5f;

    }

    if (keys[DXInput.Key.A])

    {

    MyCamera.position.X -= 0.25f;

    }

    }

    This is the method i use for controling the camera in my directX program using directinput, and i haven't had any problems with keys geting 'stuck'


  • turkeytickler

    I should have been more specific....

    System.Windows.Forms.Keys

    I guess they are not the same as the DInput keys enum



  • Adraw

    *Sigh* Okay, could you post the code for your simple app, or something Maybe I'm missing something obvious (and thanks for your help so far)...

  • manny hall

    Gee, that's annoying. I know keyboards have hardware limits for detecting key presses, but GetCurrentKeyboardState should really get the CURRENT state of the keyboard, without regard to any keypresses it missed earlier. What about my keyboard device init, is there anything fishy here

    public void InitializeInput()
    {
    // set up the keyboard
    dx_keyboard = new DI.Device( DI.SystemGuid.Keyboard );
    dx_keyboard.SetCooperativeLevel(
    this,
    DI.CooperativeLevelFlags.Background |
    DI.CooperativeLevelFlags.NonExclusive );
    dx_keyboard.Acquire();
    }



  • justStarting

    GetAsyncKeyState doesn't have a managed equivalent but its trivial to call it from managed code.

    http://www.pinvoke.net/default.aspx/user32/GetAsyncKeyState.html

    You can even pass in the Keys.XXXXX enum to it (casting to int of course) and it works just fine.



  • vasu_ve

    Nope; no multithreading and no soda.

    I mean, it's not like my keys ever get stuck while I'm word processing, composing email, or playing Knights of the Old Republic. That's why I assuming that there's something wrong with my code.

    Is there any specific part of my code that might help I don't want to post annyoing scads of code without cause...



  • Tony_

    Well if you ask me like when you press W-D and E at the same time one of the keys don't work properly I think thats normal. But none of my keys get stuck in the down state...
  • Femiani

    Well, it works when I try that...

    ...unfortunately, the keys can still get stuck, even with GetAsyncKeyState.

    I just don't get it. We made a C++ directX app in class, and this simply doesn't happen there. Why does it happen in this environment



  • MadhukarChaubey

    Probably a dumb question but you didn't happen to spill soda or something on your current keyboard and the key contacts are ACTUALLY gettting stuck down

    If you are calling GetAsyncKeyState then its really can't be anything to do with the managed environment. Plus that API is supposed to be reading things at a very low level - it doesn't use the windows messages at all.

    You don't have any multithreading stuff going on do you such that something else is resetting some internal that you are setting.



  • mancroft

    That sounds useful... I've tried making the following call:

    // DI is the DirectInput namespace
    if ( GetAsyncKeyState( (int)DI.Key.Space ) != 0 )
    {
    // Jump
    }

    But when I hit SPACEBAR, the guy never jumps (and if I set the condition to "== 0", he jumps constantly). Its seems like the method never returns anything but false...



  • DirectInput keyboard keys get stuck