2017-07-16 75 views
1

所以我得到了這個我編碼的新遊戲。長話短說,我的GUI中有一個textarea,它充當事件顯示器。當你與怪物戰鬥時,這個textarea用來顯示文字,如「你對骨骼造成3點傷害」或「骨架對你施放火球並擊中你5點傷害」。Javafx - 我如何推遲在我的textarea中顯示新行?

該代碼的作用方式使怪物在你身後發作。因此,只要你點擊「攻擊」按鈕,你就可以在文本區同時顯示你所做的事情和說出怪物的行。就好像這個怪物在你擊中它後立即以光速擊中你。

我想要做的就是延遲怪物線的顯示。所以當我點擊「攻擊」按鈕時,textarea會顯示我所做的事情,然後等待一秒鐘,然後顯示怪物的行。

我嘗試過使用Thread.sleep()方法,但它所做的只是暫停UI 1秒,然後兩行出現在textarea中。

private void attackBareFists() { 

    if (initPJ > enemyINIT) { // Player has more initiative -> 
           // Player attacks first 
     turnPlayerBareFists(); // This method will display the player's line 

     if (!endTurn()) { // endTurn() checks that the player or the monster 
          // are still alive before continuing the fight 
      delay(); 
      turnMonster(); // This method will display the monster's line 
      endTurn(); 
     } 
    } ... // The code continues, but it's the same as above except monster attacks first 
} 

/** 
* Wait for some time 
*/ 
private void delay(){ 

} 

我應該把什麼延遲()?這是我試過Thread.sleep(1000)的地方。就像我說的那樣,這樣做會導致在delay()之後執行turnPlayerBareFists()和turnMonster()的代碼。任何幫助,將不勝感激。

回答

0

好問題!我建議使用這樣的事情:

public static void delay(long delayMs, Runnable toRun){ 
    Thread t = new Thread(() ->{ 
     try { Thread.sleep(delayMs); }catch(InterruptedException ignored){} 
     Platform.runLater(toRun); 
    }); 
    t.setDaemon(true); 
    t.start(); 
} 

這種方式,你可以指定究竟有多長的延遲應該調用delay(),當你之間的代碼應該執行。本質上,你傳遞一個Runnable作爲方法的第二個參數,其中包含你想要運行的任何代碼。

例如,這將意味着你的怪物的回合會被這樣表示:

if(!endTurn()) 
    delay(1000,()->{ turnMonster(); endTurn(); }); 

如果由於某種原因,你不想使用lambda表達式(即「() - > 「的東西),你可以使用這個:

public static void delay(long delayMs, Runnable toRun){ 
    Thread t = new Thread(new Runnable(){ 
     public void run(){ 
      try { Thread.sleep(delayMs); }catch(InterruptedException ignored){} 
      Platform.runLater(toRun); 
     } 
    }); 
    t.setDaemon(true); 
    t.start(); 
} 

而且你的怪物的代碼應該是這樣的:

if(!endTurn()) 
    delay(1000, new Runnable(){ public void run(){ turnMonster(); endTurn(); } }); 

如果您想知道,Platform指的是javafx.application.PlatformrunLater()方法將始終將給定的Runnable發佈到JavaFX線程,因此可以安全地將它傳遞給操縱UI的代碼。

+0

謝謝!這工作完全按照我的意願!非常感謝你! – NZoth

2

我認爲一個更好/更一致的方式來實現這一點是通過使用計時器。你可以使用任何java實現,儘管javafx本身爲定時事件提供了幾種機制。

一種方法是Timeline

Timeline timeline = new Timeline(new KeyFrame(
    Duration.millis(1000), 
    ae -> doSkellyTurn()), 
    new KeyFrame(
    Duration.millis(1000 + 1000), // as mentioned by fabien, the time offset is relative to the 'start()' method, not to its previous keyframe! 
    ae -> endSkellyTurn())); 
timeline.play(); 

以上方式也基本爲javafx animations (as you can read in the documentation)

This blog顯示瞭如何完成任務的定時一些更多的例子。 (Ps。它也使用reactFX!)

+0

@fabien好點,我編輯了相應 – n247s