winapi - 同时多键按下释放延迟

标签 winapi input

我正在开发 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/

相关文章:

c++ - 如何从 QWebView 中的输入字段获取值

winapi - Win32 在父窗口中捕获子窗口消息

windows - 获取 winapi 中窗口的最后一个 ShowWindow 状态

windows - TIME_ZONE_INFORMATION 结构中的 Microsoft 时区名称是否已翻译?

python - 文件夹上的备用数据流

javascript - 单独的 radio 输入,在正确的输入后面 append 一个 div

c++ - Vulkan 创建实例 VK_OUT_OF_HOST_MEMORY

c - 用户在 C 中输入 int 文件得到 'Access violation'

html - Google Chrome <input/> 自动填充背景颜色在版本 72.0 中是否发生了变化?

javascript - jQuery 在 remove() 之后检查输入是否存在