导致递归的 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()
}
我正在尝试制作一个使用 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()
}