为什么事件轮询循环中的函数触发频率低于其外部函数

Why does the function in the event polling loop trigger less frequently than the function outside it

我有一个自己旋转的立方体和一个在按下某个键时旋转的立方体。问题在于,自己旋转的总是比只有在按下某个键时才旋转的旋转得更快(快得多)。

while(!quit())
{
  handleInput();
  update();
  render();
}

当我把轮换放在这里时:

update()
{
  cube.rotation += 0.09f;
}

立方体旋转得很快。
但是当我把它放在这里时:

handleinput()
{
   while(pollevent(&event))
   {
      if(event.type == keydown)
      {
        if(event.key.symbol == KEY_r )
        {
           cube.rotation += 0.09f;
        }
      }
   }

慢多了。虽然我假设当按下键时,两者都应该在每个循环中被调用一次。
而且我不知道这个问题必须标记什么。

您的 keydown 事件 触发 的频率低于您的游戏逻辑更新的频率。

一个常见的解决方案是跟踪键盘的状态。

SDL方式

我建议将键盘状态存储为布尔值数组,其大小是您要检查的键数,例如bool[SDL_KEYLAST]。 因此,每当触发事件时,您都必须修改它。最后,在每个循环中,检查保存的键盘状态。 示例代码:

handleInput()
{
    while(pollEvent(&ev))
    {
        if(event.type = keydown)
            ks[event.key.symbol] = true;
        else if(event.type = keyup)
            ks[event.key.symbol] = false;
    }
}

update()
{
    if(ks[KEY_R]) cube.rotation += 0.05f;
}

SDL2 方式

const Uint8* ks = SDL_GetKeyboardState(NULL).

此函数 returns 键盘状态数组,它不是 bool[] 而是 Uint8[] 包含 0/1 值(因此您仍然可以检查 false/true值)。

但是,如果您想使用该数组,您还必须检查 SDL_Scancode 索引值,这些索引值在此处列出:https://wiki.libsdl.org/SDL_Scancode

handleinput()
{
    //pump events so that SDL can update the keyboard state array...
}

update()
{
    const Uint8* ks = SDL_GetKeyboardState(NULL);
    if(ks[SDL_SCANCODE_R]) cube.rotation += 0.05f;
}

参考:https://wiki.libsdl.org/SDL_GetKeyboardState

dmg 可能是正确的。

Pollevent 不只是遍历当前按下的键列表,您正在遍历要处理的事件列表,并且它只会按照您的重复率进行更新。您可能希望在内部处理按钮的状态,并通过事件打开和关闭它,处理更新中的旋转(无论如何更好地分离功能)。