这是一个非常不寻常的问题,但我需要解释一下Win32如何处理不同的按键事件。
当您想要接收长按压时,可以使用WM_KEYDOWN,例如,如果您在游戏中,而您想向前移动,则按下箭头键或'W‘键,游戏中的字符将继续前进。您不必多次按键,因为有WM_KEYDOWN。
我有一个3D OpenGL应用程序,基于win32,在这个应用程序中,我使用‘world’和arrow key在3D世界中移动。他们俩的工作方式都和他们应该做的一样。
尽管如此,当我身处3D世界时,我可以感觉到Win32处理WASD和箭头键的方式之间有着微妙的区别。
case UP_k:
f_zPosition-=CAM_MOVEMENT_SPEED;
break; 同样的代码也用于case 'W':。
但在游戏中,由于某种原因,箭头键所做的移动要比WASD键的移动平稳得多。
WASD的移动像箭头键一样平滑。我想知道是否有人在Win32中注意到这一点,这是我的事件循环代码,按照注释中的要求。
do
{
window.displayGL();
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
TranslateMessage(&msg);
DispatchMessage (&msg);
}while(msg.message != WM_QUIT);发布于 2014-05-26 05:17:59
win32应用程序上的普通消息处理循环调用两个函数:
TranslateMessage(&msg);
DispatchMessage(&msg);第一个函数,TranslateMessage查看虚拟密钥消息(例如WM_KEYDOWN消息),然后如果按下的键对应于字符键,则将字符消息添加到消息队列中。如果按下'W'键,就会生成大量的WM_KEYDOWN,因为它具有自动重复功能。箭头键也是如此,但是在'W‘的情况下,对于每个WM_KEYDOWN也会生成一个WM_CHAR,您的应用程序必须对其进行处理。
即使您的应用程序只是查看WM_CHAR并丢弃它们,由此产生的延迟也可能是显而易见的,特别是因为每次处理WM_KEYDOWN时都会移动摄像机。
有关更多信息,请查看这。
解决方案:
你应该使你的运动速度独立于你处理输入的速度。有两种主要方法可以做到这一点:
在这两种情况下,当您处理输入时,不会移动您的字符。相反,当您得到WM_KEYDOWN时,将布尔型playerIsMoving设置为true,并在得到WM_KEYUP时将其重置为false。然后,只有在变量在true中时,才会在生成下一个帧时应用该移动。
更新
看到主循环之后:尝试像这样修改它:
修改1:注释掉TranslateMessage。你不需要它,除非你想在你的应用程序中有文本框之类的东西。
修改2:添加一个单独的函数来更新世界状态。
do
{
UpdateWorld()
window.displayGL();
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
//TranslateMessage(&msg);
DispatchMessage (&msg);
}while(msg.message != WM_QUIT);
// I won't define exactly all of this, you can get an idea
// what I'm doing by the names. playerIsMoving should be set
// and reset in the `WindowProcedure` when processing 'WM_KEYDOWN/UP':
void UpdateWorld(){
float delta = timeSinceLastCall()
if(playerIsMoving)
player.pos += speed * delta;
}https://stackoverflow.com/questions/23862825
复制相似问题