2011-03-07 67 views
2

我寫了一個簡單的程序與SFML的OpenGL其中提請,可以在屏幕上用箭頭鍵移動的紡紗方。重複按鍵事件阻塞

它可以在我測試過的所有Linux和Mac電腦上正常工作,但是當我嘗試移動Windows上的方塊時(通過按住箭頭鍵),它移動一小段距離然後停止移動並旋轉。我很確定該程序陷入了GetEvent方法 - 我的猜測是,當我將按鍵按下足夠長時間以使其重新開始時,事件堆棧會不斷添加新事件,然後才能彈出所有內容關閉它(如果我把Windows的密鑰重複率降到最低,那麼問題就會消失 - 儘管我不太喜歡這個解決方案)。

我發現按住Alt,Ctrl,Delete,Page Up,Page down,Home,End等等都會導致此行爲(即使我沒有在程序中檢測到任何這些鍵),但所有字母鍵,以及空格鍵,退格鍵和鍵盤箭頭鍵都可以正常工作(即,如果我將它們按住太久,它們不會導致程序暫停)。

我沒有確切的代碼(我只是把我的筆記本電腦關閉),但它看起來像:

while(running) { 
    while(app.GetEvent(event)) 
     if(event.Type==sf::Event::Closed) running=false; 
    if(input.IsKeyDown(sf::Key::Right)); // move right 
    // etc etc 
    // update rotation 
    // draw everything 
} 

任何想法,以什麼確切的問題可能是,我如何可以修復它?

+0

您是否曾嘗試在布爾值中存儲關鍵狀態,然後根據布爾狀態來執行邏輯?所以。 。 。 。 。 if(input.IsKeyDown(sf :: Key :: Right))right = true; 。 。 。 。 。 。如果(right)moveRight(); – epaik 2011-04-08 20:48:50

回答

3

我知道這是一個古老的問題,但我想回答它以幫助其他可能遇到類似問題的人。

SFML 1.6有兩種方法可以從用戶那裏獲得輸入。一種是基於事件的處理,其中處理通過sf::Window::GetEvent()發送給您的每個事件。另一種是基於查詢的,您可以直接查看窗口的sf::Input類。

你已經在這裏使用了基於查詢的方法,但把它放在一個事件循環中,而這個事件循環並不是它打算使用的方式。這是爲了像這樣使用。這是一個很好的功能,因爲SFML自動爲您保留一個布爾鍵表,所以您不需要自己管理鍵狀態。恕我直言,使用重複輸入這是更優雅,因爲你不會垃圾郵件你的事件隊列,只是檢查一個布爾值。

while(app.GetEvent(event)) 
    if(event.Type == sf::Event::Closed) running=false; 
    if(event.Type == sf::Event::KeyPressed && event.Key.Code == sf::Key::Right) 
    { 
     // move right 
    } 
} 

如果你想在只查詢SF ::直接輸入,那麼你使用相同的代碼同上,但你把它的事件循環外。

while(app.GetEvent(event) 
{ 
} 

if (myWindow.GetInput().IsKeyDown(sf::Key::Right)) 
{ 
} 

默認情況下自動按鍵重複應該爲SF :: Windows上啓用,但您可以通過使用sf::Window::EnableKeyRepeat(true)確保。這意味着它將在按住按鍵的同時重複發送KeyPressed事件。

嘗試在主事件循環之外使用基於查詢的方法,看看它是否適用於您。

+0

這個'sf :: Window :: EnableKeyRepeat(true)'的末尾剛剛回答了我的問題。謝謝你的細節。 – 2013-07-26 15:29:38