使用SDL_PollEvent与SDL_PumpEvents

时间:2019-06-03 22:42:53

标签: c++ c events sdl

我已经使用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_PumpEventsSDL_PollEvent reference

SDL_PumpEvents的作用是收集所有输入设备的状态以生成事件对象。 SDL_PumpEvents reference

因此,在第一个示例中,我不是 flushing 事件队列,那么为什么它可以正常工作而不会崩溃?第二种模式是获取输入状态的正确方法吗?

1 个答案:

答案 0 :(得分:1)

尽管PumpEvents修改了全局键盘和鼠标状态,但其精度可能不够。考虑一下您已经在单个帧中按下,移动和释放了所有鼠标-在全局状态下,您将获得最后一个位置和“释放”状态,但没有获得第一次单击甚至单击本身的位置。键盘也一样-您会获得“最新”状态,但不会获得历史记录以及按键被按下/释放的顺序。还有很多“特殊”事件,例如窗口事件,操纵杆(SDL具有可选的背景高频线程以轮询操纵杆并将事件置于队列中),甚至还有音频设备和操纵杆的热插拔事件-如果没有这些,您将无法获得检查事件队列。

您的程序不会在溢出时崩溃,因为SDL对队列中可以存储的事件数量有上限-currently 65535