Removing objects from table in function

Hi guys!
Today I need help to make a mini “lives bar” using circles.
I create the circles using a table and I want to update the number of “lives” and the “circle” display object that represent that number at the same time, I also want to put the current number of lives in a variable and pass the parameters to my “reload” scene with composer set and get variable. This is what I have.

local lives = {} local numOfLives = 3 local loseLive = 3 --create the lives   for i = 1, numOfLives do     lives[i] = display.newCircle( 0, 0, 5 )     lives[i]:setFillColor( 1, 1 , 1 )     sceneGroup:insert( lives[i] )   end   lives[1].x = centerX; lives[1].y = \_T+50   lives[2].x = lives[1].x+20; lives[2].y = \_T+50   lives[3].x = lives[2].x+20; lives[3].y = \_T+50 --function to update lives local function updateLives( event ) local lastLive = lives[i] - 1 -- HERE I GET AN ERROR display.remove(lastLive) loseLive = loseLive - 1 composer.setVariable( "loseLive", loseLive - 1 ) if loseLive == 0 then local options = { effect = "crossFade", time = 100 } composer.gotoScene( "levels.menu", options ) end end

the problem here is I’m not an expert in tables, its easy to do it like “Star Explorer” using text but I want to make it with display objects.

any help to achieve this task?

DoDi

You’re treating a display object reference like a numeric value.

Try this instead, fixes your bug and simplifies your code:

local lives local numLives = 3 -- I assume this is in create or somewhere like that... -- Pips/Dots to indicate number of lives lives = {} for i = 1, numLives do lives[i] = display.newCircle( sceneGroup, 0, 0, 5 ) lives[i]:setFillColor( 1, 1, 1 ) lives[i].x = centerX + (i-1) \* 20 lives[i].y = \_T + 50 end -- Not sure where you have this local function updateLives( event ) -- Remove Pip/Dot if( numLives \> 0 ) then display.remove( lives[numLives] ) -- destroy object numLives = numLives - 1 end composer.setVariable( "numLives", numLives ) -- not really sure what you were doing here, but I tried to -- modify it to follow the code logic if( numLives \<= 0 ) then local options = { effect = "crossFade", time = 100 } composer.gotoScene( "levels.menu", options ) end end

@roaminggamer thanks for your fast response? 

dot creation is in the scene:create.

and updateLives() is in the scene template area for functions at top.

-- not really sure what you were doing here, but I tried to -- modify it to follow the code logic

I use a “reload scene” to refresh the game scene and show some graphics. if I do not pass the parameters of “lives” when returning to the game scene the “lives” would be in 3  and not in 2 since lives are lost. I’m trying to understand this.

to use myTable.json would be better option for “lives” than to use composer set and get variable?

thanks 

DoDi

local composer = require( "composer" ) local scene = composer.newScene() local loadsave = require( "loadsave" ) --THANKS! @robmiracle --reference local livesDots local numOfLives = 3 -- Scene event functions local function updateLives() if( numOfLives \> 0 ) then display.remove( livesDots[numOfLives] ) numOfLives = numOfLives - 1 end end -- create() local myTable = (loadsave.loadTable("myTable.json") or {}) numOfLives = (myTable.livesNumber or 6) livesDots = {} for i = 1, numOfLives do livesDots[i] = display.newCircle( 0, 0, 5 ) livesDots[i]:setFillColor( 1, 1, 1 ) livesDots[i].x = centerX+242 + (i-1) \* 18 livesDots[i].y = \_T+50 sceneGroup:insert( livesDots[i] ) end -- show() local myTable = {} myTable.sceneNumber = "1" myTable.livesNumber = numOfLives loadsave.saveTable(myTable, "myTable.json")

This is what I’m trying to do right now, the LivesDots works fine, thanks @roaminggamer, but when I came back to scene after loosing I get an error saying numOfLives must be a number

if I add a “tomumber(numOfLives)” instead of “numOfLives” to “myTable.json”, the error disappears, but when I returned to the scene I have the same 3 livesDots

I’m sure I can see the problem in situ, but I don’t want to try to work it out here.

Zip up your project AS IS and attach the zip file here.

I’ll show you what you’re doing wrong.

PS - Do you know how to diff files?

I ask because I’ll provide your original file(s) and modified one(s).  I will expect you to diff them to see what was changed.

PPS - You’re and OSX user right?

@roaminggamer, thanks but… I’m a Windows user…I’m not used to publishing content in a way that everyone can see and modify. Believe me, I would like to do it!! but my ethics tells me NO, and it is something very personal.

I can’t help if I can’t see the code in situ.  

I’m not clear how a mod to the Star Explorer game is an ethics problem.  This is about learning and not money right?

If you’re doing this to learn and not to make money you can email me the entire project here (again, in a zip file):

rgemail.png

Note: I don’t generally give free debugging  help if folks are using that to make money.

If you want or need to go it alone consider:

  1. Scope & visibility. - Your variable is probably in the wrong place.
  2. Don’t create()/destroy() use enter()/exit() instead - If you’re re-entering the scene, I suggest creating in the will phase of enter and destroying in the did phase of exit.  Others will give other advice, that is fine.  This is what I do and it always works for me.

thanks @roaminggamer, but to follow your rules I will not send the .rar at this time because…

  1. I’m doing this to make money

  2. I use some print statements and see that the error was an empty json table, no value, no numOfLifes, scope :wacko: .

At this moment I am very grateful for the help you offered me, and I’m writing this wholeheartedly, because I respect you very much as a professional, as well as all the people who take time to help newbies like me.

I also take your work very seriously here as “hire a hitman” but I prefer to leave it for when something really gets out of my hands.

@roaminggamer or @all

I just realized that by using @roaminggamer code instead of having 3 lives I have 4.

local function updateLives( event ) -- Remove Pip/Dot if( numLives \> 0 ) then display.remove( lives[numLives] ) numLives = numLives - 1 end if( numLives \<= 0 ) then local options = { effect = "crossFade", time = 100 } composer.gotoScene( "levels.menu", options ) end end

the thing is every time I lose a live, a dot disappear, but the last time, its suppose to remove last dot and go to menu scene, but no, I get another chance to play the game scene with no dots.

any advice?

Thanks DoDi

Nope.  The code I see there won’t behave as you have described.  You can easily test this.

Put some print statement in the function to see what it does and how your count progresses

local function updateLives( event ) print("entering updateLives(); numLives == ", numLives ) -- Remove Pip/Dot if( numLives \> 0 ) then display.remove( lives[numLives] ) numLives = numLives - 1 print("Removed a life; numLives == ", numLives ) end if( numLives \<= 0 ) then print("Bye! numLives == ", numLives ) print("------------------------\n") local options = { effect = "crossFade", time = 100 } composer.gotoScene( "levels.menu", options ) return end print("Continuing... numLives == ", numLives ) print("------------------------\n") end

@roaminggamer

It is a very strange situation for me I started reading on lua.org about the “loops” and it really should work as it is written, I do not know if using it within the “collision” event will alter some things.

18:08:54.316 level 1 18:08:57.786 right button tap 18:08:58.946 right button tap 18:08:59.106 right button tap 18:09:01.476 collision 18:09:01.476 entering updateLives(); numOfLives == 6 18:09:01.476 Removed a life; numOfLives == 5 18:09:01.956 collision 18:09:02.496 nil 18:09:02.496 nil 18:09:02.496 nil -------------------------------------------------------timers nil 18:09:02.496 nil 18:09:02.496 nil 18:09:02.496 nil 18:09:02.496 reload ---------------------------------------------------reload scene 18:09:03.237 level 1 18:09:11.066 right button tap 18:09:15.577 collision 18:09:15.577 entering updateLives(); numOfLives == 5 18:09:15.577 Removed a life; numOfLives == 4 18:09:16.618 nil 18:09:16.618 nil 18:09:16.618 nil 18:09:16.618 nil 18:09:16.618 nil 18:09:16.618 nil 18:09:16.618 reload 18:09:17.377 level 1 18:09:25.007 right button tap 18:09:25.306 right button tap 18:09:25.487 right button tap 18:09:27.987 collision 18:09:27.987 entering updateLives(); numOfLives == 4 18:09:27.987 Removed a life; numOfLives == 3 18:09:28.557 collision 18:09:29.017 nil 18:09:29.017 nil 18:09:29.017 nil 18:09:29.017 nil 18:09:29.017 nil 18:09:29.017 nil 18:09:29.017 reload 18:09:29.736 level 1 18:09:32.107 right button tap 18:09:32.327 right button tap 18:09:35.217 collision 18:09:35.217 entering updateLives(); numOfLives == 3 18:09:35.217 Removed a life; numOfLives == 2 18:09:36.257 nil 18:09:36.257 nil 18:09:36.257 nil 18:09:36.257 nil 18:09:36.257 nil 18:09:36.257 nil 18:09:36.257 reload 18:09:36.997 level 1 18:09:41.387 right button tap 18:09:41.527 right button tap 18:09:44.198 collision 18:09:44.198 entering updateLives(); numOfLives == 2 18:09:44.198 Removed a life; numOfLives == 1 18:09:45.257 nil 18:09:45.257 nil 18:09:45.257 nil 18:09:45.257 nil 18:09:45.257 nil 18:09:45.257 nil 18:09:45.257 reload 18:09:45.997 level 1 18:09:50.207 right button tap 18:09:50.389 right button tap 18:09:50.587 right button tap 18:09:53.218 collision 18:09:53.218 entering updateLives(); numOfLives == 1 18:09:53.218 Removed a life; numOfLives == 0 18:09:53.237 Bye! numLives == 0 18:09:53.237 ------------------------ 18:09:53.237 18:09:53.719 collision 18:09:54.240 nil 18:09:54.240 nil 18:09:54.240 nil 18:09:54.240 nil 18:09:54.240 nil 18:09:54.240 nil 18:09:54.240 reload ---------------------------------------------------W H Y ?? 18:09:54.996 level 1 ---------------------------------- IT'S SUPPOSED TO BE MAIN MENU

Investigate why numLives is higher than 3.   That is one big problem I see based on what you’ve said.

Also, examine where updateLives() is being triggered and work back from there.

Finally, I think you need to have someone look at your game and walk through that bit with you.  There is more to this scene/file and I’m sure there is another factor here.

You’re treating a display object reference like a numeric value.

Try this instead, fixes your bug and simplifies your code:

local lives local numLives = 3 -- I assume this is in create or somewhere like that... -- Pips/Dots to indicate number of lives lives = {} for i = 1, numLives do lives[i] = display.newCircle( sceneGroup, 0, 0, 5 ) lives[i]:setFillColor( 1, 1, 1 ) lives[i].x = centerX + (i-1) \* 20 lives[i].y = \_T + 50 end -- Not sure where you have this local function updateLives( event ) -- Remove Pip/Dot if( numLives \> 0 ) then display.remove( lives[numLives] ) -- destroy object numLives = numLives - 1 end composer.setVariable( "numLives", numLives ) -- not really sure what you were doing here, but I tried to -- modify it to follow the code logic if( numLives \<= 0 ) then local options = { effect = "crossFade", time = 100 } composer.gotoScene( "levels.menu", options ) end end

@roaminggamer thanks for your fast response? 

dot creation is in the scene:create.

and updateLives() is in the scene template area for functions at top.

-- not really sure what you were doing here, but I tried to -- modify it to follow the code logic

I use a “reload scene” to refresh the game scene and show some graphics. if I do not pass the parameters of “lives” when returning to the game scene the “lives” would be in 3  and not in 2 since lives are lost. I’m trying to understand this.

to use myTable.json would be better option for “lives” than to use composer set and get variable?

thanks 

DoDi

local composer = require( "composer" ) local scene = composer.newScene() local loadsave = require( "loadsave" ) --THANKS! @robmiracle --reference local livesDots local numOfLives = 3 -- Scene event functions local function updateLives() if( numOfLives \> 0 ) then display.remove( livesDots[numOfLives] ) numOfLives = numOfLives - 1 end end -- create() local myTable = (loadsave.loadTable("myTable.json") or {}) numOfLives = (myTable.livesNumber or 6) livesDots = {} for i = 1, numOfLives do livesDots[i] = display.newCircle( 0, 0, 5 ) livesDots[i]:setFillColor( 1, 1, 1 ) livesDots[i].x = centerX+242 + (i-1) \* 18 livesDots[i].y = \_T+50 sceneGroup:insert( livesDots[i] ) end -- show() local myTable = {} myTable.sceneNumber = "1" myTable.livesNumber = numOfLives loadsave.saveTable(myTable, "myTable.json")

This is what I’m trying to do right now, the LivesDots works fine, thanks @roaminggamer, but when I came back to scene after loosing I get an error saying numOfLives must be a number

if I add a “tomumber(numOfLives)” instead of “numOfLives” to “myTable.json”, the error disappears, but when I returned to the scene I have the same 3 livesDots

I’m sure I can see the problem in situ, but I don’t want to try to work it out here.

Zip up your project AS IS and attach the zip file here.

I’ll show you what you’re doing wrong.

PS - Do you know how to diff files?

I ask because I’ll provide your original file(s) and modified one(s).  I will expect you to diff them to see what was changed.

PPS - You’re and OSX user right?

@roaminggamer, thanks but… I’m a Windows user…I’m not used to publishing content in a way that everyone can see and modify. Believe me, I would like to do it!! but my ethics tells me NO, and it is something very personal.

I can’t help if I can’t see the code in situ.  

I’m not clear how a mod to the Star Explorer game is an ethics problem.  This is about learning and not money right?

If you’re doing this to learn and not to make money you can email me the entire project here (again, in a zip file):

rgemail.png

Note: I don’t generally give free debugging  help if folks are using that to make money.

If you want or need to go it alone consider:

  1. Scope & visibility. - Your variable is probably in the wrong place.
  2. Don’t create()/destroy() use enter()/exit() instead - If you’re re-entering the scene, I suggest creating in the will phase of enter and destroying in the did phase of exit.  Others will give other advice, that is fine.  This is what I do and it always works for me.

thanks @roaminggamer, but to follow your rules I will not send the .rar at this time because…

  1. I’m doing this to make money

  2. I use some print statements and see that the error was an empty json table, no value, no numOfLifes, scope :wacko: .

At this moment I am very grateful for the help you offered me, and I’m writing this wholeheartedly, because I respect you very much as a professional, as well as all the people who take time to help newbies like me.

I also take your work very seriously here as “hire a hitman” but I prefer to leave it for when something really gets out of my hands.

@roaminggamer or @all

I just realized that by using @roaminggamer code instead of having 3 lives I have 4.

local function updateLives( event ) -- Remove Pip/Dot if( numLives \> 0 ) then display.remove( lives[numLives] ) numLives = numLives - 1 end if( numLives \<= 0 ) then local options = { effect = "crossFade", time = 100 } composer.gotoScene( "levels.menu", options ) end end

the thing is every time I lose a live, a dot disappear, but the last time, its suppose to remove last dot and go to menu scene, but no, I get another chance to play the game scene with no dots.

any advice?

Thanks DoDi