我有以下代码 是在屏幕上移动一个点的某些功能的一部分。 我正在使用 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/