这是一个相当不寻常的问题,但我需要对Win32如何处理不同的keydown事件进行一些解释。
当你想要接受长按时,使用 WM_KEYDOWN
,例如如果你在游戏中,并且想要向前移动,则按向上箭头键或“W”键,游戏中的角色继续前进。
由于WM_KEYDOWN
。
我有一个基于win32的3D OpenGL应用程序,我在其中使用'W-A-S-D'和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);
答案 0 :(得分:5)
在win32应用程序上处理循环的正常消息调用两个函数:
TranslateMessage(&msg);
DispatchMessage(&msg);
第一个函数TranslateMessage
查看虚拟键消息(例如WM_KEYDOWN
个消息),然后如果按下的键对应于字符键,则将字符消息添加到消息队列中。如果按住'W'
键,由于自动重复功能,会生成大量WM_KEYDOWN
。箭头键也是如此,但在'W
'的情况下,对于每个WM_KEYDOWN
,还会生成WM_CHAR
,您的应用程序必须处理该WM_CHAR
。
即使您的应用程序只是查看WM_KEYDOWN
并丢弃它们,结果延迟也可能会很明显,尤其是因为每次处理WM_KEYDOWN
时都会移动相机
有关详细信息,请查看this。
解决方案:
您应该使移动速度与处理输入的速度无关。有两种主要方法:
在这两种情况下,在处理输入时都不会移动角色。相反,当您playerIsMoving
设置布尔true
到false
时},并在获得WM_KEYUP
时将其重置为true
。然后,仅当变量位于TranslateMessage
。
<强> [UPDATE] 强>
看到你的主循环后: 尝试修改它:
修改1 :注释掉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;
}
。除非你想在你的应用程序中使用文本框等,否则你不需要它。
修改2 :添加单独的函数以更新世界状态。
{{1}}