2014-01-23 108 views
1

我試圖用SDL 2.0.1開發一個強大的遊戲輸入系統。我希望那裏沒有輸入滯後。SDL2密鑰重複延遲

我用SDL_GetKeyboardState()要做到這一點,但我切換到使用SDL_EventSDL_PollEvent()有鍵盤的統一接口,鼠標和遊戲杆輸入(與一切事件完成)。

這工作得很好,但如果我要當鍵被按下(例如移動一個字符)的連續輸入,則存在鍵被重複SDL通知之前稍有延遲。

在SDL 1.2中,可以使用函數調用設置此延遲。現在它不再(據我所知)。

我該如何消除這種延遲?我應該切換回直接讀取鍵盤狀態嗎?

供參考,在這裏是如何我目前越來越輸入...

SDL_Event sdlEvent; 
while (running) 
{ 
    SDL_PollEvent(&sdlEvent); 
    switch (sdlEvent.type) 
    { 
    case SDL_QUIT: 
     running = false; 
     break; 
    case SDL_KEYDOWN: 
     printf("Key down!\n"); 
     break; 
    default: 
     break; 
    } 
} 

的應用程序打印"Key down!",那麼小的時候沒有什麼(大約一秒鐘),然後反覆打印,直到關鍵發行了。

那麼我該如何擺脫這種延遲?

+0

您在此期間是否收到該密鑰的'SDL_KEYUP'事件? – olevegard

+0

不需要。在我釋放密鑰之前,它都是「SDL_KEYDOWN」事件。然後它是一個持續不斷的'SDL_KEYUP'事件流(直到我移動鼠標或按另一個鍵,所以我猜如果沒有事件,'SDL_PollEvent(&sdlEvent)'不會改變'sdlEvent')。 – RaptorDotCpp

回答

4

由於你沒有得到一個SDL_KEYUP你可以有一個booltrue直到你得到一個SDL_KEYUP

SDL_Event sdlEvent; 
while (running) 
{ 
    bool keyDown = false; 
    while (SDL_PollEvent(&sdlEvent)) 
    { 
     switch (sdlEvent.type) 
     { 
      case SDL_QUIT: 
       running = false; 
       break; 
      case SDL_KEYDOWN: 
       keyDown = true; 
       break; 
      case SDL_KEUP: 
       keyDown = false; 
       break; 
      default: 
       break; 
     } 
    } 
    if (keyDown) 
     printf("Key down!\n"); 
} 

當然還需要一些東西來存儲所有的按鍵,就像一個數組。 (或更好;使用C++std::map)然後,您可以使用SDL_Keycodeevent.key.keysym.sym)作爲關鍵。

+0

此代碼將執行相同的錯誤,即初始狀態,每個幀只檢查堆棧中的第一個事件。 – jordsti

+0

@jordsti啊......當然,沒有看到它沒有放在一個循環中 – olevegard

+0

你把我放在正確的方向。當我使用行爲(如字符串)和回調函數時,我現在保留了一組應該被解僱的操作。在keydown上,我將相關操作添加到集合中。在keyup上,我刪除它。作品完美無瑕。謝謝! – RaptorDotCpp

2

首先,您應查詢您的活動進入一個循環,否則你只會得到一個事件每幀 所以

SDL_Event sdlEvent; 
while (running) 
{ 
    while(SDL_PollEvent(&sdlEvent)) 
    { 
     switch (sdlEvent.type) 
     { 
     case SDL_QUIT: 
      running = false; 
      break; 
     case SDL_KEYDOWN: 
      printf("Key down!\n"); 
      break; 
     default: 
      break; 
     } 
    } 
} 

而且,來處理你的關鍵延遲,應該創建一個結構與按下的鍵,以及關鍵啓動時的時間戳。您可以將這些結構放入一個向量中,然後在獲取該關鍵點的鍵時刪除它們。要處理關鍵延遲,只需重複您的關鍵點,然後檢查當前時間戳和關鍵下降的初始時間戳之間的差異。

+0

時間戳的目的是什麼?只要你在收到SDL_KEYDOWN時將'bool'設置爲'true',並且在你收到'SDL_KEYUP'之前不要將它設置爲'false',那麼就不應該有延遲。 – olevegard

+0

這個 - >然後在一小段時間內(大約一秒鐘)沒有任何東西,然後重複打印直到該鍵被釋放。有了bool,它也可以工作,但只適用於一個鍵或動作,如果你想爲許多鍵做這種行爲,那就是這樣做的方法。 – jordsti

+0

只要'bool'仍然設置爲「true」,將會解決這個問題。除非我誤解,否則他不想延遲,因此不需要時間戳。 – olevegard