2012-03-10 213 views
1

應該在java程序中的遊戲循環始終運行在事件派發線程中嗎? 由於我的鍵盤記錄器在AWT事件線程中運行,我希望鍵盤事件在與其餘遊戲相同的線程中處理,以避免基於線程的錯誤。 如果我不在事件線程中運行遊戲循環,我可以使用ArrayBlockingQueue將事件處理程序的事件發送到遊戲循環?有更好的解決方案嗎? 謝謝遊戲循環 - 線程

也許是這樣的?

ConcurrentLinkedQueue<AWTEvent> eventQueue = new ConcurrentLinkedQueue<AWTEvent>(); 

JFrame frame = new JFrame() { 
    @override 
    protected void processEvent(AWTEvent e) { 
     if(e instanceof InputEvent) eventQueue.add(e); 
     else super.processEvent(e); 
    } 
} 

//game loop 
while(true) { 
    while(!eventQueue.isEmpty()) frame.super.processEvent(eventQueue.poll()); 
    ... 
} 

編輯:謝謝,我想我現在知道如何做到這一點。我會做這樣的

import java.util.concurrent.ConcurrentLinkedQueue; 
import java.awt.AWTEvent; 
import java.awt.Dimension; 
import java.awt.event.*; 
import javax.swing.*; 

public class QueueTest { 

    static ConcurrentLinkedQueue<AWTEvent> eventQueue = new ConcurrentLinkedQueue<AWTEvent>(); 

    public static void main(String[] args) { 
     final JPanel panel = new JPanel() { 
      @Override 
      protected void processEvent(AWTEvent e) { 
       eventQueue.add(e); 
      } 
      { 
       enableEvents( AWTEvent.MOUSE_EVENT_MASK 
          | AWTEvent.MOUSE_MOTION_EVENT_MASK 
          | AWTEvent.KEY_EVENT_MASK); 
      } 
     }; 
     final JFrame frame = new JFrame(); 
     frame.addComponentListener(new ComponentAdapter() { 
      @Override 
      public void componentShown(ComponentEvent e) { 
       panel.requestFocusInWindow(); 
      } 
     }); 
     frame.add(panel); 
     panel.setPreferredSize(new Dimension(800,600)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 

     while(true) { 
      while(!eventQueue.isEmpty()) System.out.println(eventQueue.poll()+"\n"); 
     } 
    } 
} 

回答

1

我不是一個遊戲程序員,所以你的問題促使一些研究:)因爲它是它自己的循環您不能運行在事件調度線程遊戲圈服務用戶輸入。你的應用程序基本上會凍結並且不會對任何進一步的輸入事件作出響應。你的遊戲循環應該是一個單獨的線程,並且有一個線程安全的隊列用於遊戲事件 - 隊列應該是非阻塞的,因爲即使沒有用戶輸入,你也希望遊戲循環繼續。任何你需要作爲輸入結果的渲染可能必須放回到事件隊列中 - 擺動爲此提供SwingUtilities,雖然不確定你在哪個環境。

我可能會被有經驗的遊戲開發者現在。

+0

其實,我決定不告訴OP同樣的事情,因爲我沒有在遊戲編程方面的經驗。但我認爲可以肯定地說,他不能將「遊戲循環」放在事件隊列中,希望沒有人會與此爭論。 – arcy 2012-03-10 03:51:07

1

我在我寫的遊戲引擎中遇到過類似的問題。

最後,我不得不爲我的遊戲引擎循環設置一個單獨的線程。當AWT事件被解僱時,我必須存儲它們,並在遊戲循環內的下一次邏輯更新期間將它們解僱。

這是我的解決方案,然而,我相信事件的'最簡單'的事情是要真正的輪詢他們! :)