how to save composer scene?

Hi.
I conctact you cause i need save composer scene in a button menu. I tried save it like a file but the code doesn’t run. There is another metod to save composer scene?

What do you mean by “save the composer scene”?  Do you mean save where everything is, like player position, etc.?

Yes…but my app doesn’t have a phisyc game. The scenes are static with only buttons and images.

Let me re-ask, I’m not sure what you’re goal is.  Are you wanting to save the game so that it could be resumed later, perhaps after playing another game.  Think of a Checkers game where you might be playing player A and want to save it, so you can then play the game with player B and then switch back later to play player A again?    Or is this more of a case, you want to bring up a settings screen or something and then return to where you left off?  Or be able to resume a game after someone has killed the app out of memory?

Rob

Sorry for the confusion. I exlpain better. I’ve a game like a book. Every page is a scene with composer and in every scene i want that the player can save the game. When he saved, i want that the player can read the saved page by menu, and be able resume the page also he killed app out memory.

i post an example code to explain what i would do. Here there is an example of menu game and of a scene game.

–EXAMPLE MENU GAME

local composer = require( “composer” )

local scene = composer.newScene()

local widget = require (“widget”)

W = display.contentWidth

H = display.contentHeight

–FUNCTION BUTTONS

local function handleButtonEvent( event )

    local  id = event.target.id

    if id == “button1” then

        composer.gotoScene( “quadri.quadro1” )

    elseif id == “button2” then

        print (“LOAD LAST SCENE SAVED”)

    end

end

function scene:create( event )

local group = self.view

local background = display.newImageRect (“images/background.jpg”,320,480,true)

background.x = W/2

background.y = H/2

–PLAY GAME BUTTON

local button1 = widget.newButton

{

    id = “button1”,

    label = “play game”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 200,

    height = 32,

    cornerRadius = 4,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button1.x = display.contentCenterX

button1.y = 110

–BUTTON LOAD GAME

local button2 = widget.newButton

{

    label = “load game”,

    id = “button2”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 200,

    height = 32,

    cornerRadius = 4,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button2.x = display.contentCenterX

button2.y = 180

group:insert(background)

group:insert(button1)

group:insert(button2)

end

function scene:destroy( event )

print( “destroying scenE” )

end


– Listener setup

scene:addEventListener( “create”, scene )

scene:addEventListener( “destroy”, scene )

return scene

–EXAMPLE PLAY GAME SCENE

local composer = require( “composer” )

local scene = composer.newScene()

local widget = require (“widget”)

local function scrollListener (event)

    local phase = event.phase

    local direction = event.direction

    

    if event.limitedReached then

        if “up”==direction then

            print (“limit up”)

        elseif “down”==direction then

            print (“limit down”)

        end

    end

    return true

end

–FUNCTION BUTTONS

local function handleButtonEvent( event )

     local options =

            {

                effect = “fromBottom”,

                time = 400,

            }

    local  id = event.target.id

    if id == “button1” then

        composer.gotoScene( “SCENE2”,options )

    elseif id == “button2” then

        print ( "SAVE CURRENT SCENE " )

  

    end

end

function scene:create( event )

    local group = self.view

    – SCROLLVIEW

local scrollView = widget.newScrollView

{

    left = 0,

    top = 0,

    width = display.contentWidth,

    height = display.contentHeight,

    topPadding = 50,

    bottomPadding, 50,

    horizontalScrollDisabled = true,

    verticalScrollDisabled = false,

    listener = scrollListener,

}

–TEXT

local options =

{text =  “Spiders (order Araneae) are air-breathing arthropods that have eight legs and chelicerae with fangs that inject venom. They are the largest order of arachnids and rank seventh in total species diversity among all other orders of organisms.[1] Spiders are found worldwide on every continent except for Antarctica, and have become established in nearly every habitat with the exceptions of air and sea colonization.”, 

 x = 0,

 y = 220,

 width = 298,

 font = Helvetica,

 fontSize =14,

 align = “left”

}

–BUTTON  A

local button1 = widget.newButton

{

    id = “button1”,

    label = “A”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 120,

    height = 32,

    cornerRadius = 2,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button1.x = 90

button1.y = 505

–BUTTON SAVE CURRENT SCENE

local button2 = widget.newButton

{

    label = “SAVE”,

    id = “button2”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 120,

    height = 32,

    cornerRadius = 2,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button2.x = 230

button2.y = 505

local textObject = display.newText (options)

textObject:setFillColor (0)

textObject.x = display.contentCenterX

scrollView:insert (textObject)

scrollView:insert (button1)

scrollView:insert (button2)

group:insert (scrollView)

end

function scene:destroy( event )

    print( “((destroying scene 1’s view))” )

end


– Listener setup

scene:addEventListener( “create”, scene )

scene:addEventListener( “destroy”, scene )

return scene

Rob can you aswer me, please?

I don’t see anything in the game scene to save.  About the only possibility is the scroll position of the scrollView.  I don’t see anything else that’s movable or being moved.  The scene would re-create itself  back to its defaults.

You need to ask yourself:  “What in the scene can change by some user action?”

Those things could be:

  • the X, Y of the object. 
  • the rotation of the object.
  • the alpha transparency / visibility of the object.
  • some color state
  • some other value state, like a health bar.  If the object is at 36% health you would need to save that.
  • should you recreate an object.  Think of coins in a Mario Brothers game.  Once you’ve captured the coins if you were resuming that level, you wouldn’t want to re-create the ones already captured.
  • If the game has doors/portals that are opened/closed.
  • Any inventory
  • Any score for that level
  • Any timers that would need to pick up where they left off.

The best practice there is to create a table for the level with all the things you need to save.   Then use something like:

http://coronalabs.com/blog/2014/10/14/tutorial-saving-and-loading-lua-tables-with-json/

To save a table for each level.  Then in the composer’s scene:show() function during the “will” phase, read that table and set all your objects to the values that you saved for them.  Depending on the scene and number of objects and their properties, this table could end up containing a lot of data.

local levelSaveTable = {}

levelSaveTable.bug1 = {}

levelSaveTable.bug1.x = bug1.x

levelSaveTable.bug1.y = bug1.y

levelSaveTable.bug1.health = bug1.health

etc.

Rob

What do you mean by “save the composer scene”?  Do you mean save where everything is, like player position, etc.?

Yes…but my app doesn’t have a phisyc game. The scenes are static with only buttons and images.

Let me re-ask, I’m not sure what you’re goal is.  Are you wanting to save the game so that it could be resumed later, perhaps after playing another game.  Think of a Checkers game where you might be playing player A and want to save it, so you can then play the game with player B and then switch back later to play player A again?    Or is this more of a case, you want to bring up a settings screen or something and then return to where you left off?  Or be able to resume a game after someone has killed the app out of memory?

Rob

Sorry for the confusion. I exlpain better. I’ve a game like a book. Every page is a scene with composer and in every scene i want that the player can save the game. When he saved, i want that the player can read the saved page by menu, and be able resume the page also he killed app out memory.

i post an example code to explain what i would do. Here there is an example of menu game and of a scene game.

–EXAMPLE MENU GAME

local composer = require( “composer” )

local scene = composer.newScene()

local widget = require (“widget”)

W = display.contentWidth

H = display.contentHeight

–FUNCTION BUTTONS

local function handleButtonEvent( event )

    local  id = event.target.id

    if id == “button1” then

        composer.gotoScene( “quadri.quadro1” )

    elseif id == “button2” then

        print (“LOAD LAST SCENE SAVED”)

    end

end

function scene:create( event )

local group = self.view

local background = display.newImageRect (“images/background.jpg”,320,480,true)

background.x = W/2

background.y = H/2

–PLAY GAME BUTTON

local button1 = widget.newButton

{

    id = “button1”,

    label = “play game”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 200,

    height = 32,

    cornerRadius = 4,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button1.x = display.contentCenterX

button1.y = 110

–BUTTON LOAD GAME

local button2 = widget.newButton

{

    label = “load game”,

    id = “button2”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 200,

    height = 32,

    cornerRadius = 4,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button2.x = display.contentCenterX

button2.y = 180

group:insert(background)

group:insert(button1)

group:insert(button2)

end

function scene:destroy( event )

print( “destroying scenE” )

end


– Listener setup

scene:addEventListener( “create”, scene )

scene:addEventListener( “destroy”, scene )

return scene

–EXAMPLE PLAY GAME SCENE

local composer = require( “composer” )

local scene = composer.newScene()

local widget = require (“widget”)

local function scrollListener (event)

    local phase = event.phase

    local direction = event.direction

    

    if event.limitedReached then

        if “up”==direction then

            print (“limit up”)

        elseif “down”==direction then

            print (“limit down”)

        end

    end

    return true

end

–FUNCTION BUTTONS

local function handleButtonEvent( event )

     local options =

            {

                effect = “fromBottom”,

                time = 400,

            }

    local  id = event.target.id

    if id == “button1” then

        composer.gotoScene( “SCENE2”,options )

    elseif id == “button2” then

        print ( "SAVE CURRENT SCENE " )

  

    end

end

function scene:create( event )

    local group = self.view

    – SCROLLVIEW

local scrollView = widget.newScrollView

{

    left = 0,

    top = 0,

    width = display.contentWidth,

    height = display.contentHeight,

    topPadding = 50,

    bottomPadding, 50,

    horizontalScrollDisabled = true,

    verticalScrollDisabled = false,

    listener = scrollListener,

}

–TEXT

local options =

{text =  “Spiders (order Araneae) are air-breathing arthropods that have eight legs and chelicerae with fangs that inject venom. They are the largest order of arachnids and rank seventh in total species diversity among all other orders of organisms.[1] Spiders are found worldwide on every continent except for Antarctica, and have become established in nearly every habitat with the exceptions of air and sea colonization.”, 

 x = 0,

 y = 220,

 width = 298,

 font = Helvetica,

 fontSize =14,

 align = “left”

}

–BUTTON  A

local button1 = widget.newButton

{

    id = “button1”,

    label = “A”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 120,

    height = 32,

    cornerRadius = 2,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button1.x = 90

button1.y = 505

–BUTTON SAVE CURRENT SCENE

local button2 = widget.newButton

{

    label = “SAVE”,

    id = “button2”,

    onEvent = handleButtonEvent,

    emboss = false,

    --properties for a rounded rectangle button…

    shape=“roundedRect”,

    width = 120,

    height = 32,

    cornerRadius = 2,

    fillColor = { default={ 1, 0, 0, 1 }, over={ 1, 0.1, 0.7, 0.4 } },

    strokeColor = { default={ 1, 0.4, 0, 1 }, over={ 0.8, 0.8, 1, 1 } },

    strokeWidth = 2

}

– Center the button

button2.x = 230

button2.y = 505

local textObject = display.newText (options)

textObject:setFillColor (0)

textObject.x = display.contentCenterX

scrollView:insert (textObject)

scrollView:insert (button1)

scrollView:insert (button2)

group:insert (scrollView)

end

function scene:destroy( event )

    print( “((destroying scene 1’s view))” )

end


– Listener setup

scene:addEventListener( “create”, scene )

scene:addEventListener( “destroy”, scene )

return scene

Rob can you aswer me, please?

I don’t see anything in the game scene to save.  About the only possibility is the scroll position of the scrollView.  I don’t see anything else that’s movable or being moved.  The scene would re-create itself  back to its defaults.

You need to ask yourself:  “What in the scene can change by some user action?”

Those things could be:

  • the X, Y of the object. 
  • the rotation of the object.
  • the alpha transparency / visibility of the object.
  • some color state
  • some other value state, like a health bar.  If the object is at 36% health you would need to save that.
  • should you recreate an object.  Think of coins in a Mario Brothers game.  Once you’ve captured the coins if you were resuming that level, you wouldn’t want to re-create the ones already captured.
  • If the game has doors/portals that are opened/closed.
  • Any inventory
  • Any score for that level
  • Any timers that would need to pick up where they left off.

The best practice there is to create a table for the level with all the things you need to save.   Then use something like:

http://coronalabs.com/blog/2014/10/14/tutorial-saving-and-loading-lua-tables-with-json/

To save a table for each level.  Then in the composer’s scene:show() function during the “will” phase, read that table and set all your objects to the values that you saved for them.  Depending on the scene and number of objects and their properties, this table could end up containing a lot of data.

local levelSaveTable = {}

levelSaveTable.bug1 = {}

levelSaveTable.bug1.x = bug1.x

levelSaveTable.bug1.y = bug1.y

levelSaveTable.bug1.health = bug1.health

etc.

Rob