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

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

最佳答案

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

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

关于c++ - 使用SDL_PollEvent与SDL_PumpEvents,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56435371/

10-08 22:11