SDL 事件队列



我有以下代码是某些在屏幕上移动点的功能的一部分。我正在使用 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 鼠标事件的处理速度不够快

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

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

这将确保您的事件循环运行时间不超过 10 毫秒。或者你可以有一个计数器,确保你运行不超过"x"次迭代。

相关内容

  • 没有找到相关文章

最新更新