簡體   English   中英

Javafx-如何延遲在文本區域中顯示新行?

[英]Javafx - How can I delay the display of a new line in my textarea?

所以我得到了我正在編寫的新游戲。 長話短說,我的GUI中有一個文本區域,可充當事件顯示器。 當您與怪物戰斗時,該文本區域用於顯示多行文字,例如“您對骨架造成3點傷害”或“骨架向您投擲火球並向您造成5點傷害”。

該代碼以某種方式工作,以使怪物在您之后進行攻擊。 因此,一旦您按下“攻擊”按鈕,在文本區域中就會同時顯示說明您所做的行和說明怪物所做的行。 就像怪物在擊中它之后就可以光速擊中您一樣。

我想做的是延遲顯示怪物線。 這樣,當我按下“攻擊”按鈕時,文本區域將顯示我所做的行,然后等待一秒鍾,然后顯示怪物的行。

我嘗試使用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(){

}

我應該在delay()中添加什么? 這是我嘗試過Thread.sleep(1000)的地方。 就像我說的那樣,這樣做導致turnPlayerBareFists()和turnMonster()的代碼在delay()之后執行。 任何幫助,將不勝感激。

我認為使用計時器是實現此目的的更好/更一致的方法。 您可以使用任何Java實現,盡管javafx本身為定時事件提供了幾種機制。

一種方法是時間線

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動畫的基礎知識(您可以在文檔中閱讀)

該博客顯示了更多有關如何完成定時任務的示例。 (注:它也使用reactFX!)

好問題! 我建議使用這樣的東西:

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()與執行代碼之間的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.Platform ,並且runLater()方法將始終將給定的Runnable發布到JavaFX線程,因此可以安全地將操縱UI的代碼傳遞給它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM