导致递归的 Scalafx 动画计时器:可以避免这种情况吗?

Scalafx animation timer causing recursive : Possible to avoid that?

我正在尝试制作一个使用 class AnimationTimer 来处理它的游戏。我的代码摘要如下所示:

主要Class

object Game extends JFXApp{

    def showMenu{
        //code that show the .fxml layout and controller will handle the controller
    }

    def showInstruction{
        //code that show the .fxml instruction
    }

    def showGame():Unit = {
        this.roots.center = {
            new AnchorPane(){
                children = new Group(){

                    val timer:AnimationTimer = AnimationTimer(t=> {
                        //game code

                        if(playerDie){
                            timer.stop
                            val gameOver:AnimationTimer = AnimationTimer(t => {
                                if(exitPressed){
                                    showMenu
                                } else if (restartPressed){
                                    restartGame
                                }
                            })
                            gameOver.start
                        }
                    })
                    timer.start
                }
            }
        }
    }

    def restartGame(){
        //show restart layout
    }

    showMenu()
}

重启控制器

@sfxml
class RestartController(private val countDownLabel:Label){
    var lastTimer:Double = 0
    var countDownSec:Double = 5.999
    val countDown:AnimationTimer = AnimationTimer(t => {
        val delta = (t-lastTimer)/1e9
        if(delta < 1) countDownSec -= delta
        countDownLabel.text = countDownSec.toInt.toString
        if(countDownSec <= 0) {
            countDown.stop
            Game.showGame
        }
        lastTimer = t
    })//end AnimationTimer pauseTimer
    countDown.start

    //I think Game.showGame should be located at here but tried several ways still can't implement it

}

我有一些变量,例如位于伴生对象中某些 class 的游戏关卡,所以我想避免递归,因为如果它递归会导致关卡的结果不一致。

当玩家死亡时,如果用户退出,用户将显示菜单,如果玩家再次按下开始游戏,则不会显示伴随对象中那些变量的任何不一致。

但是,如果播放器按下重启,它将进入递归,这意味着该方法调用另一个方法,因此旧方法没有结束并说如果我这样做

ShootingGame.level += 1 //be trigger when certain requirement meet

有时会+=2甚至更多

是否有任何解决方案使其不递归,这与我退出游戏时的行为完全一样,而旧的 showGame() 方法将在我开始新游戏之前完全结束??

我通过不回调相同的函数解决了这个问题,而是重新初始化了整个程序,如下所示:

射击游戏

class ShootingGame{
    def restart:ListBuffer[Circle] = {
        var toBeRemove:ListBuffer[Circle]

        //initialize and add those needed to be remove into toBeRemove

        toBeRemove
    }
}

主要Class

object Game extends JFXApp{

    def showMenu{
        //code that show the .fxml layout and controller will handle the controller
    }

    def showInstruction{
        //code that show the .fxml instruction
    }

    def showGame():Unit = {
        this.roots.center = {
            new AnchorPane(){
                children = new Group(){

                    val timer:AnimationTimer = AnimationTimer(t=> {
                        //game code

                        if(playerDie){
                            timer.stop
                            val gameOver:AnimationTimer = AnimationTimer(t => {
                                if(exitPressed){
                                    showMenu
                                } else if (restartPressed){
                                    for(i <- game.restart) children.remove(i)
                                    timer.start
                                }
                            })
                            gameOver.start
                        }
                    })
                    timer.start
                }
            }
        }
    }

    showMenu()
}

尽量不要回调同一个函数,而是重新初始化整个程序,如下所示:

射击游戏

class ShootingGame{
    def restart:ListBuffer[Circle] = {
        var toBeRemove:ListBuffer[Circle]

        //initialize and add those needed to be remove into toBeRemove

        toBeRemove
    }
}

主要Class

对象游戏扩展 JFXApp{

    def showMenu{
        //code that show the .fxml layout and controller will handle the controller
    }

    def showInstruction{
        //code that show the .fxml instruction
    }

    def showGame():Unit = {
        this.roots.center = {
            new AnchorPane(){
                children = new Group(){

                    val timer:AnimationTimer = AnimationTimer(t=> {
                        //game code

                        if(playerDie){
                            timer.stop
                            val gameOver:AnimationTimer = AnimationTimer(t => {
                                if(exitPressed){
                                    showMenu
                                } else if (restartPressed){
                                    for(i <- game.restart) children.remove(i)
                                    timer.start
                                }
                            })
                            gameOver.start
                        }
                    })
                    timer.start
                }
            }
        }
    }

    showMenu()
}