我已经使用SDL一段时间了,但是现在看来我在处理键盘事件时一直用错误的方式做事。
通常我的主循环看起来像这样:
int main() {
SDL_Init(SDL_INIT_VIDEO);
/* Some video system initializations */
/* Main loop */
for(;;) {
SDL_PumpEvents();
const unsigned char *key = SDL_GetKeyboardState(nullptr);
/* Do something with the keys pressed */
}
}
...这对我来说很好。但是我最近看了一些代码示例,从技术上讲,它们全部使用不同的模式:
int main() {
SDL_Init(SDL_INIT_VIDEO);
/* Some video system initializations */
/* Main loop */
for(;;) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
/* switch/case to know keys pressed */
}
}
}
因此,查看SDL文档后,我发现SDL_PollEvent
确实调用了SDL_PumpEvents
。 SDL_PollEvent reference
SDL_PumpEvents
的作用是收集所有输入设备的状态以生成事件对象。 SDL_PumpEvents reference
因此,在第一个示例中,我不是 flushing 事件队列,那么为什么它可以正常工作而不会崩溃?第二种模式是获取输入状态的正确方法吗?
答案 0 :(得分:1)
尽管PumpEvents
修改了全局键盘和鼠标状态,但其精度可能不够。考虑一下您已经在单个帧中按下,移动和释放了所有鼠标-在全局状态下,您将获得最后一个位置和“释放”状态,但没有获得第一次单击甚至单击本身的位置。键盘也一样-您会获得“最新”状态,但不会获得历史记录以及按键被按下/释放的顺序。还有很多“特殊”事件,例如窗口事件,操纵杆(SDL具有可选的背景高频线程以轮询操纵杆并将事件置于队列中),甚至还有音频设备和操纵杆的热插拔事件-如果没有这些,您将无法获得检查事件队列。
您的程序不会在溢出时崩溃,因为SDL对队列中可以存储的事件数量有上限-currently 65535。