Hi everyone.

For the past day I've been trying to find a good way to handle keyboard input.

Naturally, I wanted to just use WM_KEYDOWN and WM_KEYUP to handle my events, but they proven to have limitations. In my game there was a keyboard delay. If you pressed and held down the right arrow key, the character would move one pixel to the right, stop, then continue moving. I wanted the character to immediately start moving and continue moving once the right arrow key was pressed and held.

Another problem with using just WM_KEYDOWN is that if you are moving your character with the right arrow key and then press spacebar, your character stops moving. Apparently this WM_KEYDOWN message couldn't handle more than one key being processed at a time.

I look into DirectInput and get it working finally. I notice there is none of that keyboard repeat rate delay and it could handle more than one key being held at a time. The problem was, it was messy. Basically, DirectInput was overkill. Also, handling KeyUp messages with DirectInput was hell.

Now I look into GetAsyncKeyState. It looks good, but it seems a bit messy and slow.

Overall, I'm looking for a way to use WM_KEYDOWN and WM_KEYUP to handle more than one key at a time (so if you're moving and press space you don't stop moving for example) and I also want it to not have a delay. For example, the instant I press the right arrow key my character starts moving and doesn't stop.

The only method I found for doing this so far required a messy array of bools I didn't really want to get into. It was worse than using DirectInput or GetAsyncKeyState in my opinion.


Use WM_KEYDOWN as a toggle instead of an event that actually moves your character. You've probably discovered by now that your character movement corresponds to how repeat keys work. Therefore;

MoveFlag ^= 1;

Then in a timer event check if the flag is on and if so move your character.

if (MoveFlag && 1)
   .... Move Character

If you want to move in all four directions or even diagonally then just use a bit position in MoveFlag array to represent up down left right. If you use a 4 bit or 8 bit values in MoveFlag you can even change the speed you want your character to move in that direction relative to the rest.

So lets say MoveFlag represents Left Up Right Down each having a 4 bit value. Then MoveFlag = 0460H. This would move your character 4 pixels up and 6 right everytime your timer event was executed. Of course there is a lot of code that needs to be implemented to make this work, but I think you understand now how using WM_KEYDOWN, WM_KEYUP as toggles and then a timer works much better for your objective.

NOTE: I code exclusively in assembly so my C++ syntax may not be correct, but procedurally this is how I would implement.

This article has been dead for over six months. Start a new discussion instead.