SDL事件队列

时间:2013-12-16 20:41:09

标签: 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'时,程序会在每次外部循环迭代中执行,如下所示:

  • BreakPoint A
  • BreakPoint B
  • BreakPoint A
  • BreakPoint C
  • BreakPoint E

1 个答案:

答案 0 :(得分:1)

我很瘦,我刚回答了类似的问题: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”次。