Scalafx动画计时器导致递归:可以避免吗?

时间:2017-07-01 05:37:27

标签: java scala javafx scalafx

我正在尝试制作一款使用AnimationTimer类来处理它的游戏。我的代码摘要看起来像这样:

主要类

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()
}

RestartController

@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

}

我有一些变量,如游戏级别,位于伴侣对象的某个类中,所以我想避免递归,因为如果它是递归的,它将导致该级别的结果不一致。

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

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

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

有时会+ = 2甚至更多

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

2 个答案:

答案 0 :(得分:1)

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

<强> ShootingGame

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

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

        toBeRemove
    }
}

主要类

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()
}

答案 1 :(得分:1)

尝试不回调相同的功能,而是重新初始化整个程序,如下所示:

射击游戏

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

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

        toBeRemove
    }
}

主要类

对象游戏扩展了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()
}