【问题标题】:Using SDL_PollEvent vs SDL_PumpEvents使用 SDL_PollEvent 与 SDL_PumpEvents
【发布时间】:2019-06-03 22:42:53
【问题描述】:

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

所以在第一个示例中,我没有刷新事件队列,那么为什么它可以在没有崩溃的情况下工作呢?第二种模式是正确获取输入状态的方式吗?

【问题讨论】:

    标签: c++ c events sdl


    【解决方案1】:

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

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

    【讨论】:

    • 这很有趣。因此,性能应该没有真正的差异,因为无论如何都会创建事件并将其保存到队列中。
    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多