2015-03-31 113 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