Advertisement

Keyboard Input problem

Started by August 07, 2002 03:33 PM
7 comments, last by C-Squared 22 years, 1 month ago
I''m getting into Windows (Visual C++ 6.0) programming after working with C++ for a while. For now, I''m just learning little tidbits to practice with, rather than taking a step by step class. Anyway, I made this small program in which you use the keyboard to move a box around the window. I hope to eventually make a small game similar to Galaxian. My problem is this: If you''re holding the left arrow key (causing the box to go left), and then press the spacebar (while still holding the left arrow), the box will stop moving , and any subsequent spacebar presses will cause the box to move left again. In order to check for key presses, I use the GetAsyncKeyState function under WM_KEYDOWN. This is kind of difficult to describe, so if anyone needs some clarification, let me know. Thanks.
If you are processing the WM_KEYDOWN Message:

Use this switch tree in your WM_KEYDOWN prcessor, as GetAsyncKeyState is left in for Win16 support.


              switch (wParam)             {                 case VK_LEFT:                                         // Process the LEFT ARROW key.                                          break;                  case VK_RIGHT:                                         // Process the RIGHT ARROW key.                                          break;                  case VK_UP:                                         // Process the UP ARROW key.                                          break;                  case VK_DOWN:                                         // Process the DOWN ARROW key.                                          break;                  case VK_HOME:                                         // Process the HOME key.                                          break;                  case VK_END:                                         // Process the END key.                                          break;                  case VK_INSERT:                                         // Process the INS key.                                          break;                  case VK_DELETE:                                         // Process the DEL key.                                          break;                  case VK_F2:                                         // Process the F2 key.                                         break;                                  // Process other non-character keystrokes.                                  default:                     break;             }   


Because of the autorepeat feature, more than one WM_KEYDOWN message may be posted before a WM_KEYUP message is posted. The previous key state (bit 30) can be used to determine whether the WM_KEYDOWN message indicates the first down transition or a repeated down transition.

-James
Advertisement
If you''re using the WM_KEYDOWN message, when you press left, the box should only move a bit...

In any case you might want to do something like this:
if GetAsyncKeyState(VK_UP)    MoveUp();if GetAsyncKeyState(VK_DOWN)    MoveDown();if GetAsyncKeyState(VK_LEFT)    MoveLeft();//etc.. 

To the Anonymous poster (James):
I tried what you said, and it didn''t work.
What do you mean by the bit 30 (previous key state)? Would it be this:

if(GetAsyncKeyState(VK_WHATEVER) & 0x30)
{
//do whatever;
}

I''ve seen something like that before.
There is a better way. Use Windows messages with booleans:


  //first set up a key array globallybool keys[256];//then use windows messages to set the valuesLRESULT CALLBACK WndProc(HWND hWnd,// Handle For This Window  UINT uMsg,		// Message For This Window  WPARAM wParam,	// Additional Message Information  LPARAM lParam)	// Additional Message Information{	switch (uMsg)	// Check For Windows Messages	{		case WM_KEYDOWN:  // Is A Key Being Held Down?		{			keys[wParam] = TRUE;  // If So, Mark It As TRUE			return 0;  // Jump Back		}		case WM_KEYUP:	// Has A Key Been Released?		{			keys[wParam] = FALSE;  // If So, Mark It As FALSE			return 0;  // Jump Back		}	}}//then check the keys in your game loop//make sure that you do not us else if here//without else if, you can detect multiple keys at onceif(keys[VK_LEFT]) {  //move left}if(keys[VK_RIGHT]) {  //move right}  


ps. To give credit where credit is due, this code is take directly from NeHe''s OpenGL tutorial code.

---
Make it work.
Make it fast.

"I’m happy to share what I can, because I’m in it for the love of programming. The Ferraris are just gravy, honest!" --John Carmack: Forward to Graphics Programming Black Book
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Same AP (James):

Are you using MFC or are you programing your WindProc like CaptainJester (CJ) has above?

If your are programming With MFC, say so, I can give you step by step how to do it. otherwise, look at CJ''s switch tree. He takes the message and switches it to see which WM_ it is. Once he has determined that is is KEYUP or KEYDOWN, he stores the key in a map that he cycles through every loop to see if they need to be processed.

If you place the switch tree I posted that came from the Windows Platform SDK that you can view or download at msdn.microsoft.com in place of his map routines, you can switch the wParam of the KEYDown message which happens to be the key that was pressed to send that message. You don''t ever have to use GetAsyncKeyState.

When I say bit 30, I meant bit 30 of the lParam.

goto
msdn.microsoft.com/library
and look up WM_KEYDOWN

-James
Advertisement
here is a link to a zip file containing the workspace and all the files:
Click Here

Once you get it going, do the following:
Use the arrow keys to move the box left(or right, up, down, whatever).
Now, suppose you were to use another key, (say, the spacebar), to do something (such as fire a missle). If you fire a missle while you are moving with the arrow keys, you stop moving. Thats the problem I'm trying to fix. I hope this helps explain better.

[edited by - C-Squared on August 8, 2002 7:55:32 PM]
The method I posted will fix your problem.

---
Make it work.
Make it fast.

"I’m happy to share what I can, because I’m in it for the love of programming. The Ferraris are just gravy, honest!" --John Carmack: Forward to Graphics Programming Black Book
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
OK, it fixed the problem, but now when I move with the arrow keys, it moves very far, as if the WM_KEYUP isn't being processed correctly. I uploaded a new zip file. I guess I should have made everything a function, but for now you'll have to copy/paste. Also, When I use InvalidateRect to redraw, I can't use hWnd for the first parameter because it doesn't exist yet; is it okay to just move the declaration to the top of the file? Thanks for everyone's help so far.
PS To get the new ZIP file, use the link in my previous post.

[edited by - C-Squared on August 9, 2002 2:19:37 PM]

This topic is closed to new replies.

Advertisement