Saving levels (only) help!

[lua]

composer.gotoScene(mySceneNameVariableFromJson)

[/lua]

There are many approaches to communicating the level to play to a scene:

  1. You can use a non-global data table that’s required in each module and scene (which is a module): http://docs.coronalabs.com/tutorial/basics/globals/index.html (which I know you’re familiar with). Simply set a table member to have the value the level to play:

    myData.currentLevel = 3

for instance.

  1. Composer has a set of API calls that performs a similar function to the non-global data table. After all when you require composer you are getting a Lua data table that’s included in your scenes. We added a .setVariable() and .getVariable() API for this:

In your scene where you select the level:

composer.setVariable("currentLevel", 3)

in the scene where you need the information:

local currentLevel = composer.getVariable("currentLevel")
  1. Composer allows you to pass parameters on the gotoScene() call:

    composer.gotoScene(“game”, { params = { currentLevel = 3 }, effect = “crossFade”, time = 500 } )

then in your scene, during the scene:create() and scene:show() events, you will have a populated table:

function scene:create( event )     local params = event.params     local currentLevel = 1     if params and params.currentLevel then         currentLevel = params.currentLevel     end     ... end

I’m sure there are other techniques as well.

Rob

thanks for your help.

I do not have a common game.lua module in wich I replace values in each level, NO.
I have 10 different modules and I’m getting errors in the composer.gotoScene()

I have a progress module:

---------------------progress.lua------------------------- --save and load last level local M = {} local composer = require( "composer" ) local json = require( "json" ) local lastLevel = composer.getVariable( "level" ) local filePath = system.pathForFile( "levels.json",   system.DocumentsDirectory ) function M.saveLevel()   if filePath then     local contents = json.encode(lastLevel)     file:write( contents )     io.close( filePath )     return true   else     return false end function M.loadLevel()   local file = io.open( filePath, "r" )   if file then     -- read all contents of file into a string     local contents = file:read( "\*a" )     lastLevel = json.decode(contents);     io.close( file )     return lastLevel   end   return nil end return M

ok, now in every scene at top I require the progress module and
set the “level” variable to level # in this example 3, but it’s
the same in level 1 and level 2.

---------------------level\_3.lua-------------------------- local progress = require( "progress" ) local physics = require( "physics" ) physics.start() composer.setVariable( "level", 3 )

I call the M.loadLevel() function in every levels#.lua scene “create”
and the M.saveLevel() function in every levels#.lua scene “show”

-- create() function scene:create( event )    progress.loadLevel() end -- show() function scene:show( event )    progress.saveLevel() end

ok, and in menu.lua following @nick said

local function gotolastLevel()  composer.gotoScene( progress.lastLevel ) end

but I’, getting this error

I am going to give it a hack since I think I understand what you want, but I am probably also wrong. 

  1. In main.lua retrieve the level from json from a file (from what I am reading I think you have that down if not you can use what Rob originally posted).

  2. From what I am also reading you have a bunch of levels called something like level1.lua, level2.lua, level3.lua. I am guessing you have a folder called levels. So from main I would call:

    local level = 2 – You would replace this with whatever code to retrieve the level from a file. composer.gotoScene(“levels.level”…level)

Just read your last post you are almost there. Use Rob’s library it won’t get any easier and the code is there.

https://github.com/robmiracle/Simple-Table-Load-Save-Functions-for-Corona-SDK

In every level scene as the scene:show save the scene number. You already know it since you are creating 1 scene per level:

local loadsave = require("loadsave") myTable = {} myTable.sceneNumber = "1" -- This would be for level 1 loadsave.saveTable(myTable, "myTable.json")

Then when you launch the app do what I did above but retrieve the scene using Rob’s library:

local loadsave = require("loadsave") local myTable = loadsave.loadTable("myTable.json") local level = (myTable.sceneNumber or 1) composer.gotoScene("levels.level"..level)

@agramonte

why in the scene:show you use global myTable and in main you use local myTable?

I am experiencing many global and local problems with myTable, I do not understand anything …

If someone can explain to me how this work I will appreciate. It’s new for me and hard to understand.

what is the roll of (t, filename, location) in function M.saveTable(t, filename, location)

do I need to chage those values?

Sorry, both should be marked Local. I just copy and pasted from the sample in the link. The t is the table you want to save.

For example:

local t = {} t.level = "1"

filename is the name of the file to save to the file system: “pref.json” or “level.json” or “whatever.txt”

And finally, location is where you want to save that file.

t = table to save

filename = name of file to save the data to

location = folder to save the file to (optional, defaults to system.DocumentsDirectory)

I suspect that @agramonte simply left the “local” off of the myTable variable.

If you’re having trouble understanding global vs. local, getting a lot of nil variables that you think shouldn’t be or things behaving weirdly there is a good chance you need to understand “scope” better. This tutorial explains it:  http://docs.coronalabs.com/tutorial/basics/scope/index.html

It’s really a simple concept once you understand what defines a block of code. It really helps if you properly indent your code so you can easily see each block of code.

Consider:

local myFirstVariable = 1 local function myFunction( ) local mySecondVariable = 2 if mySecondVariable == 2 then local myThirdVariable = 3  print( mySecondVariable ) -- prints 2 end print( myThirdVariable ) -- prints nil end

vs

local myFirstVariable = 1 local function myFunction( ) local mySecondVariable = 2 if mySecondVariable == 2 then local myThirdVariable = 3 print( mySecondVariable ) -- prints 2 end print( myThirdVariable ) -- prints nil end

The blocks of code are identical other than some formatting, but the first block is really hard to understand where one block of code begins and ends. The indentions should show you that there actually three blocks of code. One is a “main chunk” (code lined up against the left edge, a function block named myFunction() and a “if” block.

local variables can only be seen in the block they are defined and any children blocks, for instance, the “if” block is a child of the myFunction() block. The myFunction() block is a child of the main chunk. 

This means that myThirdVariable only exists and can be seen inside the “if” block. The mySecondVariable only exists inside the function and can only be seen there. But since the “if” block is a child of the function, it can also see mySecondVariable. One the “if” block is done, myThirdVariable goes away and isn’t available to the rest of myFunction().

The indenting of the code really helps you visualize what’s going on. 

Rob

Here you go a simple example. I created this from the game template. I just copied and pasted 6 scenes. Imagine they are your 6 mini-games.  There is just one button in the middle and you click and go to the next scene. Then if using the simulator you refresh, it remembers where you left off.  I am using Rob’s library.

thanks to everyone especially @agramonte. I am studying what you upload and I am understanding much better. I believe that I will soon be able to implement it.

:) 

if I want to change the image of “play button”, or replace it with a “continue button” in my menu when a .json file it’s created, the only way is to use LFS to check if myTable.json exist? or there is another comparision I can make to achieve this task?

DoDi