c++ - SDL 事件队列

标签 c++ event-handling sdl keyboard-events

我有以下代码 是在屏幕上移动一个点的某些功能的一部分。 我正在使用 SDL

if(SDL_PollEvent(&event)){

    //BreakPoint A

    if(event.type == SDL_KEYDOWN)
        if(event.key.keysym.sym == SDLK_d){
            goLeft = true;
            //BreakPoint B
        }
    else if(event.type == SDL_KEYUP)
        if(event.key.keysym.sym == SDLK_d){
            goLeft = false;
            //BreakPoint C
        }
    else{
         //BreakPoint D
    }

}

//BreakPoint E

//Move sprites and other things..
//Update  screen ..

所有这些都在一个循环中。每次运行这个循环时,都会对点的移动进行计算并渲染一帧。 我的问题是,当我连续按 'D' 时,离开按钮后点 不会立即停止。

改变 if(SDL_PollEvent(&event)){
while(SDL_PollEvent(&event)){ 一切正常。为什么会这样?

一个假设是,通过连续按“D”,事件队列将被键盘输入事件淹没。如此多的事件被插入到事件队列中,所有这些都发生在一帧渲染或一次迭代中我在上面说过的循环,但是在每一帧上我只从队列中删除一个事件。所以当我离开'D'按钮时没有更多的事件被插入并且发生“额外”移动因为得到'D'的事件' 已被释放并更新 goLeft 变量,我必须首先删除所有那些一个一个地涌入队列的事件。因此,在这些事件被释放之前,点将移动。

但是从另一方面来说,如果我有 while(SDL_PollEvent(&event)){ 并且持续按下“D”,它会离开这个内部循环吗?因为这个循环是在队列中有事件时运行的,正如我所说,我通过按“D”连续插入它们。

编辑

正如我所说的 while 循环,它工作正常并且它实际上从循环中逃脱了。它是如何发生的?
从我所做的一些测试中,我看到当连续按下“D”时,程序在每次外部循环迭代中执行如下:

  • 断点A
  • 断点B
  • 断点A
  • 断点 C
  • 断点E

最佳答案

我想我刚刚回答了一个类似的问题:SDL mouse events are not being handled quick enough

您似乎遇到了同样的问题,即在事件循环中间等待 vsync。如果您希望事件持续触发,您可以执行以下操作:

Uint32 timeout = SDL_GetTicks() + 10;
while(SDL_PollEvent(&events) && !SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {...}

这将确保您的事件循环不会运行超过 10 毫秒。或者您可以有一个计数器并确保您不会运行超过“x”次迭代。

关于c++ - SDL 事件队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20620458/

相关文章:

c++ - 有没有办法在 C++ 中使用 SOIL 将一个纹理拆分为一组纹理?

go - SDL2 音频无法正确播放

c++ - 如何用 C++ 编写简短的文字?

c++ - 将 tf::transform 对象写入文件

c++ - 输出省略 "January"

c# - 将我自己的参数发送给事件处理程序?

iphone - 适用于 iPhone 的 SDL 有多成熟?

C++ 11 Boost 1.65 recursive_directory_iterator 给出段错误

javascript - 为什么这个事件监听器在 javascript 数组中不能用于多个键?

jQuery IE8 点击错误