2017-10-18 3 views
0

大丈夫ですので、私はボードゲームに取り組んでいます。 最初の 'whileループ'は、ゲームが終了したかどうかをチェックし、内側の 'whileループ'はユーザーの入力を待つことになっています(squareSelectorとrooSelectorは自分のマウスリストです。リスナーによって返される) しかし、 'whileループ'はプログラムをクラッシュさせ、リスナーの動作をブロックします。 これについて読んだところ、スイングはシングルスレッドであることがわかったので、whileループがアクティブな間はリスナーは動作しません。しかし、私はnullpointersを避けるために入力を待つ必要があります。 これを解決する方法に関するアイデアはありますか? (別のアプローチのように、またはどのように入力のための私のループ待ち時間を作るために)whileループが私のリスナーの仕事を妨げている

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

入力を賢明にするには、飢餓によって他人を殺すのを防ぐ方法が含まれています:Thread.yield()またはThread.sleep(1) – Doleron

+0

一般的にUI(つまりアニメーションなし) (すなわち、「リアルタイム」ではない)ゲームループはめったに必要ありません。 NPEを防止する必要があると主張していますが、ループの実際の必要性よりもむしろ設計上の欠陥またはコーディングエラーを示しています。 – Thomas

答えて

0

スイングはシングルスレッドです。その設計上、GUIに関連するすべてのものは、イベントディスパッチスレッドとも呼ばれるSwingスレッド上で実行されなければなりません。それは基本的に1つのことを行います:イベントキューを調べ、何かがあればそれを処理し、そうでなければスリープ状態になります。すべてのマウス移動、キー押下、再描画などは、実際にはイベントキュー内のイベントです。

ゲームがGUIイベントに反応し、操作時間が長くない場合は、特別な操作は必要ありません。 whileを使わずにロジックを書くことができるので、ブロックされず、イベントにしか反応しません。しかし、この可能性は完全にあなたが実装しようとしているものに依存します。

スレッドを長時間ブロックする操作がある場合は、スレッド用に別のスレッドを使用することをお勧めします。このように、他のスレッドが行うことはあなたのGUIには影響しませんが、あるスレッドから別のスレッドにデータを送信するか、別のスレッドで何かを呼び出すことに非常に注意する必要があります。

関連する問題