Archived

This topic is now archived and is closed to further replies.

Movement lag?

This topic is 5586 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

I am having a issue with movement in my game and I was wondering if anyone had similar problems. I am creating Pong with simple controls. up makes it go up down makes it go down. Here is the code I use. Process of the input: case VK_UP: box.move(0,-5); break; case VK_DOWN: box.move(0,5); break; Method to "move" the box: void CObject::move(int xmove, int ymove) { yaxis = yaxis + ymove; } The problem is, when I hold down either up or down, the "paddle" moves 5 pixles, stays idle for a second, then starts a continuous move in the direction I told it to go. The controls overall work properly, but I am wondering what is causing that little lag when I first hold in the key. Any ideas? Thanks in advance!

Share this post


Link to post
Share on other sites
It is pausing because you are working with key-repeats. When you hold the key down, the OS sends repetative key-pressed messages to the program. It takes a moment before this kicks in, so you can type normally and not worry about holding the button down too long.

The correct solution would be to base the movement on the time interval. Basically, when the key is pressed you set a velocity. When it is released, remove the velocity (make it 0). Every frame, move the object time_since_last_frame*velocity.

Share this post


Link to post
Share on other sites
The best way to fix that is to create a keyboard buffer which is an array of 256 BOOL''s.

BOOL keyBuffer[256];

The 256 values represent the scan codes of the keys on your keyboard, thus making it easy to use the VK_ constants as index to this keyboard buffer.

To get some functionality into this keyboard buffer array you have to intercept the WM_KEYDOWN and WM_KEYUP messages. The wParam parameter for those messages represents the scan code value of the key pressed.

Therefore, on WM_KEYDOWN you mark the corresponding key in the keyboard buffer as TRUE, and on WM_KEYUP you mark it as FALSE.

e.g. case WM_KEYDOWN: keyBuffer[wParam] = TRUE; break;
case WM_KEYUP: keyBuffer[wParam] = FALSE; break;


Now you are all set to go.

You have to make keyBuffer global if you want to use it in the entirety of your program.

Once it''s declared as global, anywhere in the program you can do this:

if (keyBuffer[VK_UP])
box.move(-5);
else if (keyBuffer[VK_DOWN])
box.move(5);

...

CBox::move(int dy)
{
m_box.y += dy;
}

This will make up for a very smooth movement.

If you want PRECISION you have to use DirectInput which is a bit more complex and is not part of the Win32 API.

Hope this helps!

-G|aD-

Share this post


Link to post
Share on other sites
Ill actually be using a key buffer in my next program, but it is something I dont want to use here.

Deyja, what you described is actuall exactly what I want. Really, I had that exact code set up but I couldnt find a way to tell when the user released the key, and I didnt see any VK flags that would fit the bill. How would I detect the release of the key someone is currently pressing?

Share this post


Link to post
Share on other sites
quote:

How would I detect the release of the key someone is currently pressing?



Intercept the WM_KEYUP message.

By the way, take a look at the GetAsyncKeyState() function which is a replacement for the keyBuffer() technique w/o having to type all that code.

Good luck!

-G|aD-

Share this post


Link to post
Share on other sites
OK, I set my key handler to watch for the WM_KEYUP, but it just acts like it never sees it. I checked all my arguments and they are all correct. It lets me compile fine...I swear its just like I never get that message. Any ideas?

Share this post


Link to post
Share on other sites
My key code looks like this (Barely changed from NeHe''s original code.


  
case WM_KEYDOWN: // Is A Key Being Held Down?

{
theGame->SendKeyPress(wParam);
return 0; // Jump Back

}

case WM_KEYUP: // Has A Key Been Released?

{
theGame->SendKeyRelease(wParam);
return 0; // Jump Back

}


Inside class ''Game'' I have


  
JMerror Game::SendKeyPress(JMuint8 key)
{
if (key > 255) return JMbad_key;
keys[key] = true;
return JMno_error;
}


JMerror Game::SendKeyRelease(JMuint8 key)
{
if (key > 255) return JMbad_key;
keys[key] = false;
return JMno_error;
}


Of course; you would probably want to just plop the keys array into the main program. In the main game loop, you have ''if(keys[VK_DOWN]) object.move(object.velocity*time_passed);''

You should also check to make sure they aren''t pressing opposite keys - for instance, if they are pressing up AND down, nothing happens. So, if up is pressed, ignore it when you get the keypressed message for down.

Share this post


Link to post
Share on other sites
I narrowed it down even more. I put a case for WM_KEYDOWN in my code and it didnt detect that either. It seems that the problem is, is that my program just isnt seeing any of the "WM" messages. Anyone know why this would happen?

Share this post


Link to post
Share on other sites
If it wasn''t seeing any WM messages (WM means ''Windows Message''. Never would have quessed that, eh?) it wouldn''t be getting the WM_KEYDOWN message either. Post the message handling code.

Share this post


Link to post
Share on other sites
I''m supposing you have a PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) which doesn''t let messages get on your window''s queue therefore your program doesn''t see them.

Anyways...the only way to find out is if you post your main loop code.

-G|aD-

Share this post


Link to post
Share on other sites