How do I lock levels with storyboard

I have fifteen levels and i want to do a level lock system so when a user quits and comes back they can play the appropriate level and not have to start from the beginning.

I tried using ego and ice but I couldn’t figure it out. Does anyone have any suggestions on how they would go about doing it? tnx [import]uid: 75779 topic_id: 25923 reply_id: 325923[/import]

Why not simply add a table to the storyboard object so it will be passed to the different scenes:

storyboard.isLevelLocked = {}  
  
for i = 1, 15 do  
 storyboard.isLevelLocked[i] = true  
end  

Then to unlock a level:

storyboard.isLevelLocked[level] = false  

To test it see if the level is locked:

if storyboard.isLevelLocked[level] then  
 -- do code for a locked level  
else  
 -- do code for an un-locked level  
end  

[import]uid: 19626 topic_id: 25923 reply_id: 104935[/import]

I believe i can do that. One question would it still work if the user turned off the phone and came back to the game the next day or would it reset.

Also the storyboard.isLevelLocked table would be created in the main.lua file correct? [import]uid: 75779 topic_id: 25923 reply_id: 104955[/import]

This is something I’m working on now for my game, Blender… I’m using a settings json file stored in system.DocumentsDirectory…

Good info here:
http://blog.anscamobile.com/2012/02/reading-and-writing-files-in-corona/
http://blog.anscamobile.com/2011/08/tutorial-exploring-json-usage-in-corona/

Essentially I’m:

  1. Checking to see if the settings file exists, if not (new user), create the empty file

  2. If contents of this file are empty, populate user settings with a default table of data

  3. or… if user has played, use the decoded json data to get user settings data

  4. Update your display based on this data…

Then, as user plays and completes a level, write to this settings file with updated data (table encoded with json.encode())

Hope that helps! [import]uid: 131038 topic_id: 25923 reply_id: 104956[/import]

You could create the isLevelLocked in any storyboard scene file or main.lua, where ever it makes the most sense.

This makes no attempt to save that information between sessions, so you would have to take additional steps to save the information and on start up, see what the settings were and reestablish the current game state.
[import]uid: 19626 topic_id: 25923 reply_id: 104958[/import]

@natedicken

I need to learn this json. When you use it do have a separate module with the json function in it? [import]uid: 75779 topic_id: 25923 reply_id: 105072[/import]

Rob,

you mention that “This makes no attempt to save that information between sessions, so you would have to take additional steps to save the information and on start up, see what the settings were and reestablish the current game state.”

i was trying to use ice to store values, but i wasn’t able to store it in the icebox. any links you could provide on how to save storyboard scenes sessions ???

thanks [import]uid: 17701 topic_id: 25923 reply_id: 105796[/import]

I have no idea why ICE wouldn’t work. But if you want a super simple way to save any Lua table (probably shouldn’t save display objects… but):

http://omnigeek.robmiracle.com/2012/02/23/need-to-save-your-game-data-in-corona-sdk-check-out-this-little-bit-of-code/

I’ve been putting those two functions in my main.lua like this:

local storyboard = require "storyboard"  
local json = require( "json" )  
  
function saveTable(t, filename)  
 local path = system.pathForFile( filename, system.DocumentsDirectory)  
 local file = io.open(path, "w")  
 if file then  
 local contents = json.encode(t)  
 file:write( contents )  
 io.close( file )  
 return true  
 else  
 return false  
 end  
end  
   
function loadTable(filename)  
 local path = system.pathForFile( filename, system.DocumentsDirectory)  
 local contents = ""  
 local myTable = {}  
 local file = io.open( path, "r" )  
 if file then  
 print("trying to read ", filename)  
 -- read all contents of file into a string  
 local contents = file:read( "\*a" )  
 myTable = json.decode(contents);  
 io.close( file )  
 print("Loaded file")  
 return myTable  
 end  
 print("file not found")  
 return nil  
end  
  
storyboard.loadTable = loadTable  
storyboard.saveTable = saveTable  
  

I then try to read my “settings.json” file. If that fails, then I will set my initial settings and then write the settings table out to “settings.json”.

  
storyboard.settings = storyboard.loadTable("settings.json")  
if storyboard.settings == nil then -- didn't load the table  
 storyboard.settings = {}  
 storyboard.settings.musicOn = true  
 storyboard.settings.soundFX = true  
 storyboard.highScore = 0  
 storyboard.saveTable(storyboard.settings, "settings.json")  
end  
  

At this point, I have added my load and save functions to storyboard. I have also added a table called “settings” to storyboard as well. These will be passed to every storyboard scene.

Now within any given scene, if I change one of the settings:

  
 storyboard.settings.highScore = playerScore  
 storyboard.saveTable("settings.json")  
  

I can quickly update my settings and save them. Any other scene will see the changes since they are part of the storyboard object.

All of my games have a “gamesettings.lua” file that I use to allow the players to turn music and sound on and off, etc.

Since I’m dealing with settings files, I only need to load the settings in main.lua but I need to save them in lots of place. So in theory I don’t need to add the loadTable function to storyboard, but you might have other uses, like having a separate high score file, that you might want to load and save in other settings.

In your case, I would save your level lock data to your settings and use this method to save the state of your level load screen out and be able to read it back when you start up the program.
[import]uid: 19626 topic_id: 25923 reply_id: 105833[/import]

Rob,

thanks for the great code and sample. it does work.

i was just wondering a few things.

  1. if i created a storyboard.score = 0

and then i wanted to add lets say 25 to it would i do it like this

storyboard.settings.score = storyboard.settings.score + 25
storyboard.saveTable(“settings.json”)

  1. how would i get the score to output into the screen and also the terminal.

when i do the print (storyboard.settings.score) i get a nil value.

thanks again

I’ve been trying to use ice for scoring and i got stuck with the text not being updated with the new value from scene to scene. so I’m giving this method a try [import]uid: 17701 topic_id: 25923 reply_id: 107305[/import]

Glad it’s working for you. [import]uid: 19626 topic_id: 25923 reply_id: 107319[/import]

Rob,

good news got it working by adding settings. before the highscore.

storyboard.settings = storyboard.loadTable("settings.json")  
if storyboard.settings == nil then -- didn't load the table  
 storyboard.settings = {}  
 storyboard.settings.musicOn = true  
 storyboard.settings.soundFX = true  
 storyboard.settings.highScore = 100  
 storyboard.saveTable(storyboard.settings, "settings.json")  
end  
print ("the HIGHscore is:", storyboard.settings.highScore)  

now i gotta see if i can add to it as well [import]uid: 17701 topic_id: 25923 reply_id: 107309[/import]

thanks again.

how do i go about displaying the highscore on screen?

i just got the code working to update

storyboard.settings.highScore = storyboard.settings.highScore + 75 storyboard.saveTable(storyboard.settings, "settings.json") [import]uid: 17701 topic_id: 25923 reply_id: 107320[/import]

There are a bunch of different ways, but basically I create a text object:

local highScoreText = display.newText(string.format("%07d", storyboard.settings.highScore), 0, 0, "Helvetica", 48)  
highScoreText.x = display.contentWidth - 150  
highScoreText.y = 48)  
group:insert(highScoreText)  

then later to update it:

highScoreText.text = string.format("%07d",storyboard.settings.highScore)  

[import]uid: 19626 topic_id: 25923 reply_id: 107336[/import]

thanks for the code.

i did get a error

Runtime error
…s/emanouel/CoronaProjects/H/main.lua:69: attempt to index global ‘group’ (a nil value)
stack traceback:
[C]: ?
…s/emanouel/CoronaProjects/H/main.lua:69: in main chunk
Runtime error: …s/emanouel1979/CoronaProjects/Haunted House/main.lua:69: attempt to index global ‘group’ (a nil value)
stack traceback:
[C]: ?
…s/emanouel1979/CoronaProjects/Haunted House/main.lua:69: in main chunk
line 69 has the following

group:insert(highScoreText)  

i had to commit out that line to work,

i also noticed the score show up with 3 extra 0 in the front of the score. for example score 3000 would be 0003000 [import]uid: 17701 topic_id: 25923 reply_id: 107344[/import]

“group” is the default display group that storyboard uses. If you’re not using storyboard but using Director for your scene management, then its “localGroup”. If you are not using any scene management then you probably don’t need to insert the display object into it.

As for the leading zero’s, that’s what the:

string.format("%07d", storyboard.settings.highScore)

does for you. %d means a number. The 7 means allocate 7 spaces to hold the number (padding spaces on the left). But some people like having leading zeros since it’s kind of a throwback to the 8 bit days.

You probably want to at least maintain the leading spaces if you don’t want the zeros so that the number stays right justified so as the number increases the score isn’t moving around. The reason why 7 digits? Covers scores in the millions. So feel free to change the number of digits, if you like. [import]uid: 19626 topic_id: 25923 reply_id: 107409[/import]

Rob,

thanks for clearing up the value info, its more clear to me now how that works.

I’m currently using storyboard, but i haven’t setup any groups in the main.lua file

heres is my main.lua

-----------------------------------------------------------------------------------------  
-- main.lua  
-----------------------------------------------------------------------------------------  
display.setStatusBar( display.HiddenStatusBar )  
  
-- require controller module  
local storyboard = require( "storyboard" )  
local scene = storyboard.newScene()  
storyboard.ice = require("ice")  
local score = ice:loadBox( "score" )  
local gameScore = score:retrieve("gameScore")  
---------------------------------------------------------------------------------  
-- BEGINNING OF YOUR IMPLEMENTATION  
---------------------------------------------------------------------------------  
  
local json = require( "json" )  
   
function saveTable(t, filename)  
 local path = system.pathForFile( filename, system.DocumentsDirectory)  
 local file = io.open(path, "w")  
 if file then  
 local contents = json.encode(t)  
 file:write( contents )  
 io.close( file )  
 return true  
 else  
 return false  
 end  
end  
   
function loadTable(filename)  
 local path = system.pathForFile( filename, system.DocumentsDirectory)  
 local contents = ""  
 local myTable = {}  
 local file = io.open( path, "r" )  
 if file then  
 print("trying to read ", filename)  
 -- read all contents of file into a string  
 local contents = file:read( "\*a" )  
 myTable = json.decode(contents);  
 io.close( file )  
 print("Loaded file")  
 return myTable  
 end  
 print("file not found")  
 return nil  
end  
   
storyboard.loadTable = loadTable  
storyboard.saveTable = saveTable  
  
storyboard.settings = storyboard.loadTable("settings.json")  
if storyboard.settings == nil then -- didn't load the table  
 storyboard.settings = {}  
 storyboard.settings.musicOn = true  
 storyboard.settings.soundFX = true  
 storyboard.settings.highScore = 100  
 storyboard.saveTable(storyboard.settings, "settings.json")  
end  
  
print ("Current HIGH SCORE:", storyboard.settings.highScore)  
storyboard.settings.highScore = storyboard.settings.highScore + 25  
storyboard.saveTable(storyboard.settings, "settings.json")  
print ("HIGH Score updated to:", storyboard.settings.highScore)  
  
local highScoreText = display.newText(string.format("%03d", storyboard.settings.highScore), 0, 0, "Helvetica", 22)  
highScoreText.x = display.contentWidth - 50  
highScoreText.y = 300  
--group:insert(highScoreText)  
  
local scoredata  
  
--[[ uncomment out below four lines to remove FPS status  
local fps = require("fps")  
local performance = fps.PerformanceOutput.new();  
performance.group.x, performance.group.y = 50, 0;  
performance.alpha = 0.2; -- So it doesn't get in the way of the rest of the scene  
--]]  
  
score:storeIfNew("gameScore", 100)  
score:save()  
  
print( "Main: Current Score is:", gameScore )  
   
scoredata = display.newText( "SCORE: " .. score:retrieve( "gameScore" ), 0, 0, "Helvetica", 22 )  
scoredata.x = 70  
scoredata.y = 300  
  
-- load first screen  
storyboard.gotoScene( "intro", "fade", 1000 )  

intro.lua

---------------------------------------------------------------------------------  
-- Intro Screen   
---------------------------------------------------------------------------------  
local storyboard = require( "storyboard" )  
local scene = storyboard.newScene()  
storyboard.ice = require("ice")  
local score = ice:loadBox( "score" ) -- this (loading the ice box locally) is what was missing!!  
local gameScore = score:retrieve("gameScore")  
---------------------------------------------------------------------------------  
-- BEGINNING OF YOUR IMPLEMENTATION  
---------------------------------------------------------------------------------  
local background  
  
-- Called when the scene's view does not exist:  
function scene:createScene( event )  
 local screenGroup = self.view  
  
 background = display.newImage( "assets/graphics/intro.png", 0, 0 )  
 screenGroup:insert( background )  
  
 print( "\nIntro: createScene event")  
end  
-- Called immediately after scene has moved onscreen:  
function scene:enterScene( event )  
 local group = self.view   
 print( "Intro: enterScene event" )  
  
 print( "Intro Current Score is:", gameScore )  
  
gameScore = gameScore + 5  
score:store("gameScore", gameScore)  
score:save() -- this will finally work!  
print( "updated score is:", gameScore )  
  
print ("Current HIGH SCORE:", storyboard.settings.highScore)  
storyboard.settings.highScore = storyboard.settings.highScore + 10  
storyboard.saveTable(storyboard.settings, "settings.json")  
print ("")  
print ("Intro Scene HIGH Score updated to:", storyboard.settings.highScore)  
highScoreText.text = string.format("%03d",storyboard.settings.highScore)  
  
  
 local function gotoTitle()  
 storyboard.gotoScene( "title", "fade", 500 )  
end  
   
-- To wait 3 seconds before switching scenes,  
timer.performWithDelay(1500, gotoTitle)  
  
 local lastScene = storyboard.getPrevious()  
  
 print( "last scene was:", lastScene ) -- output: last scene name  
end  
  
-- Called when scene is about to move offscreen:  
function scene:exitScene( event )  
 local group = self.view   
 print( "Intro: exitScene event" )  
end  
-- Called prior to the removal of scene's "view" (display group)  
function scene:destroyScene( event )  
 local group = self.view  
 print( "((destroying Intro's view))" )  
end  
  
---------------------------------------------------------------------------------  
-- END OF YOUR IMPLEMENTATION  
---------------------------------------------------------------------------------  
  
-- "createScene" event is dispatched if scene's view does not exist  
scene:addEventListener( "createScene", scene )  
  
-- "enterScene" event is dispatched whenever scene transition has finished  
scene:addEventListener( "enterScene", scene )  
  
-- "exitScene" event is dispatched before next scene's transition begins  
scene:addEventListener( "exitScene", scene )  
  
-- "destroyScene" event is dispatched before view is unloaded, which can be  
-- automatically unloaded in low memory situations, or explicitly via a call to  
-- storyboard.purgeScene() or storyboard.removeScene().  
scene:addEventListener( "destroyScene", scene )  
  
---------------------------------------------------------------------------------  
  
return scene  

I’ve been testing my file with both this method and ice box to see which one works, as I’ve had issues getting icebox to pass data and update to the text box.

now in the updating code you provided

highScoreText.text = string.format("%03d",storyboard.settings.highScore)  

should i have included the

group:insert(highScoreText)  

to update the score to the text ? as I’m not getting the score updated in real time, its updating it via the print command but not on the highScoreText

when i run the code like this i get the following errors
Runtime error
…/emanouel1979/CoronaProjects/Haunted House/intro.lua:42: attempt to index global ‘highScoreText’ (a nil value)
stack traceback:
[C]: ?
…/emanouel1979/CoronaProjects/Haunted House/intro.lua:42: in function <… house>
?: in function ‘dispatchEvent’
?: in function <?:1095>
(tail call): ?
?: in function <?:1170>
?: in function <?:218>
[import]uid: 17701 topic_id: 25923 reply_id: 107443[/import] </…>

With storyboard apps, you typically would not have a group in “main.lua” so you wouldn’t put it in a group there.

You also typically would not show your score on menu pages, splash screens, help pages, etc. I would not put the code to show it in main, but in your game and game over scenes.

display objects that you put in main.lua (or any other scene) that you don’t put into that scene’s “group” will sit above any scene’s so you can setup things that should be there in every scene.
[import]uid: 19626 topic_id: 25923 reply_id: 107597[/import]

Rob,

thanks for the response.

i was just testing it with the main file. so in the scene 1.lua i start the score output.

when i try to update the score on screen it doesn’t update, but the print command does show the updated score in terminal.

im not sure what code to use to update the output score.

lets say in scene 2 i pick up a item , it adds 25 to my current score. how do i get the text output to update as well.

print ("Current HIGH SCORE:", storyboard.settings.highScore)  
storyboard.settings.highScore = storyboard.settings.highScore + 10  
storyboard.saveTable(storyboard.settings, "settings.json")  
print ("")  
print ("Intro Scene HIGH Score updated to:", storyboard.settings.highScore)  
highScoreText.text = string.format("%03d",storyboard.settings.highScore) -- if i enable this i still get the error  

in the above code i use the print statement to check the status of the score update and it works, just stuck with how to output the value on screen [import]uid: 17701 topic_id: 25923 reply_id: 107602[/import]

You have to put the display.newText() in the same scene file. [import]uid: 19626 topic_id: 25923 reply_id: 107607[/import]

do you mean at the end of line 4 ?

highScoreText = display.newText  

is that code above correct? or do i need to pass the variable to the next scene ??

display.newText()

i tried running the game with the

highScoreText.text = string.format("%03d",storyboard.settings.highScore)  

but the it keeps returning a nil value. am i missing something in my code to pass the value, i have the value correctly printing onto terminal

im assumng I’m not correctly passing the value to the other scenes

basically i want to display the score when i go to scene1.lua and have it updated in every scene within the game.

doesn’t display.newText() create a new text box, and not update to the current one ?? [import]uid: 17701 topic_id: 25923 reply_id: 107610[/import]