【问题标题】:SDL Event QueueSDL 事件队列
【发布时间】:2013-12-16 20:41:08
【问题描述】:

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

【问题讨论】:

    标签: c++ event-handling sdl keyboard-events


    【解决方案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”次。

    【讨论】:

    • 首先感谢您的回答。实际上发生的事情是它逃脱了循环。因为正如我所说,它在 while 循环中运行良好。我的问题之一是为什么以及如何发生这种情况。
    • 它转义了 while 循环,因为即使您的键盘重复率很高,您也最多每百毫秒左右就会收到一个新的键事件(每秒 10 个键事件,但我认为它是通常是低得多的利率)。与此同时,队列大部分是空的(给予或接受一些鼠标事件),所以 while 循环结束。如果您使用“if”(而不是“while”)逐个删除事件,则可能会在渲染时累积一堆事件,从而在您停止按键时看到“延迟移动”效果。跨度>
    • 你能解释一下为什么这个比率很低吗? SDL 是否故意这样做是来自操作系统吗?
    • 我不认为 SDL 涉及重复率,这是一个操作系统设置。从谷歌的快速搜索来看,它似乎每秒最多可以使用 30 个键,具体取决于操作系统和键盘类型。那是每 33 毫秒发生一次事件,有足够的时间让您的循环摆脱“while”条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2012-07-10
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    相关资源
    最近更新 更多