Jump to content
  • Advertisement
Sign in to follow this  
Waaayoff

Input and smooth movement?

This topic is 2610 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'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?

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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);
}
}

}

Share this post


Link to post
Share on other sites
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);
}

Share this post


Link to post
Share on other sites
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);
}
}
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites

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

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!