Storyboard.removeAll() seems not working - images remain on top

Hi,

I’m developing a simple game (my first one) which has several scenes. The first one shows a logo, and the second one shows the game menu. The game Works fine in corona simulator, android and xcode emulator, but in iOS devices it doesn’t.

The problem: After the first scene is shown, a logo image remains on top despite second scene (the menu) is executed, avoiding user can see the menu. Despite menu.lua (second scene) executes a storyboard.removeAll() the logo (shown in first scene - loadapp.lua) remains on top.

I’ve tries different approaches like removing logo images or using alpha property, but they don’t work. what am i doing wrong? any ideas? As I mentiones before this problema is only present in iOS device version.

main.lua code

–Initial Settings
display.setStatusBar( display.HiddenStatusBar ) --Hide status bar from the beginning

– Import sqlite and storyboard
local sqlite3 = require(“sqlite3”)
local storyboard = require “storyboard”

storyboard.purgeOnSceneChange = true --So it automatically purges for us

–Create a database table for holding the high scores in.
local dbPath = system.pathForFile(“gamedata.db3”, system.DocumentsDirectory)
local db = sqlite3.open( dbPath ) 

local tablesetup = [[
  CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY,
                                       sound_on,
                                       music_on,
                                       game_rush);
  INSERT INTO settings VALUES (1, ‘1’, ‘1’,‘0’ );
 ]]
db:exec( tablesetup ) --Create it now.

local tablescores = [[
  CREATE TABLE IF NOT EXISTS scores (id INTEGER PRIMARY KEY,
                                       score);
 ]]
db:exec( tablescores ) --Create it now.
db:close() --Then close the database

–Now change scene to go to the menu.
storyboard.gotoScene( “loadapp”, “fade”, 400 )  – loads first scene

loadapp.lua (first scene)

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()

–controls
local backgroundImg
local menutimer


– *** STORYBOARD SCENE EVENT FUNCTIONS ***

function scene:createScene( event )
    local screenGroup = self.view
       
    backgroundImg = display.newImageRect(“images/logo.png”,480,320)
    backgroundImg.x = display.contentCenterX; backgroundImg.y = display.contentCenterY

    screenGroup:insert(backgroundImg)
   
    – Cambia al MainMenu screen
    local gotoMainMenu = function()
        display.remove(backgroundImg)
        backgroundImg = nil
        storyboard.gotoScene(“menu”,“crossFade”, 400)
    end
   
    menutimer = timer.performWithDelay( 3000, gotoMainMenu, 1 )  – after 3secs displays menu scene
   
end

function scene:enterScene( event )
end

function scene:exitScene( event )
    – cancel timer
    timer.cancel( menutimer ); menutimer = nil;
end

function scene:destroyScene( event )
end


– Add the story board event listeners

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )
scene:addEventListener( “destroyScene”, scene )


menu.lua (second scene)

module(…,package.seeall)

–Start off by requiring storyboard and creating a scene.
local storyboard = require( “storyboard” )
local scene = storyboard.newScene()

  • visible controls
    local displayGroup = display.newGroup( )
    local buttons = display.newGroup( )
    local playBtn
    local optionsBtn
    local creditsBtn
    local backgroundImg
    local logo

– *** STORYBOARD SCENE EVENT FUNCTIONS ***

function scene:createScene( event )
    local screenGroup = self.view

    --Background image…
    backgroundImg = display.newImageRect( “images/background1.png”, 480,320)
    backgroundImg.x = display.contentCenterX
    backgroundImg.y = display.contentCenterY
    displayGroup:insert(backgroundImg)

    logo = display.newImageRect( “images/logo.png”, 278 * 1.20,185 * 1.20)
    logo.x = display.contentCenterX; logo.y = 115
    displayGroup:insert(logo)

   – Play button
    local onPlayTouch = function()
       local optionsscr =
        {
            effect = “crossFade”,
            time = 400
        }
        storyboard.gotoScene(“game”, optionsscr)
    end    
   
    playBtn = display.newImageRect(“images/playOn.png”, 90, 90 )                     
    playBtn:setReferencePoint( display.CenterReferencePoint);
    playBtn.x = display.contentCenterX
    playBtn.y = 250
    buttons:insert( playBtn )
    playBtn:addEventListener(“touch”, function(event) onPlayTouch() end)

    – Settings button
    local onSettingsTouch = function()
                                                  
        local optionsscr =
        {
            effect = “crossFade”,
            time = 400
        }
        storyboard.gotoScene(“gamesettings”, optionsscr)
    end    
       
    optionsBtn = display.newImageRect(“images/settingsOn.png”, 75, 75)
    optionsBtn:setReferencePoint( display.CenterReferencePoint )
    optionsBtn.x = 100
    optionsBtn.y = 250
    buttons:insert( optionsBtn )
    optionsBtn:addEventListener(“touch”, function(event) onSettingsTouch() end)

    – Credits button
    local onCreditsTouch = function()
        local optionsscr =
        {
            effect = “crossFade”,
            time = 400
        }
       storyboard.gotoScene(“gamecredits”, optionsscr)
    end    

    creditsBtn = display.newImageRect(“images/creditsOn.png”, 75, 75)
    creditsBtn:setReferencePoint( display.CenterReferencePoint )
    creditsBtn.x = 380
    creditsBtn.y = 250  
    buttons:insert( creditsBtn )
    creditsBtn:addEventListener(“touch”, function(event) onCreditsTouch() end)

end

– Called immediately after scene has moved onscreen:
– Start timers/transitions etc.
function scene:enterScene( event )
    local screenGroup = self.view
    storyboard.removeAll( )

    buttons.alpha = 1
    displayGroup.alpha = 1
    screenGroup:insert(displayGroup)
    screenGroup:insert(buttons)
end

function scene:exitScene( event )
end

function scene:destroyScene( event )     
end


– Add the story board event listeners

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )
scene:addEventListener( “destroyScene”, scene )

–Return the scene to storyboard.
return scene

Hi, Dont you have displaygroup:insert instead of screenGroup:insert(logo) Cheers Atanas

Thanks Atanas, I followed your advice by changing loadapp.lua but the problem remains. I enabled storyboard.isDebug and I get this warning every times I change scene: “No scenes were purged”

code modified (loadapp.lua):

–controls
local displayGroup = display.newGroup( )
local backgroundImg
local menutimer


– *** STORYBOARD SCENE EVENT FUNCTIONS ***

function scene:createScene( event )
    local screenGroup = self.view
       
    backgroundImg = display.newImageRect(“images/logoadviafront.png”,480,320)
    backgroundImg.x = display.contentCenterX; backgroundImg.y = display.contentCenterY

    displayGroup:insert(backgroundImg)
   
    – Cambia al MainMenu screen
    local gotoMainMenu = function()
        display.remove(backgroundImg)
        backgroundImg = nil
        storyboard.gotoScene(“menu”,“crossFade”, 400)
    end
   
    menutimer = timer.performWithDelay( 3000, gotoMainMenu, 1 )
   
    screenGroup:insert(displayGroup)
end

Ah, Then try to put the global variables as local into the createscene or set them to nil to release the references to them

Thanks again.

I’ve tried two approaches:

1.setting to nil in exitScene

function scene:exitScene( event )
    – cancel timer
    timer.cancel( menutimer ); menutimer = nil;
    backgroundImg:removeSelf()
    backgroundImg = nil
    displayGroup:removeSelf()
    displayGroup = nil

end

2.setting to nil just before calling storyboard.gotoScene(“menu”,“crossFade”, 400)

    local gotoMainMenu = function()    

        backgroundImg:removeSelf()
        backgroundImg = nil
        displayGroup:removeSelf()
        displayGroup = nil

        storyboard.gotoScene(“menu”,“crossFade”, 400)
    end

But none of them seems to work.

I’m concerned about the warning in the console saying “no scenes were purged” is there any tool to debug the storyboard?

I just validated the warning “no scenes were purged” appears in corona simulator also, however, in iOS devices the previous scene images remains frozen on top of the new scene.

With storyboard, all display objects that you want storyboard to manage must be inserted into the scene’s view.  At the top of each of the four main storyboard functions reads:

      local screenGroup = self.view

This makes sceneGroup the group you must insert things into if you wish to have storyboard manage items.  You of course can put things into a different group if you wish, as long as you insert that group into the screenGroup.

This has little to do with calling removeScene() as the symptom of things staying on the screen is very likely to be failure to get them in the right group. 

Thanks Rob for your comments.

I’ve implemented the suggested code, but the behavior is the same, of course i;m doing something wrong.

The attached three images shows the output of the code below.

Code will display scene1.jpg, but when the App goes to menu scene (scene2.jpg), a frozen version of scene1 (scene1-frozen.jpg) remains on top, overlying the menu scene.

Code (loadapp.lua) looks like this (I’ve implemented Rob suggestion):

–controls
local menutimer

local cx = display.contentCenterX
local cy = display.contentCenterY

function scene:createScene( event )
    local screenGroup  = self.view
      
    local logo =display.newText(“This text gets frozen”, 0, 0, “Luckiest Guy”, 30 )
    logo:setFillColor( 1 )
    logo.x = cx; logo.y = cy

    screenGroup :insert(logo)
  
    – Cambia al MainMenu screen
    local gotoMainMenu = function()
        screenGroup:removeSelf()
        screenGroup =nil
        local options =
        {
            effect = “crossFade”,
            time = 400,
        }      
        storyboard.gotoScene(“menu”, options)
    end
  
   menutimer = timer.performWithDelay( 3000, gotoMainMenu, 1 )
end

 

Don’t do this:

        screenGroup:removeSelf()
        screenGroup =nil

This is removing the sceneGroup before storyboard can transition things away.  Since the group is destroyed Storyboard can’t go through the group and remove the items as it should.

Rob

Just a quick question. Is the fact that the images are removed from the screen a guarantee that the memory was freed?

>>Just a quick question. Is the fact that the images are removed from the screen a guarantee that the memory was freed?

Not necessarily - the images can be hiding behind the scenes. You can use storyboard.isDebug = true; and print the memory consumed before entering each scene to see if it stays consistent

hi, I just found the issue.

Fow some reason (which I don’t know) I had “antialias” setting on true. I removed (for newbied recycling code like me see this url http://forums.coronalabs.com/topic/32777-anti-alias-disabled/). 

I removed it and it worked fine.

Thanks a lot to all for their help.

olman

Hi, Dont you have displaygroup:insert instead of screenGroup:insert(logo) Cheers Atanas

Thanks Atanas, I followed your advice by changing loadapp.lua but the problem remains. I enabled storyboard.isDebug and I get this warning every times I change scene: “No scenes were purged”

code modified (loadapp.lua):

–controls
local displayGroup = display.newGroup( )
local backgroundImg
local menutimer


– *** STORYBOARD SCENE EVENT FUNCTIONS ***

function scene:createScene( event )
    local screenGroup = self.view
       
    backgroundImg = display.newImageRect(“images/logoadviafront.png”,480,320)
    backgroundImg.x = display.contentCenterX; backgroundImg.y = display.contentCenterY

    displayGroup:insert(backgroundImg)
   
    – Cambia al MainMenu screen
    local gotoMainMenu = function()
        display.remove(backgroundImg)
        backgroundImg = nil
        storyboard.gotoScene(“menu”,“crossFade”, 400)
    end
   
    menutimer = timer.performWithDelay( 3000, gotoMainMenu, 1 )
   
    screenGroup:insert(displayGroup)
end

Ah, Then try to put the global variables as local into the createscene or set them to nil to release the references to them

Thanks again.

I’ve tried two approaches:

1.setting to nil in exitScene

function scene:exitScene( event )
    – cancel timer
    timer.cancel( menutimer ); menutimer = nil;
    backgroundImg:removeSelf()
    backgroundImg = nil
    displayGroup:removeSelf()
    displayGroup = nil

end

2.setting to nil just before calling storyboard.gotoScene(“menu”,“crossFade”, 400)

    local gotoMainMenu = function()    

        backgroundImg:removeSelf()
        backgroundImg = nil
        displayGroup:removeSelf()
        displayGroup = nil

        storyboard.gotoScene(“menu”,“crossFade”, 400)
    end

But none of them seems to work.

I’m concerned about the warning in the console saying “no scenes were purged” is there any tool to debug the storyboard?

I just validated the warning “no scenes were purged” appears in corona simulator also, however, in iOS devices the previous scene images remains frozen on top of the new scene.

With storyboard, all display objects that you want storyboard to manage must be inserted into the scene’s view.  At the top of each of the four main storyboard functions reads:

      local screenGroup = self.view

This makes sceneGroup the group you must insert things into if you wish to have storyboard manage items.  You of course can put things into a different group if you wish, as long as you insert that group into the screenGroup.

This has little to do with calling removeScene() as the symptom of things staying on the screen is very likely to be failure to get them in the right group. 

Thanks Rob for your comments.

I’ve implemented the suggested code, but the behavior is the same, of course i;m doing something wrong.

The attached three images shows the output of the code below.

Code will display scene1.jpg, but when the App goes to menu scene (scene2.jpg), a frozen version of scene1 (scene1-frozen.jpg) remains on top, overlying the menu scene.

Code (loadapp.lua) looks like this (I’ve implemented Rob suggestion):

–controls
local menutimer

local cx = display.contentCenterX
local cy = display.contentCenterY

function scene:createScene( event )
    local screenGroup  = self.view
      
    local logo =display.newText(“This text gets frozen”, 0, 0, “Luckiest Guy”, 30 )
    logo:setFillColor( 1 )
    logo.x = cx; logo.y = cy

    screenGroup :insert(logo)
  
    – Cambia al MainMenu screen
    local gotoMainMenu = function()
        screenGroup:removeSelf()
        screenGroup =nil
        local options =
        {
            effect = “crossFade”,
            time = 400,
        }      
        storyboard.gotoScene(“menu”, options)
    end
  
   menutimer = timer.performWithDelay( 3000, gotoMainMenu, 1 )
end

 

Don’t do this:

        screenGroup:removeSelf()
        screenGroup =nil

This is removing the sceneGroup before storyboard can transition things away.  Since the group is destroyed Storyboard can’t go through the group and remove the items as it should.

Rob