SDL2 似乎每 50 毫秒才轮询一次输入

SDL2 only seems to poll input every 50ms

我注意到 SDL2 似乎只在大约 50 毫秒内轮询输入。

例如,如果我像这样轮询事件就是我的主循环

SDL_Event event;
while(SDL_PollEvent(&event)){
    if(event.type == SDL_KEYDOWN || event.type == SDL_KEYUP){
         inputs.push_back(...);
    }
}

对于某些帧,输入向量实际上是空的。只有当我在我的主循环中使用 SDL_Delay(50) 时,我才能避免得到一个空的输入向量。

我可以强制 SDL2 以低于 50 毫秒的速度更新输入吗?

这与SDL 没有任何关系。 SDL 是 PeekMessage 等函数的包装器,SDL 无法 return 比这些底层特定于平台的函数具有更高分辨率的事件。实际的硬件轮询速率将由 OS 管理,通常低于 10 毫秒,有时低至 1 毫秒。

这个名字可能有点误导,因为 SDL_PollEvent 实际上并不轮询硬件。相反,硬件轮询作为操作系统功能的正常部分在后台连续发生。 SDL_PumpEvents 将事件从 OS 事件队列移动到 SDL 事件队列。 SDL_PollEvent 将事件从 SDL 事件队列移至您自己的应用程序。因此,将 SDL_PollEvent 视为轮询 OS 队列而不是轮询您的实际硬件。

看来这里的问题是误会了。 SDL_KEYDOWN事件并不表示键按下,它表示键变为或已按下"repeating" .重复率可通过 OS 的控制面板进行配置。所以如果我按下一个键,按住它,然后松开它,我会得到一系列这样的事件:

SDL_KEYDOWN  pressed the key
SDL_KEYDOWN  repeat #1, after the repeat delay
SDL_KEYDOWN  repeat #2, quickly afterwards
SDL_KEYDOWN  repeat #3, quickly
...          ...
SDL_KEYUP    released the key

你会想要这样的东西:

switch (event.type) {
case SDL_KEYDOWN:
    key_pressed = true;
    break;
case SDL_KEYUP:
    key_pressed = false;
    break;
}

或者您可以使用 SDL_GetKeyboardState