2013-12-16 71 views
1

我有以下代码,其中 是一些在屏幕上移动点的功能的一部分。 我使用SDLSDL事件队列

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 .. 

所有这一切都是在loop.Each时间,此环跑,计算正在取得点的移动和帧渲染。 我的问题是,当我连续按'D',离开按钮后,点 不会立即停止。

更改if(SDL_PollEvent(&event)){
while(SDL_PollEvent(&event)){ 事情Ok.Why会出现这种情况?

一个假设是,通过连续按'D'键事件队列正在被键盘输入事件泛滥。因此,许多这些事件被插入到事件队列中,并且所有这些事件都发生在一帧渲染或一个迭代我上面说过的循环,但是在每一帧我只从队列中删除一个事件。因此,当我离开'D'按钮时不再插入事件并且发生“额外”移动,因为得到' D'已经发布并且更新了goLeft变量,我必须首先删除所有那些一个接一个地泛滥队列的事件。所以直到那些被释放的小点才会移动。

但从另一方面,如果我有while(SDL_PollEvent(&event)){和'D'不断按下它将永远离开这个内部循环?因为此循环在队列中有事件时运行,并且正如我所说的,我通过按'D'连续插入它们。

编辑

当我用while循环表示它工作得很好,它实际上逃脱从loop.How不会发生?
和一些测试,我已经做了,我看到按“d”时不断地在程序上的每个外部循环迭代的执行过程如下:

  • 断点
  • 断点乙
  • 断点
  • 断点ç
  • 断点Ë

回答

1

我瘦我刚才已经回答了类似的概率lem: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)) {...} 

这将确保您的活动循环不超过10ms.Or更多的运行,你可以有一个计数器,并确保你不运行超过“x”次迭代。

+0

首先感谢您的回答。 实际上发生的是它逃脱了循环。因为正如我所说的,它在while循环中工作正常。 我的问题的一部分是为什么发生这种情况。 –

+0

它逃避了while循环,因为即使你有很高的键盘重复率,你至少每隔百毫秒就会得到一个新的关键事件(每秒10个关键事件,但我认为它通常是低得多的速率)。与此同时,队列大部分是空的(给予或接受几个鼠标事件),所以while循环结束。如果您使用“if”(而不是“while”)逐个移除事件,则可能会在渲染时堆积一堆事件,从而导致您停止按键时看到的“延迟移动”效果。 – gabomdq

+0

你能解释为什么这个比率很低? SDL是否故意从操作系统中执行它? –