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