2015-03-31 84 views
3

我遇到类似乒乓球的SDL 2.0键盘输入问题。当我通过按左箭头移动到左边时,如果按下一次键,它将由SDL_PollEvents()处理并正确响应。但是,如果我按住该键,则在连续移动之前会得到一个短暂延迟(只要Windows键重复延迟)。SDL 2.0按键重复和延迟

这里是函数处理事件:

void Event::PlayerEvent (Player &player) 
{ 
    while (SDL_PollEvent (&mainEvent)) 
    { 
     switch (mainEvent.type) 
     { 
      case SDL_KEYDOWN : 
       switch (mainEvent.key.keysym.sym) 
       { 
        case SDLK_ESCAPE : 
         gameRunning = false; 
         break; 
        case SDLK_LEFT : 
         player.moving = player.left; 
         break; 
        case SDLK_RIGHT : 
         player.moving = player.right; 
       } 
       break; 
      case SDL_QUIT : 
       gameRunning = false; 
     } 
    } 
} 

编辑:毕竟,我设法通过调用 SystemParametersInfo来解决这个问题(SPI_SETKEYBOARDDELAY,0,0,0),在程序和SystemParametersInfo的开始( SPI_SETKEYBOARDDELAY,1,0,0),以返回标准密钥重复延迟。

+1

看看[此](http://lazyfoo.net/tutorials/SDL/26_motion/index.php)教程。作者使用2个技巧:(1)按键影响物体速度而不是位置; (2)检测按键向上和过滤重复。所以当按键时,速度增加。一旦增加,继续按不会改变它,因此对象继续移动。当键入时,速度降低并且物体停止移动。这可能有助于解决延迟问题。 – senderj 2015-04-01 01:33:35

+0

它减少了一点延迟,但仍然不是我所期待的。 – KVASS 2015-04-01 17:44:48

+0

经过代码的一些调整之后,我必须说,这个教程是适当的解决我的问题。我摆脱了延误。非常感谢。 – KVASS 2015-04-02 20:32:17

回答

3

对于游戏移动,您通常不使用事件,而是使用状态。

尝试使用SDL_GetKeyboardState()事件循环的外面:

const Uint8* keystates = SDL_GetKeyboardState(NULL); 

... 

if(keystates[SDL_SCANCODE_LEFT]) 
    player.moving = player.left; 
else if(keystates[SDL_SCANCODE_RIGHT]) 
    player.moving = player.right; 
+0

感谢提示,我肯定会在将来使用keystates,但它没有解决关键延迟的问题。 – KVASS 2015-04-01 17:47:16

+0

即使使用SPI_SETKEYBOARDDELAY(当然,它不是跨平台的),也只能保证延迟到250ms。使用关键状态时不会有任何延迟。 如果您想毫不拖延地使用关键事件,则需要对它们做出不同的响应。在keydown上,设置运动。在关键时刻,停止运动。还要注意,你可以通过检查event.key.repeat忽略重复的关键字。 – 2015-04-02 15:19:58