2017-02-01 4 views
1

У меня есть цикл for, который повторяется через всех игроков в моей игре. Перед следующей итерацией я хочу разрешить текущему игроку 3 минуты сделать выделение (это событие холста mouseclick). Все, что я пробовал, отключает мое приложение без ошибок. Я был в этом часами, не понимая, что происходит. Что я делаю не так?Почему 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. Это заморозит весь ваш графический интерфейс, что затруднит обработку пользовательских входов. Вместо того, чтобы использовать либо 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() будет вызван в поток приложений FX через 3 минуты.

+0

С первым методом приложение перестает работать, но таймер ничего не делает. Все продолжается как обычно. Что касается второго метода, я получаю ошибки. В частности: type Task не принимает параметры, и метод не переопределяет или не реализует метод из супертипа – ShoeLace1291

+0

@ ShoeLace1291 Вам нужно импортировать 'javafx.concurrent.Task' для второго подхода. Оба метода должны работать нормально. С момента, когда вы вызываете 'timer.play()/новый поток (таймер) .start();' он должен занять около 3 минут, пока не будет вызван 'законченныйSleeping()' в этом примере. Конечно, вместо цикла, который у вас есть в коде, вам нужно реализовать обработчик событий ('event -> finishedSleeping()'), который обрабатывает до истечения 3 минут ожидания. – Calculator

+0

Хорошо, поэтому первым методом я импортировал неправильный класс Task. Но ни один из вышеперечисленных методов ничего не делает. Все сразу выполняется. – ShoeLace1291

Смежные вопросы