我正在开发 2D 游戏并面临需要同时检测多个按键按下/释放的问题,例如,角色对角线移动。
问题是当我“同时”(它与我的 react 无关我按下/释放非常快)按下/释放多个(两个)键消息之间的延迟通常比单帧(16ms with VSync
),例如,它可以达到 50-100 毫秒,因此角色开始单向移动,并且仅在稍微延迟对角线之后(如预期的那样)。
WinAPI
消息是正常的还是硬件限制?是否可以更快地检测输入或游戏如何处理输入?
唯一有点帮助的解决方案是在游戏逻辑中处理具有周期性延迟(例如每 100 毫秒)的输入,但这会大大牺牲控制响应能力。
我正在 while 循环中发送 WinAPI WM_KEYDOWN
/WM_KEYUP
消息。
while (PeekMessage(&message, 0, 0, 0, PM_REMOVE))
DispatchMessage(&message);
我还尝试使用 GetMessage
将输入与渲染线程分开分派(dispatch)。
延迟测量测试项目:pastebin
实际 OpenGL
对角线运动测试项目:pastebin
最佳答案
直接的答案是肯定的,在通过普通 Windows 消息队列处理按键时,50 毫秒左右的延迟很常见。我相信这些延迟有多种来源。
首先,键盘本身有一个串行接口(interface)。从历史上看,这是非常慢的,并且可能与底层 55 毫秒时钟有关。 USB 键盘可能会快得多,但关键是每个单独的按键按下或释放都将单独发送和处理,即使它们看起来绝对是同时的。
导致处理 Windows 消息的 Windows 代码路径很长,中间消息的流量可能很高。如果有许多消息要处理,您同时释放的键可能会被许多其他消息分开。在一定程度上,您可以通过查看消息而不是等待它们来减少这种情况。
所以您真的必须使用原始输入,您将需要快速处理事件,并且您仍然需要预测延迟。我的猜测是您将需要将您的输入“去抖动”到至少 20 毫秒的曲调以获得流畅的行为。那里有很多读物可以帮助您前进。
关于winapi - 同时多键按下释放延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22392683/