keeping score / health in storyboard

hi,

I’m trying to keep score game using storyboard scenes. i would like to start the game with 100 health. would it be better to store it in a external module and keep calling it up in each scene ?

i used the code from peach’s techority.com tutorial and modified it from a scoring system to a health system

-- health.lua  
  
module(..., package.seeall)  
  
--Start the health at 100  
local health = 100  
  
--Create health text and make it dark gray  
local healthText = display.newText(health, 20, 290, native.systemFont, 24)  
healthText:setTextColor( 255, 255, 255 )  
  
--Create the first aid kit  
local firstaidkit = display.newRect( 0, 0, 50, 50 )  
firstaidkit:setFillColor( 150, 180, 200 )  
  
--Function to add to health and update healthText  
local function addToHealth()  
health = health + 30  
healthText.text = health  
firstaidkit:removeSelf()  
firstaidkit:removeEventListener("tap", addToHealth)  
end  
firstaidkit:addEventListener("tap", addToHealth)  
  
--Hide the status bar  
display.setStatusBar(display.HiddenStatusBar)  
  

i know id have to remove the following from the health.lua

--Create the first aid kit  
local firstaidkit = display.newRect( 0, 0, 50, 50 )  
firstaidkit:setFillColor( 150, 180, 200 )  
  
--Function to add to health and update healthText  
local function addToHealth()  
health = health + 30  
healthText.text = health  
firstaidkit:removeSelf()  
firstaidkit:removeEventListener("tap", addToHealth)  
end  
firstaidkit:addEventListener("tap", addToHealth)  
----------------------------------------------------------------------------------------  
-- main.lua  
----------------------------------------------------------------------------------------  
display.setStatusBar( display.HiddenStatusBar )  
  
-- require controller module  
local storyboard = require "storyboard"  
local health = require( "health" )  
  
-- comment 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  
  
-- load first screen  
storyboard.gotoScene( "scene1", "fade", 400 )  

how could i create the firstaidkit in scene1.lua and have it access the data from health.lua and then add 30 to the health.

[code]

– scene1.lua Room 1

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()
local lastScene = storyboard.getPrevious()
ocal health = require( “health” )


– BEGINNING OF YOUR IMPLEMENTATION

local background, room2, blackKey, blackdoorlocked, text1

– Touch event listener for background image
local function gotoRoom2( self, event )
if event.phase == “began” then

storyboard.gotoScene( “scene2”, “fade”, 400 )

return true
end
end

local function doorlocked( self, event )
if event.phase == “began” then
– storyboard.gotoScene( “scene20”, “fade”, 400 )
text1 = display.newText( “Door is Locked, the key should be near by”, 0, 245, native.systemFontBold, 20 )
text1:setTextColor( 255 )
transition.to(text1, {time=1000, onComplete = function() display.remove(text1) end})
return true

elseif(event.phase == “moved”) then
– Do Something During the “moved” phase
transition.to(self, {x = event.x, y = event.y, time=0});
end
end

local function onSceneTouchx( self, event )
if event.phase == “began” then

storyboard.gotoScene( “scene3”, “fade”, 400 )

return true
end
end

– Called when the scene’s view does not exist:
function scene:createScene( event )
local screenGroup = self.view

background = display.newImage( “assets/graphics/Room1.png”, 0, 0 )
screenGroup:insert( background )

blackdoorlocked = display.newImage( “assets/graphics/BlackLock2.png”, 175, 0 )
screenGroup:insert( blackdoorlocked )

blackdoorlocked.touch = doorlocked

room2 = display.newImage( “assets/graphics/gotoRoom2.png”, 175, 0 )
screenGroup:insert( room2 )

room2.touch = gotoRoom2

– blackKey = display.newImage( “assets/graphics/BlackKey.png”, 100, 200 )
– screenGroup:insert( blackKey )

– blackKey.touch = onSceneTouchx

print( “\n1: createScene event”)
end
– Called immediately after scene has moved onscreen:
function scene:enterScene( event )

print( “1: enterScene event” )

– remove previous scene’s view
storyboard.purgeScene( lastScene )
print( “last scene was:”, lastScene ) – output: last scene name

– Update Lua memory text display
– blackKey:addEventListener( “touch”, blackKey )
room2:addEventListener( “touch”, room2 )
blackdoorlocked:addEventListener( “touch”, blackdoorlocked )

end
– Called when scene is about to move offscreen:
function scene:exitScene( event )

print( “1: exitScene event” )

– remove touch listener for image
– blackKey:removeEventListener( “touch”, blackKey )
room2:removeEventListener( “touch”, room2 )
blackdoorlocked:removeEventListener( “touch”, blackdoorlocked )
end
– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )

print( “((destroying scene 1’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
[/code] [import]uid: 17701 topic_id: 25782 reply_id: 325782[/import]

You could save it in a file and read it when you needed it (I’d suggest Ego for this) - that way you could still have it be local.

Is that an option for you? :slight_smile: [import]uid: 52491 topic_id: 25782 reply_id: 104403[/import]

Peach,

how do i implement the ego.lua into the game health bar?

so i only need to play the require code below in the main.lua?

ego = require "ego"  
saveFile = ego.saveFile  
loadFile = ego.loadFile  

lets say i save the code in main.lua and then when i enter scene2.lua i see a health pack. i click on it and it adds health = health + 25

how would i could that ?

thanks [import]uid: 17701 topic_id: 25782 reply_id: 104540[/import]

Keep in mind that you can always add things to tables in lua. Things like “storyboard” are just big Lua tables. You do a:

local storyboard = require(“storyboard”)

in every storyboard scene, so you an freely add things to the “storyboard” table:

storyboard.score = storyboard.score + 1

or for even more fun, in your main.lua:

  
local storyboard = require "storyboard"  
storyboard.health = require "health"  
  

then in “scene1.lua”

  
local storyboard = require "storyboard"  
  
print(storyboard.health )  
  

storyboard.health would be the same as doing a new local health=require(“health”) all over the place. You can use storyboard.health just like you would use just “health”. [import]uid: 19626 topic_id: 25782 reply_id: 104542[/import]

rob,

thanks for the info,

so basically the code in scene1.lua would be like

local function addToHealth()  
storyboard.health = storyboard.health + 30  
healthText.text = health -- or should this be storyboard.healthText.text = storyboard.health ?  
firstaidkit:removeSelf()  
firstaidkit:removeEventListener("tap", addToHealth)  
end  
firstaidkit:addEventListener("tap", addToHealth)  

would i also need to use storyboard.healthText.text = storybaord.health ??

[import]uid: 17701 topic_id: 25782 reply_id: 104547[/import]

i did the code and didn’t get the correct output, heres what i got from terminal

table: 0xab04f60

everytime i reload it, it will output a different table value

print(storyboard.health)  

in your example you had

local storyboard = require "storyboard"  
   
print(storyboard.health )  

shouldn’t it be ???

local storyboard = require( "storyboard" )  
  
print(storyboard.health )  

in the main.lua i have

-----------------------------------------------------------------------------------------  
-- main.lua  
-----------------------------------------------------------------------------------------  
display.setStatusBar( display.HiddenStatusBar )  
  
-- require controller module  
local storyboard = require "storyboard"  

but in all my scene.lua files i have it as

---------------------------------------------------------------------------------  
-- scene1.lua Room 1  
---------------------------------------------------------------------------------  
local storyboard = require( "storyboard" )  
local scene = storyboard.newScene()  
local lastScene = storyboard.getPrevious()  
  

or do i need to put

storyboard.health = require "health"  

before the print in each scene file ??? [import]uid: 17701 topic_id: 25782 reply_id: 104552[/import]

Peach,

i was able to get the health working with the help of your score.lua. the problem comes from when i click on the health pack and it adds 75 health to the health. after i leave the scene and come back to the same scene i get the following error

…manouel1979/CoronaProjects/scene10.lua:77: attempt to call method ‘addEventListener’ (a nil value)
stack traceback:
[C]: in function ‘addEventListener’
…manouel1979/CoronaProjects/scene10.lua:77: in function <…manouel1979>
?: in function ‘dispatchEvent’
?: in function <?:1051>
(tail call): ?
?: in function <?:1215>
?: in function <?:218>

<br>local function gotoRoom69( self, event )<br> if event.phase == "began" then<br> room69:removeSelf()<br> health.sethealth (health.gethealth()+75)<br>-- storyboard.gotoScene( "scene6", "fade", 400 )<br> room69:removeEventListener( "touch", room69 )<br> return true<br> end<br>end<br>

I’m trying to figure out how to stop the event listener from being called up again.

i even tried removing the
<br>function scene:destroyScene( event )<br>
[import]uid: 17701 topic_id: 25782 reply_id: 104779[/import] </…manouel1979>

Which of those is line 77 in scene10.lua?

The score addon you are talking about may not be the best option for this; did you actually look at Ego? What Rob suggests above is also very solid advice. [import]uid: 52491 topic_id: 25782 reply_id: 104833[/import]

Try something like this:

local function gotoRoom69( self, event )  
 if event.phase == "began" then  
 storyboard.health.sethealth (storyboard.health.gethealth()+75)  
 room69:removeSelf()  
 room69:removeEventListener( "touch", room69 )  
 return true  
 end  
end  

i kept getting table: 0xab04f60 output value instead of the 100 . so i wash;t sure what i did wrong

The health module is returning a object with member methods and properties. In Lua those objects are tables. table:0xab04f60 is the memory address of the table. You can’t manipulate it directly. I don’t have the health module code to look at, but looking at the code above, it appears to have getter and setter functions.

Using the storyboard object is basically putting a table inside a table, so you have to reference it:

storyboard.health.memberfunction() or
storyboard.health.memberproperty = …

[import]uid: 19626 topic_id: 25782 reply_id: 104908[/import]

Peach,

i did look into ego, but wasn’t sure how to use it for storing the health info.

i tried using rob’s method, but i got stuck with the coding, i kept getting table: 0xab04f60 output value instead of the 100 . so i wash;t sure what i did wrong

i did try score and so far its works, the only problem is when i go back into a scene where i removed the firstaidkit, it is looking for the event, as it is created again.

here is the code below

[code]

– scene10.lua Room 10

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()
local lastScene = storyboard.getPrevious()
storyboard.health = require (“health”)

– BEGINNING OF YOUR IMPLEMENTATION

local background, room6, room69

–[[
local firstaidkit = display.newImage( “assets/graphics/FirstAidKit.png”, 22, 22 )

–Function to add to health and update healthText
local function addToHealth( self, event )
health.sethealth (health.gethealth()+75)
firstaidkit:removeSelf()
firstaidkit:removeEventListener(“tap”, addToHealth)
end
firstaidkit:addEventListener(“tap”, addToHealth)
–]]

– Touch event listener for background image
local function gotoRoom6( self, event )
if event.phase == “began” then

storyboard.gotoScene( “scene6”, “fade”, 400 )

return true
end
end

local function gotoRoom69( self, event )
if event.phase == “began” then
health.sethealth (health.gethealth()+75)
room69:removeSelf()
– room69:removeEventListener( “touch”, room69 )
return true
end
end

– Called when the scene’s view does not exist:
function scene:createScene( event )
local screenGroup = self.view

background = display.newImage( “assets/graphics/Room10.png”, 0, 0 )
screenGroup:insert( background )

room6 = display.newImage( “assets/graphics/gotoRoom6.png”, 5, 130 )
screenGroup:insert( room6 )

room6.touch = gotoRoom6

room69 = display.newImage( “assets/graphics/FirstAidKit.png”, 22, 22 )
screenGroup:insert( room69 )

room69.touch = gotoRoom69

print( “\n10: createScene event”)
end
– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
print( “10: enterScene event” )

– remove previous scene’s view
storyboard.purgeScene( lastScene )
print( “last scene was:”, lastScene ) – output: last scene name

– Update Lua memory text display
room6:addEventListener( “touch”, room6 )
room69:addEventListener( “touch”, room69 )
end
– Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
print( “6: exitScene event” )

– remove touch listener for image
room6:removeEventListener( “touch”, room6 )
end
– Called prior to the removal of scene’s “view” (display group)
–function scene:destroyScene( event )
– local group = self.view
– print( “((destroying scene 10’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
[/code] [import]uid: 17701 topic_id: 25782 reply_id: 104905[/import]

Rob,

thanks for the clarificalation, so basically i put at the start of my file.

storyboard.health.memberproperty = require (“health”)

is that correct ??

the code you provide gave me the same error

Runtime error
…/CoronaProjects/scene10.lua:76: attempt to call method ‘addEventListener’ (a nil value)
stack traceback:
[C]: in function ‘addEventListener’
…manouel1979/CoronaProjects/scene10.lua:76: in function <…manouel1979>
?: in function ‘dispatchEvent’
?: in function <?:1051>
(tail call): ?
?: in function <?:1215>
?: in function <?:218>

i know it has to do with going back into room 10 and add event listener is being created, is there a way to prevent it from being created again when the room is entered ?

the new health.lua file
<br>module(..., package.seeall)<br> <br>-- Init images. This creates a map of characters to the names of their corresponding images.<br> local numbers = { <br> [string.byte("0")] = "assets/graphics/0.png",<br> [string.byte("1")] = "assets/graphics/1.png",<br> [string.byte("2")] = "assets/graphics/2.png",<br> [string.byte("3")] = "assets/graphics/3.png",<br> [string.byte("4")] = "assets/graphics/4.png",<br> [string.byte("5")] = "assets/graphics/5.png",<br> [string.byte("6")] = "assets/graphics/6.png",<br> [string.byte("7")] = "assets/graphics/7.png",<br> [string.byte("8")] = "assets/graphics/8.png",<br> [string.byte("9")] = "assets/graphics/9.png",<br> [string.byte(" ")] = "assets/graphics/space.png",<br>}<br>-- health components<br>local thehealthGroup = display.newGroup()<br>local theBackground = display.newImage( "assets/graphics/healthbar.png" )<br>local theBackgroundBorder = 10<br>thehealthGroup:insert( theBackground )<br>local numbersGroup = display.newGroup()<br>thehealthGroup:insert( numbersGroup )<br>-- the current health<br>local thehealth = 10<br>-- the location of the health image<br>-- initialize the health<br>-- params.x &lt;= X location of the health<br>-- params.y &lt;= Y location of the health<br>function init( params )<br> thehealthGroup.x = params.x<br> thehealthGroup.y = params.y<br> sethealth( 0 )<br>end<br>-- retrieve health panel info<br>-- result.x &lt;= current panel x<br>-- result.y &lt;= current panel y<br>-- result.xmax &lt;= current panel x max<br>-- result.ymax &lt;= current panel y max<br>-- result.contentWidth &lt;= panel width<br>-- result.contentHeight &lt;= panel height<br>-- result.health &lt;= current health<br>function getInfo()<br> return {<br> x = thehealthGroup.x,<br> y = thehealthGroup.y,<br> xmax = thehealthGroup.x + thehealthGroup.contentWidth,<br> ymax = thehealthGroup.y + thehealthGroup.contentHeight,<br> contentWidth = thehealthGroup.contentWidth,<br> contentHeight = thehealthGroup.contentHeight,<br> health = thehealth<br> }<br>end<br>-- update display of the current health.<br>-- this is called by sethealth, so normally this should not be called<br>function update()<br> -- remove old numerals<br> thehealthGroup:remove(2)<br> local numbersGroup = display.newGroup()<br> thehealthGroup:insert( numbersGroup )<br> -- go through the health, right to left<br> local healthStr = tostring( thehealth )<br> local healthLen = string.len( healthStr )<br> local i = healthLen <br> -- starting location is on the right. notice the digits will be centered on the background<br> local x = 70<br> local y = thehealthGroup.contentHeight / 2<br> <br> while i &gt; 0 do<br> -- fetch the digit<br> local c = string.byte( healthStr, i )<br> local digitPath = numbers[c]<br> local characterImage = display.newImage( digitPath )<br> -- put it in the health group<br> numbersGroup:insert( characterImage )<br> <br> -- place the digit<br> characterImage.x = x - characterImage.width / 2<br> characterImage.y = y<br> x = x - characterImage.width<br> -- <br> i = i - 1<br> end<br>end<br>-- get current health<br>function gethealth()<br> return thehealth<br>end<br>-- set health to value<br>-- health &lt;= health value<br>function sethealth( health )<br> thehealth = health<br> <br> update()<br>end<br><br> [import]uid: 17701 topic_id: 25782 reply_id: 104914[/import] </…manouel1979>

It’s good to see the code for the health module.

Lets take a moment and try to explain what’s going on.

When you do a:

local health = require("health")  

you end up with a local object in that lua file (say main.lua or scene.lua)

You would do code like:

local currentHealth = health.gethealth()  
currentHealth = currentHealth + 10   
health.sethealth(currenthealth)  

But the health object is only exposed in the module it’s included in. You could, in every module you want to access the health object in, to the require statement.

But if you wanted to only require it once, say in main.lua, leave the “local” off of the require. But doing so makes it a global object and now any scene file you load you can just access it with the code above. It only saves you having to require it wherever you want it.

But we know globals are bad. So Jonathan Beebe suggests that you use the storyboard object to hold any variables that need passed between storyboard scenes.

If you want to go this route, the above code looks like:

local storyboard.health = require("health")  
  
local currentHealth = storyboard.health.gethealth()  
currentHealth = currentHealth + 10   
storyboard.health.sethealth(currenthealth)  

[import]uid: 19626 topic_id: 25782 reply_id: 104932[/import]

Rob,

thanks for clearing that up for me.

i did get a error when i put local storyboard.health = require(“health”) at the start of my code.
shouldn’t it be storyboard.health = require(“health”) ??

the error is

Copyright © 2009-2012 A n s c a , I n c .
Version: 2.0.0
Build: 2012.805
The file sandbox for this project is located at the following folder:
(/Users/e9/Library/Application Support/Corona Simulator/Haunted House-9C5596D8D2694A3F5472DC3989A7B207)
Syntax error: /Users/emanouel1979/CoronaProjects/HH/main.lua:8: unexpected symbol near ‘.’

line 8 is

local storyboard.health = require ("health")  

the code i currently have is

local storyboard = require "storyboard"  
storyboard.health = require ("health")  
local healthInfo = health.getInfo()  
  
health.sethealth (health.gethealth()+75) -- code to ad to current score  

so far I’ve noticed that if i place the code

 health.sethealth (health.gethealth()+7  

in a different scene for example scene3.lua i don’t need to put the require statement as its still being used.

I’ve also noticed that if i return back to the room where i got the firstaidkit i get a error that it whats to start the add evenylistener for a object thats not there. the code is in the previous message. I’m not sure how to code it.

here’s the error code

Runtime error
…manouel9/CoronaProjects/HH/scene10.lua:76: attempt to call method ‘addEventListener’ (a nil value)
stack traceback:
[C]: in function ‘addEventListener’
…manouel9/CoronaProjects/HH/scene10.lua:76: in function <…manouel9>
?: in function ‘dispatchEvent’
?: in function <?:1051>
(tail call): ?
?: in function <?:1215>
?: in function <?:218>
i was planning if have a if statement if object is not taken then create add event listener, or else don’t load event listener. any tips ???

thanks again for your very good knowledge and help [import]uid: 17701 topic_id: 25782 reply_id: 105005[/import] </…manouel9>

Yea, leave the “local” off. Storyboard has already been declared above.

[import]uid: 19626 topic_id: 25782 reply_id: 105006[/import]

Rob thanks.

how about the addeventlistener error ??

any suggestions??

thanks [import]uid: 17701 topic_id: 25782 reply_id: 105015[/import]

good news !!!

i finally figured it out :slight_smile:

i move the code from

function scene:enterScene( event )  
  
room69:addEventListener( "touch", room69 )  

to

function scene:createScene( event )  
  
room69:addEventListener( "touch", room69 )  

reason being : createScene() is where stuff gets built once and held in memory until the scene is purged, while enterScene() is where stuff happens every-time you enter.

hope this can help someone else :slight_smile:

now if i wanted a game over screen, i should just reverse the score of + 25 to - 25 and then check the score to see if it is 0 or < then and then bring up the game over screen. ??

thanks again to Rob and Peach for there help regarding this issue :slight_smile: [import]uid: 17701 topic_id: 25782 reply_id: 105068[/import]

Do you start at 0? If so, then your game would be over right away. Your game’s rules will dictate when it’s over. Without knowing more about what you’re building, it’s hard to advise about how to determine when the game is over.

[import]uid: 19626 topic_id: 25782 reply_id: 105118[/import]

Rob,

the game starts off at 100 health, in normal mode, i also plan on adding a hard and extreme mode later on. which can be easily done later on.

the only two situations where to check for health of 0 or < would be

  1. during a boss battle
  2. when clicking on a negative object

kinda similar to a rail shooter (House of the dead, virtua cop) where you click on a health pack gain health, shot a innocent lose health.
[import]uid: 17701 topic_id: 25782 reply_id: 105135[/import]

quick question do i need to put

storyboard.health = require ("health") in every scene file?

in my main file its setup as

  
-- main.lua  
-------------------------------------------------------------------------  
display.setStatusBar( display.HiddenStatusBar )  
  
-- require controller module  
local storyboard = require "storyboard"  
storyboard.health = require ("health")  
local healthInfo = health.getInfo()  

while in the scene1.lua its setup as

[code]
– scene 1 Room 1

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()
[/code] [import]uid: 17701 topic_id: 25782 reply_id: 105136[/import]