为什么事件轮询循环中的函数触发频率低于其外部函数
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;
}
dmg 可能是正确的。
Pollevent 不只是遍历当前按下的键列表,您正在遍历要处理的事件列表,并且它只会按照您的重复率进行更新。您可能希望在内部处理按钮的状态,并通过事件打开和关闭它,处理更新中的旋转(无论如何更好地分离功能)。
我有一个自己旋转的立方体和一个在按下某个键时旋转的立方体。问题在于,自己旋转的总是比只有在按下某个键时才旋转的旋转得更快(快得多)。
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;
}
dmg 可能是正确的。
Pollevent 不只是遍历当前按下的键列表,您正在遍历要处理的事件列表,并且它只会按照您的重复率进行更新。您可能希望在内部处理按钮的状态,并通过事件打开和关闭它,处理更新中的旋转(无论如何更好地分离功能)。