Jump to content
  • Advertisement
Sign in to follow this  
silverphyre673

Clearing keys after GetKeyState()

This topic is 4878 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey. I'm using the GetKeyState() function in the Win32 API to poll the keyboard for keypresses. The thing about it is that it appears to "remain on" until another key is pressed. For example, in the pong clone I'm using it in, the paddle will go all the way to the top/bottom of the screen and stay there until another key is pressed. It seems to only get the last key pressed. I'm wondering which function to use to check for multiple key inputs at the same time and clear them when the key is lifted. What I'm doing right now is having a 256 boolean buffer that holds whether any of the keys have been pressed. I just poll the keyboard like this:
void KeyboardInput::PollKeyboard()
{
    short key_pressed;
    for ( unsigned int i = 0; i < 256; ++i )
    {
        key_pressed = GetKeyState(i);
        //WinToIICode() converts a Windows virtual keypress code to my own
        //sequential code.  Shouldn't affect anything - its just a big switch
        //statement that appears to be functioning properly.

        //keys[] is the 256 boolean buffer I mentioned earlier. 
        if (key_pressed<0)
        {
            keys[WinToIICode( i )] = true;
        }
        else
        {
            keys[WinToIICode( i )] = false;
        }
    }
}

On MSDN's keyboard input page they say that in general, you will use GetKeyState() for keyboard input, but it doesn't appear to be helping, unfortunately. Any hints? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
I'm trying to allow multiple keys being pressed at the same time. The game is two player as well as one player, and it wouldn't be very fair if you were playing pong and your friend prevented you from moving your paddle by pressing on their controls, would it? I tried both GetAsyncKeyState and GetKeyState, and neither of them really worked. Processing WM_KEYPRESS messages works for single-key input just fine, but I haven't found a way to get it to work for multiple simultaneous keypresses.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Alternativly, process WM_KEYDOWN and WM_KEYUP events.


Much better option than Get(Async)KeyState

Share this post


Link to post
Share on other sites
Hrmmmn, I doubt you're using the function properly, silverphyre673.


Anyway, this method does basically what you want. Put this code in your WndProc function, and avoids those functions completly (I prefer this method):


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_KEYDOWN:
keys[wParam] = true;
break;
case WM_KEYUP:
keys[wParam] = false;
break;
}
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Andrew Russell
Hrmmmn, I doubt you're using the function properly, silverphyre673.


Anyway, this method does basically what you want. Put this code in your WndProc function, and avoids those functions completly (I prefer this method):

*** Source Snippet Removed ***


Agreed. I tried your method, but it unfortuntely resulted in the original problem of not working when two keys are pressed at once (only the latest key pressed is treated as down). Also, does anyone know how to set how long it takes before holding down a key just creates a whole bunch of characters, like holding down "i" might produce iiiiiiiiiiiiii? I want the paddles to move smoothly, and its really hard to play right now at fast speeds. Thanks.

Share this post


Link to post
Share on other sites
Then something is wrong in the way you are using the keys[] array. Are you setting a key to false later in your program or something?

Unless you are doing something extreemly daft when you process the incoming keys (which is almost impossible with the WM_KEYDOWN/WM_KEYUP method I gave you).

The keyboard repeat-rate should be irrelevent. It sends another WM_KEYDOWN event before it ever sends a WM_KEYUP event. Meaning that the key is already set to true when the event does "keys[wParam] = true;" (in other words, it has no effect).

Your messages would be something like "DOWN(key becomes true) DOWN DOWN DOWN DOWN DOWN UP(key becomes false)".

Your function that reads the key array should look something like this:

void Update()
{
if(keys[PLAYERONE_UP])
{
playerone.y += 5;
}
if(keys[PLAYERONE_DOWN])
{
playerone.y -= 5;
}
if(keys[PLAYERTWO_UP])
{
playertwo.y += 5;
}
if(keys[PLAYERTWO_DOWN])
{
playertwo.y -= 5;
}
}

Share this post


Link to post
Share on other sites
Ah! I got it. My fault: I was checking to see if a key was pressed with my input wrapper every message. Changing it to checking once every 10ms worked. Thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!