When running my “game” it will run fine the first time, and then again the second time, but not the 3rd time around. What would cause something like this to happen? I made sure it purged the scenes when I left them.
TBH there’s a whole variety of reasons why this might happen. What actually happens ?
Sounds to me like something is not getting cleaned up properly, or you are cleaning up and a chunk is not re executing. Purging the scene will cause the main chunk to not be re executed the next time around.
Here is the full code. Like I said its pretty basic…
main.lua
[lua]display.setStatusBar(display.HiddenStatusBar)
local storyboard = require(“storyboard”)
storyboard.gotoScene(“game”)[/lua]
game.lua
[lua]display.setStatusBar(display.HiddenStatusBar)
local storyboard = require(“storyboard”)
local scene = storyboard.newScene()
score = 0
highScore = 0
function scene:createScene(event)
local sceneGroup = self.view
local background = display.newImageRect(“hay.jpg”,1000,2000)
background.x = display.contentCenterX
background.y = display.contentCenterY
sceneGroup:insert(background)
local button = display.newImageRect(“start.png”,400,200)
button.x = display.contentCenterX
button.y = display.contentCenterY
sceneGroup:insert(button)
function missed(event)
if event.phase == “began” then
storyboard.gotoScene(“restart”)
storyboard.purgeScene(“game”)
end
return true
end
function clicked(event)
if event.phase == “began” then
score = score + 1
print(score)
end
return true
end
background:addEventListener(“touch”,missed)
button:addEventListener(“touch”,clicked)
end
function scene:enterScene(event)
end
scene:addEventListener(“createScene”,scene)
return scene[/lua]
restart.lua
[lua]display.setStatusBar(display.HiddenStatusBar)
local storyboard = require(“storyboard”)
local scene = storyboard.newScene()
highscore = 0
function scene:createScene(event)
local sceneGroup = self.view
local background = display.newImageRect(“hay.jpg”,1000,2000)
background.x = display.contentCenterX
background.y = display.contentCenterY
sceneGroup:insert(background)
local button = display.newImageRect(“start.png”,400,200)
button.x = display.contentCenterX
button.y = display.contentCenterY
sceneGroup:insert(button)
background:addEventListener(“touch”,missed)
button:addEventListener(“touch”,clicked)
if score >= highScore then
highScore = score
elseif score <= highScore then
highScore = highScore
end
showScore = display.newText("High Score: " … highScore, 100,100,“Helvetica”,50)
showScore:setFillColor(0,0,0)
print(“you missed”)
print(“score reset to 0”)
score = 0
end
function clicked(event)
storyboard.gotoScene(“game”)
storyboard.purgeScene(“restart”)
showScore.alpha = 0
return true
end
function scene:enterScene(event)
end
scene:addEventListener(“enterScene”, scene)
scene:addEventListener(“createScene”,scene)
return scene[/lua]
It’s a bit unreadable (the formatting, not your code ). The first thing that springs to mind is you are purging scenes whilst you are still in them (e.g. in restart.lua 29/30)
Corona is event driven. So ‘gotoScene’ doesn’t actually gotoScene immediately, and return when its done. It probably does part of it and then sets up timers to run the transitions and so on and finishes it after that. It may just simply set some kind of queue that is checked on enterFrame to go to this scene. But you can’t write code that assumes either, you have to write for the actual API. So gotoScene should be viewed more as a ‘request’ to go to the scene at some point, rather than assuming it will do it *now*.
So when you ‘click’ in restart for example, it does the gotoScene() and purgeScene() and then returns to tidy up (i.e. it will send the post-scene events, whether you are listening for them or not). At this point it is still actually in the restart scene.
It’s a feature of FSMs that unless you queue up the ‘scene changes’ it is possible to get into weird sequences of messages
I don’t know how reliable the garbage collection that storyboard is (never used it) but it is supposed to be semi-automatic, e.g. it does it when it needs it. I’d be inclined to let it.
If this isn’t the problem, I’d make copy of your files and comment out all the code that isn’t actually required, to test the scene changes stand alone.
I would recommend doing your purge/remove before you do the gotoScene and purge/remove the scene you’re going to.
You are also using global variables. These are frought with errors. You can do global like things without them being global if you use the techniques in this tutorial: http://coronalabs.com/blog/2013/05/28/tutorial-goodbye-globals/
Rob
So you’re saying switch:[lua]storyboard.gotoScene(“game”)
storyboard.purgeScene(“restart”)[/lua]
to:
[lua]storyboard.purgeScene(“restart”)
storyboard.gotoScene(“game”)
[/lua]
Is that what you’re saying Rob?
No.
storyboard.purgeScene(“game”)
storyboard.gotoScene(“game”)
and
storyboard.purgeScene(“restart”)
storyboard.gotoScene(“restart”)
But when I click the button I want it to go to a new scene and remove the old one…why would i want to remove the scene and go back to the same scene?
If you were using Storyboard the way we intended, you would never purge scenes and do the code needed to manage resets without it. We cache these scenes for a reason, assuming you’re going to back to them and it’s more efficient to not have to reload all of those assets from the file system. But people struggle with this because you have to do things at right event and time.
Because this is hard for people to do, they take the short cut of blowing away the unused scenes so that they are freshly re-created when you go to them.
You really shouldn’t try and delete the scene that’s currently on the screen, so you will always have two scenes around, the one on the screen and the one you just sent off screen. Since both are going to be in memory, you can make things easy on you by purging a scene before you go to it.
Of course, if you want to auto purge things, there is a storyboard setting for this. See:
http://docs.coronalabs.com/api/library/storyboard/purgeOnSceneChange.html
Ah that makes more sense. Thanks.
TBH there’s a whole variety of reasons why this might happen. What actually happens ?
Sounds to me like something is not getting cleaned up properly, or you are cleaning up and a chunk is not re executing. Purging the scene will cause the main chunk to not be re executed the next time around.
Here is the full code. Like I said its pretty basic…
main.lua
[lua]display.setStatusBar(display.HiddenStatusBar)
local storyboard = require(“storyboard”)
storyboard.gotoScene(“game”)[/lua]
game.lua
[lua]display.setStatusBar(display.HiddenStatusBar)
local storyboard = require(“storyboard”)
local scene = storyboard.newScene()
score = 0
highScore = 0
function scene:createScene(event)
local sceneGroup = self.view
local background = display.newImageRect(“hay.jpg”,1000,2000)
background.x = display.contentCenterX
background.y = display.contentCenterY
sceneGroup:insert(background)
local button = display.newImageRect(“start.png”,400,200)
button.x = display.contentCenterX
button.y = display.contentCenterY
sceneGroup:insert(button)
function missed(event)
if event.phase == “began” then
storyboard.gotoScene(“restart”)
storyboard.purgeScene(“game”)
end
return true
end
function clicked(event)
if event.phase == “began” then
score = score + 1
print(score)
end
return true
end
background:addEventListener(“touch”,missed)
button:addEventListener(“touch”,clicked)
end
function scene:enterScene(event)
end
scene:addEventListener(“createScene”,scene)
return scene[/lua]
restart.lua
[lua]display.setStatusBar(display.HiddenStatusBar)
local storyboard = require(“storyboard”)
local scene = storyboard.newScene()
highscore = 0
function scene:createScene(event)
local sceneGroup = self.view
local background = display.newImageRect(“hay.jpg”,1000,2000)
background.x = display.contentCenterX
background.y = display.contentCenterY
sceneGroup:insert(background)
local button = display.newImageRect(“start.png”,400,200)
button.x = display.contentCenterX
button.y = display.contentCenterY
sceneGroup:insert(button)
background:addEventListener(“touch”,missed)
button:addEventListener(“touch”,clicked)
if score >= highScore then
highScore = score
elseif score <= highScore then
highScore = highScore
end
showScore = display.newText("High Score: " … highScore, 100,100,“Helvetica”,50)
showScore:setFillColor(0,0,0)
print(“you missed”)
print(“score reset to 0”)
score = 0
end
function clicked(event)
storyboard.gotoScene(“game”)
storyboard.purgeScene(“restart”)
showScore.alpha = 0
return true
end
function scene:enterScene(event)
end
scene:addEventListener(“enterScene”, scene)
scene:addEventListener(“createScene”,scene)
return scene[/lua]
It’s a bit unreadable (the formatting, not your code ). The first thing that springs to mind is you are purging scenes whilst you are still in them (e.g. in restart.lua 29/30)
Corona is event driven. So ‘gotoScene’ doesn’t actually gotoScene immediately, and return when its done. It probably does part of it and then sets up timers to run the transitions and so on and finishes it after that. It may just simply set some kind of queue that is checked on enterFrame to go to this scene. But you can’t write code that assumes either, you have to write for the actual API. So gotoScene should be viewed more as a ‘request’ to go to the scene at some point, rather than assuming it will do it *now*.
So when you ‘click’ in restart for example, it does the gotoScene() and purgeScene() and then returns to tidy up (i.e. it will send the post-scene events, whether you are listening for them or not). At this point it is still actually in the restart scene.
It’s a feature of FSMs that unless you queue up the ‘scene changes’ it is possible to get into weird sequences of messages
I don’t know how reliable the garbage collection that storyboard is (never used it) but it is supposed to be semi-automatic, e.g. it does it when it needs it. I’d be inclined to let it.
If this isn’t the problem, I’d make copy of your files and comment out all the code that isn’t actually required, to test the scene changes stand alone.
I would recommend doing your purge/remove before you do the gotoScene and purge/remove the scene you’re going to.
You are also using global variables. These are frought with errors. You can do global like things without them being global if you use the techniques in this tutorial: http://coronalabs.com/blog/2013/05/28/tutorial-goodbye-globals/
Rob
So you’re saying switch:[lua]storyboard.gotoScene(“game”)
storyboard.purgeScene(“restart”)[/lua]
to:
[lua]storyboard.purgeScene(“restart”)
storyboard.gotoScene(“game”)
[/lua]
Is that what you’re saying Rob?
No.
storyboard.purgeScene(“game”)
storyboard.gotoScene(“game”)
and
storyboard.purgeScene(“restart”)
storyboard.gotoScene(“restart”)
But when I click the button I want it to go to a new scene and remove the old one…why would i want to remove the scene and go back to the same scene?
If you were using Storyboard the way we intended, you would never purge scenes and do the code needed to manage resets without it. We cache these scenes for a reason, assuming you’re going to back to them and it’s more efficient to not have to reload all of those assets from the file system. But people struggle with this because you have to do things at right event and time.
Because this is hard for people to do, they take the short cut of blowing away the unused scenes so that they are freshly re-created when you go to them.
You really shouldn’t try and delete the scene that’s currently on the screen, so you will always have two scenes around, the one on the screen and the one you just sent off screen. Since both are going to be in memory, you can make things easy on you by purging a scene before you go to it.
Of course, if you want to auto purge things, there is a storyboard setting for this. See:
http://docs.coronalabs.com/api/library/storyboard/purgeOnSceneChange.html