2017-10-18 90 views
0

沒關係,所以我正在進行一場桌上游戲。 第一個'while循環'檢查遊戲是否結束,內部'while循環'應該等待用戶輸入(squareSelector和rooSelector是我的mouselisteners,'k'和's'是應該輸入的被聽衆返回) 然而,'while循環'崩潰了我的程序並阻止了我的偵聽器工作。 我讀了這個,發現swing是單線程的,所以我的聽衆在whileloop處於活動狀態時無法工作。不過,我需要等待輸入,以避免空指針。 關於如何解決這個問題的任何想法? (如在一個不同的方法,或者如何使我的循環等待輸入)雖然循環阻止我的聽衆工作

的gameloop

while(currentPlayer.haveIWon() == false){ 
     //wait for input 
     while(!inputIsDone){ 
      System.out.println("waiting for move"); 
      System.out.println(squareSelector.isDone() + " " + rooSelector.isDone()) ; 
      checkInput() ; 
      if(squareSelector.isDone() && rooSelector.isDone()){ 
       inputIsDone = true ; 
      } 
     } 
     //update board 
     currentPlayer.performMove(k, s); 
     rooSelector.setDone(false); 
     squareSelector.setDone(false); 
     inputIsDone = false ; 
     //currentPlayer.setInput(false); 
     //repaint 
     Main.getState().getComponent().repaint(); 

    } 
    //display winnner thing 

的checkInput方法

public void checkInput(){ 
    if(rooSelector.getSelected() != null){ 
     k = rooSelector.getSelected() ; 
    } 
    if(squareSelector.getSelected() != null){ 
     s = squareSelector.getSelected() ; 
    } 
} 

如果你需要更多的代碼來了解這是怎麼回事讓我知道,我會添加更多。

+0

不應該阻止[事件調度線程](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html)。 - 問題在於你的循環阻止了EDT處理輸入事件。遊戲循環(如果有必要的話)應該在其自己的線程中運行(例如通過[SwingWorker](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html))。 – Thomas

+0

在cheking輸入明智的循環包括一種方法來防止通過飢餓殺死他人的Thread:Thread.yield()或Thread.sleep(1) – Doleron

+0

一般來說,遊戲不會不斷更新其UI(即沒有動畫)或世界(即不是「實時」)很少需要遊戲循環。你聲明你需要一個來防止NPE,但是這意味着設計缺陷或編碼錯誤,而不是真正需要循環。 – Thomas

回答

0

Swing是單線程的。由於其設計,與GUI相關的所有內容都必須在Swing線程上完成,也稱爲事件分派線程。它基本上做了一件事:看事件隊列,如果有某事,它會處理它,如果沒有,就進入睡眠狀態。每個鼠標移動,按鍵,重畫等都是事件隊列中的事件。

如果您的遊戲只對GUI事件做出反應並且沒有冗長的操作,則不必使用任何特殊的操作。你可以在沒有while的情況下編寫你的邏輯,以便它不會阻塞,只對事件做出反應。但是,這種可能性完全取決於您正在嘗試實施的內容。

如果您有任何長時間阻塞該線程的操作,則需要爲此使用單獨的線程。這樣,其他線程不會影響您的GUI,但您需要非常小心地將數據從一個線程發送到另一個線程,或者在另一個線程上調用某些線程。