2017-02-01 5 views
1

私は私のゲームのすべてのプレイヤーを繰り返し処理するforループを持っています。次回の反復の前に、現在のプレイヤーに3分の選択を許可したい(これはキャンバスマウスイベントです)。私が試したすべてがエラーなしで私のアプリをクラッシュさせます。私はこれについて何が起こっているのかという手がかりがなく、何時間も続いてきました。私は間違って何をしていますか?thread.sleepがJavaFXアプリケーションをクラッシュさせるのはなぜですか?

startGame.addEventHandler(MouseEvent.MOUSE_CLICKED, 
       new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent e) { 

       gameStatus = "Started"; 
       players.add(new Player(0, "Amrit")); 
       players.add(new Player(1, "Tyler")); 
       players.add(new Player(2, "Scott")); 
       players.add(new Player(3, "Ryker")); 

       //Select first two settlements with one road extending from each 
       for (int s = 0; s < 2; s++) { 

        for (int p = 0; p < players.size(); p++) { 

         phase = "Pick Settlements"; 
         playerTurn = p; 

         //Loop through all tiles 
         for (int t = 0; t < tiles.length; t++) { 

          //Loop through the vertices of the current tile 
          for (int v = 0; v < tiles[t].vertices.length; v++) { 

           drawCircle(gc, new Point(tiles[t].vertices[v].x, tiles[t].vertices[v].y), (int) (windowHeight * .05), true, true, "rgba(255, 238, 144, .3)", 0); 

          } 

         } 

         gc.setFill(Color.web("0xFFEB8A")); 
         gc.strokeText(players.get(p).name + ", please place your first settlement!", windowHeight * .95, windowWidth * .85); 
         selected = false; 
         canvas.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { 
          // @Override 
          @Override 
          public void handle(final MouseEvent event) { 
           if (!pointClicked().equals(0)) { 
            players.get(playerTurn).settlementsAvail--; 
            selected = true; 
           } 
          } 

         }); 

         try 
         { 
          Thread.sleep(1000 * 60 * 3); 
         } 
         catch(InterruptedException er) 
         { 
          // this part is executed when an exception (in this example InterruptedException) occurs 
         } 
        } 

       } 

       gameStatus = "Ended"; 

      } 

     }); 
+0

実際のクリックハンドラーでスリープ状態にしてもよろしいですか?そうすれば、プログラム全体(または少なくともユーザーとのやりとり)がかなりの期間ロックされることになります。実際の例外とエラーメッセージを投稿してください。 – luk2302

+0

申し訳ありませんが、これについてはっきりしていませんが、startGameハンドラは、クリックハンドラ(キャンバス)とは別のものです。キャンバスのクリックハンドラは少し下にあります。 – ShoeLace1291

答えて

0

あなたはFXアプリケーションスレッドで眠っています。これによりGUI全体がフリーズされ、ユーザーの入力を処理できなくなります。代わりTimeLineのいずれかを使用する:

Timeline timer = new Timeline(   
     new KeyFrame(Duration.seconds(60 * 3), event -> finishedSleeping()) 
); 
timer.play(); 

またはJavaFXのTask

Task<Void> timer = new Task<Void>() { 
    @Override 
    protected Void call() throws Exception { 
     try { 
      Thread.sleep(1000 * 60 * 3); 
     } catch (InterruptedException e) {} 
     return null;  
    } 
}; 
timer.setOnSucceeded(event -> finishedSleeping()); 
new Thread(timer).start(); 

この例の睡眠でFXアプリケーション・スレッドとは異なるスレッドで起こります。 finishedSleeping()は、3分が経過するとFXアプリケーションスレッドで呼び出されます。

+0

最初の方法では、アプリはもうクラッシュしませんが、タイマーは何もしません。すべて正常に続きます。 2番目の方法はエラーが出ます。具体的には、次のように入力します。タスクはパラメータを取らず、メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません。 – ShoeLace1291

+0

@ ShoeLace1291 2番目のアプローチでは、javafx.concurrent.Taskをインポートする必要があります。どちらの方法もうまくいくはずです。 'timer.play()/ new Thread(timer).start(); 'と呼ばれる場所から、この例の' finishedSleeping() 'が呼び出されるまで約3分かかります。もちろん、ループの代わりに、現在コード中に待機している3分の最後に到達するのを処理するイベントハンドラ( 'event - > finishedSleeping()')を実装する必要があります。 – Calculator

+0

最初の方法では、もともと間違ったタスククラスをインポートしました。しかし、上記の方法のいずれも、何もしません。すべてがすぐに実行されます。 – ShoeLace1291

関連する問題