Input and smooth movement?

Started by
11 comments, last by Waaayoff 12 years, 5 months ago
I'm using Win32 messages to capture keyboard movement. Whenever my WndProc recieves a WM_KEYDOWN message, i move the camera by 1 unit. However, this causes the camera to 'jump' positions and not move smoothly. I don't understand why this is happening?
"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
Advertisement
Look into frame independence. You will find several threads on the subject here.

Remember to mark someones post as helpful if you found it so.

Journal:

http://www.gamedev.net/blog/908-xxchesters-blog/

Portfolio:

http://www.BrandonMcCulligh.ca

Company:

www.gwnp.ca

I already use the elapsed time to regulate movement. When i move the camera inside the rendering loop, the movement is smooth. The problem is when i move the camera inside the WndProc function. The camera sorts of suddenly jerks into movement.
"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
I think that is due to the fact that windows API messages are not necessarily called at say 60FPS or however frames your game is running at. I am not going to say that it belongs in the rendering loop as you should have your rendering and update logic separate but I think it is better suited there than in the windows function.

Remember to mark someones post as helpful if you found it so.

Journal:

http://www.gamedev.net/blog/908-xxchesters-blog/

Portfolio:

http://www.BrandonMcCulligh.ca

Company:

www.gwnp.ca

I would check how your processing your message pump, you might be only processing 1 windows message per frame.

Make sure its like this:

for(;;) //message pump
{
//look for a message
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//check that we arent quitting
if(msg.message==WM_QUIT) break;
//translate message
TranslateMessage(&msg);
//dispatch message
DispatchMessage(&msg);

}
else
{
if ( Program_Running() == 0) // good call
{

}
else //bail out we had a error
{
MessageBox(NULL, "Failed in Program_Running()" , "Fatal Error", MB_OK);
PostQuitMessage(99);
}
}

}
My loop is the same.

Game loop
void Renderer::StartRendering()
{
MSG msg;

while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);

if(msg.message == WM_QUIT)
break;
}

mImmediateContext->ClearRenderTargetView(mRenderTargetView, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
mImmediateContext->ClearDepthStencilView(mZBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0);

if (mFrameListener)
if (!mFrameListener->OnRenderStart())
break;

mSwapChain->Present(0, 0);
}
}



WndProc

LRESULT Framework::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_KEYDOWN:
{
if (wParam == 'S')
{
mCamera->TransZ(-1);
}

else if (wParam == 'D')
{
mCamera->TransX(1);
}
}
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
}

return DefWindowProc(mhWnd, uMsg, wParam, lParam);
}

"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
Your code below will check peekmessage() 1 time per render frame, you need to make it a if else and only render if there is no windows message.

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);

if(msg.message == WM_QUIT)
break;
}


It should be like this: (edit sorry for formatting)

void Renderer::StartRendering()
{
MSG msg;

while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);

if(msg.message == WM_QUIT)
break;
}
else
{
mImmediateContext->ClearRenderTargetView(mRenderTargetView, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
mImmediateContext->ClearDepthStencilView(mZBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0);

if (mFrameListener)
if (!mFrameListener->OnRenderStart())
break;

mSwapChain->Present(0, 0);
}
}
}
Instead of responding to input directly in your WndProc, collect a list of active keys. Update this list whenever you get a KEYUP or KEYDOWN message. Then, in your game logic, check the list of currently-pressed keys and update your camera position each game frame using that information. Should solve your problem.

More details here if you're interested.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Sorry i should have said so, but i already tried to add the 'else' statement. Didn't work.

EDIT: ApochPiQ, yes i know i can do that. I was just wondering why WndProc behaves like i described. Am i doing it wrong or what?
"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "

Sorry i should have said so, but i already tried to add the 'else' statement. Didn't work.


:(, you still should process all of your windows messages every frame =p

This topic is closed to new replies.

Advertisement