Help with removing a display object inside of a function

I have a variable

local group

then inside the createScene I have the display objects

group = display.newGroup()     jockey1 = display.newImage ("horse1.png")     group:insert ( jockey1 )                              -- I think I'm inserting the image here     jockey1.x = 10; jockey1.y = 108     jockey1:scale (.8, .8)     jockey1:setReferencePoint( display.CenterRightReferencePoint )     jockey1.win = false

All the jockeys 1 to 6

Then I use the jockey in this function

local function decideWinner () if jockey1.x \>= 1000 then     if jockey1.win == false then         jockey1.win = true         horse\_place = 1         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 1     end end

And also in this other function

local function rollDice()         if imageGroup[1] ~= nil then               imageGroup[1]:removeSelf()         end         local newImage = display.newImage(dicesPictures[getDice])        imageGroup:insert(newImage)         newImage.x = 911;  newImage.y = 715               if getDice == 1 then                 audio.play(diceSound2)                   jockey1.x = jockey1.x + 100         elseif getDice == 2 then                 audio.play(diceSound1)                 jockey1.x = jockey1.x + 50                 jockey2.x = jockey2.x + 50

I use them in two functions – decideWinner, and rollDice

so in the exitScene I remove the runtime, and the EventListener

Runtime:removeEventListener("enterFrame", decideWinner)         buttonRoller:removeEventListener("tap", rollDice)

And I get this error

File: ERROR

ERROR: nil key supplied for property lookup.

I don’t know what’s going on. I paid someone $25.00 to help me out with this problem…

I guess he didn’t know how to do it,… he just stop answering my e-mails

There they go…flying away $25.00 dollars…

Thanks for all the help

If you want Storyboard to manage your assets, then you need to have group defined in each of the four listener functions as:

     local group = self.view

This gives you the display group for the scene and is where you need to put your display objects.

Hi Rob.

I went to Corona Jobs. I found someone. I gave him $25.00. He was supposed to help me out with this problem.

He stop answering my e-mails. He wrote some code for me. It works fine. Except for the removing of the objects.

He wrote this

local group = display.newGroup() -- I think this is a table, I don't know why     jockey1 = display.newImage ("horse1.png")     group:insert ( jockey1 )     jockey1.x = 10; jockey1.y = 108     jockey1:scale (.8, .8)     jockey1:setReferencePoint( display.CenterRightReferencePoint )     jockey1.win = false

But then at the beginning of the createScene is the group that you mention

function scene:createScene( event )     local group = self.view

So the display objects (jockey1 to jockey6)

are inserted, maybe it’s because they have the same name “group”

But if I change the name…which objects goes in the table, and which objects goes in the group = self.view?

Would you mind looking at the complete code

-- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- -- Little Racecourse -- By Victor M. Barba -- Copyright 2013 -- All Rights Reserved -- -- Version 1.0 -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[STORYBOARD REQUIRE]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ local storyboard = require( "storyboard" ) local widget = require "widget" local scene = storyboard.newScene() local horse\_place = 0 local winGroup local imageGroup --local group local buttonHorseShoe local buttonPlayerRound local buttonHorse local buttonMoney local buttonRoller local jockey1 local jockey2 local jockey3 local jockey4 local jockey5 local jockey6 ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[CREATE SCENE]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ function scene:createScene( event )     local group = self.view           local background = display.newImage ("bg1.png")     group:insert ( background ) ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[LOAD SOUNDS]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ local diceSound1 = audio.loadSound( "sound1.mp3") local diceSound2 = audio.loadSound( "sound2.mp3") local backgroundMusic = audio.loadStream ("backgroundSound.mp3") ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[VARIABLES]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ local horse\_count = 0 local horse\_previous = 1 local winner = 0 local winTable = {"bigNumberOne.png", "bigNumberTwo.png", "bigNumberThree.png", "bigNumberFour.png", "bigNumberFive.png", "bigNumberSix.png"} winGroup = display.newGroup() -- holds all the images for winning local dicesPictures = {"dice1.png", "dice2.png", "dice3.png", "dice4.png", "dice5.png", "dice6.png", "dice7.png", "dice8.png", "dice9.png", "dice10.png", "dice11.png", "dice12.png", "dice13.png", "dice14.png", "dice15.png", "dice16.png", "dice17.png", "dice18.png", "dice19.png", "dice20.png", "dice21.png"} local getDice = math.random(1,#dicesPictures) imageGroup = display.newGroup()     local group = display.newGroup()     jockey1 = display.newImage ("horse1.png")     group:insert ( jockey1 )     jockey1.x = 10; jockey1.y = 108     jockey1:scale (.8, .8)     jockey1:setReferencePoint( display.CenterRightReferencePoint )     jockey1.win = false          jockey2 = display.newImage ("horse2.png")     group:insert ( jockey2 )     jockey2.x = 10; jockey2.y = 205     jockey2:scale (.8, .8)     jockey2:setReferencePoint( display.CenterRightReferencePoint )     jockey2.win = false          jockey3 = display.newImage ("horse3.png")     group:insert ( jockey3 )     jockey3.x = 10; jockey3.y = 308     jockey3:scale (.8, .8)     jockey3:setReferencePoint( display.CenterRightReferencePoint )     jockey3.win = false          jockey4 = display.newImage ("horse4.png")     group:insert ( jockey4 )     jockey4.x = 28; jockey4.y = 412     jockey4:scale (.8, .8)     jockey4:setReferencePoint( display.CenterRightReferencePoint )     jockey4.win = false          jockey5 = display.newImage ("horse5.png")     group:insert ( jockey5 )     jockey5.x = 10; jockey5.y = 518     jockey5:scale (.8, .8)     jockey5:setReferencePoint( display.CenterRightReferencePoint )     jockey5.win = false          jockey6 = display.newImage ("horse6.png")     group:insert ( jockey6 )     jockey6.x = 10; jockey6.y = 625     jockey6:scale (.8, .8)     jockey6:setReferencePoint( display.CenterRightReferencePoint )     jockey6.win = false      ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[FUNCTIONS]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ local function buttonHorseShoeHandler()          for i = 1, winGroup.numChildren do             winGroup[1]:removeSelf()         end                          storyboard.gotoScene( "mainMenu", "flip", 200 )         return true end local function buttonPlayerRoundHandler()                  for i = 1, winGroup.numChildren do             winGroup[1]:removeSelf()         end                  storyboard.gotoScene( "playersMenu", "flip", 200 )         return true end local function buttonHorseHandler()                  for i = 1, winGroup.numChildren do             winGroup[1]:removeSelf()         end                  storyboard.gotoScene( "horsesMenu", "flip", 200 )         return true end local function buttonMoneyHandler()                  for i = 1, winGroup.numChildren do             winGroup[1]:removeSelf()         end                  storyboard.gotoScene( "buyMenu", "flip", 200 )         return true end local function decideWinner () if jockey1.x \>= 1000 then     if jockey1.win == false then         jockey1.win = true         horse\_place = 1         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 1     end end if jockey2.x \>= 1000 then     if jockey2.win == false then         jockey2.win = true         horse\_place = 2         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 2     end end if jockey3.x \>= 1000 then     if jockey3.win == false then         jockey3.win = true         horse\_place = 3         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 3     end end if jockey4.x \>= 1000 then     if jockey4.win == false then         jockey4.win = true         horse\_place = 4         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 4     end end if jockey5.x \>= 1000 then     if jockey5.win == false then         jockey5.win = true         horse\_place = 5         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 5     end end if jockey6.x \>= 1000 then     if jockey6.win == false then         jockey6.win = true         horse\_place = 6         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 6     end end if horse\_count == horse\_previous then     --local win = display.newImage(winTable[horse\_count], true)     local win = display.newText("Horse " .. horse\_place  .. " Came In " .. horse\_count .. " Place!", 400, 400, "Arial", 36)     win.x = 300; win.y = 200     winGroup:insert(win)     audio.play( firstplacesound )     horse\_previous = horse\_previous + 1     transition.to(win, {delay = 1000, time = 500, alpha = 0}) end if horse\_count == 6 then     Runtime:removeEventListener("enterFrame", decideWinner)     local win = display.newText("Horse " .. winner .. " Won the Race!", 400, 400, "Arial", 36)     win.x = 512; win.y = 400     winGroup:insert(win) end end Runtime:addEventListener("enterFrame", decideWinner) local function rollDice()         if imageGroup[1] ~= nil then               imageGroup[1]:removeSelf()         end         local newImage = display.newImage(dicesPictures[getDice])        imageGroup:insert(newImage)         newImage.x = 911;  newImage.y = 715               if getDice == 1 then                 audio.play(diceSound2)                   jockey1.x = jockey1.x + 100         elseif getDice == 2 then                 audio.play(diceSound1)                 jockey1.x = jockey1.x + 50                 jockey2.x = jockey2.x + 50         elseif getDice == 3 then                 audio.play(diceSound1)                 jockey1.x = jockey1.x + 50                 jockey3.x = jockey3.x + 50         elseif getDice == 4 then                 audio.play(diceSound2)                 jockey1.x = jockey1.x + 50                 jockey4.x = jockey4.x + 50         elseif getDice == 5 then                 audio.play(diceSound1)                 jockey1.x = jockey1.x + 50                 jockey5.x = jockey5.x + 50         elseif getDice == 6 then                 audio.play(diceSound2)                 jockey1.x = jockey1.x + 50                 jockey6.x = jockey6.x + 50         elseif getDice == 7 then                 audio.play(diceSound1)                 jockey2.x = jockey2.x + 100         elseif getDice == 8 then                 jockey2.x = jockey2.x + 50                 jockey3.x = jockey3.x + 50                 audio.play(diceSound2)         elseif getDice == 9 then                 jockey2.x = jockey2.x + 50                 jockey4.x = jockey4.x + 50                 audio.play(diceSound1)         elseif getDice == 10 then                 jockey2.x = jockey2.x + 50                 jockey5.x = jockey5.x + 50                 audio.play(diceSound2)         elseif getDice == 11 then                 jockey2.x = jockey2.x + 50                 jockey6.x = jockey6.x + 50                 audio.play(diceSound1)         elseif getDice == 12 then                 jockey3.x = jockey3.x + 100                 audio.play(diceSound1)         elseif getDice == 13 then                 jockey3.x = jockey3.x + 50                 jockey4.x = jockey4.x + 50                 audio.play(diceSound2)         elseif getDice == 14 then                 jockey3.x = jockey3.x + 50                 jockey5.x = jockey5.x + 50                 audio.play(diceSound1)         elseif getDice == 15 then                 jockey3.x = jockey3.x + 50                 jockey6.x = jockey6.x + 50                 audio.play(diceSound2)         elseif getDice == 16 then                 jockey4.x = jockey4.x + 100                 audio.play(diceSound1)         elseif getDice == 17 then                 jockey4.x = jockey4.x + 50                 jockey5.x = jockey5.x + 50                 audio.play(diceSound2)         elseif getDice == 18 then                 jockey4.x = jockey4.x + 50                 jockey6.x = jockey6.x + 50                 audio.play(diceSound1)         elseif getDice == 19 then                 jockey5.x = jockey5.x + 100                 audio.play(diceSound2)         elseif getDice == 20 then                 jockey5.x = jockey5.x + 50                 jockey6.x = jockey6.x + 50                 audio.play(diceSound1)         elseif getDice == 21 then                 jockey6.x = jockey6.x + 100                 audio.play(diceSound1)         end         getDice = math.random(1,#dicesPictures)        return true end          buttonRoller = display.newImage ("buttonRoller.png")     group:insert ( buttonRoller )     buttonRoller.x = 730     buttonRoller.y = 715     buttonRoller:addEventListener("tap", rollDice)          buttonHorseShoe = widget.newButton{     defaultFile="buttonHorseShoe.png",     onRelease = buttonHorseShoeHandler     }     group:insert ( buttonHorseShoe )     buttonHorseShoe.x = 440     buttonHorseShoe.y = 730          buttonPlayerRound = widget.newButton{     defaultFile="buttonPlayerRound.png",     onRelease = buttonPlayerRoundHandler     }     group:insert ( buttonPlayerRound )     buttonPlayerRound.x = 490     buttonPlayerRound.y = 680          buttonHorse = widget.newButton{     defaultFile="buttonHorseRound.png",     onRelease = buttonHorseHandler     }     group:insert ( buttonHorse )     buttonHorse.x = 560     buttonHorse.y = 680          buttonMoney = widget.newButton{     defaultFile="buttonMoney.png",     onRelease = buttonMoneyHandler     }     group:insert ( buttonMoney )     buttonMoney.x = 605     buttonMoney.y = 730 end ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[EXIT SCENE]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ function scene:exitScene()         for i = 1, winGroup.numChildren do             winGroup[1]:removeSelf()         end                    if imageGroup[1] ~= nil then             imageGroup[1]:removeSelf()         end              imageGroup:removeSelf()         getDice = nil                  winGroup:removeSelf()         winGroup = nil                           Runtime:removeEventListener("enterFrame", decideWinner)                end ------------------------------------------------------------------------------------------ -- --==\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*[DESTROY SCENE]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*++-- -- ------------------------------------------------------------------------------------------ function scene:destroyScene( event )     local group = self.view                  if buttonHorseShoe then             buttonHorseShoe:removeSelf()             buttonHorseShoe = nil         end                  if buttonPlayerRound then             buttonPlayerRound:removeSelf()             buttonPlayerRound = nil         end                      if buttonHorse then             buttonHorse:removeSelf()             buttonHorse = nil         end                      if buttonMoney then             buttonMoney:removeSelf()             buttonMoney = nil         end                  if buttonRoller then             buttonRoller:removeSelf()             buttonRoller = nil         end                                 end ---------------------------------------------------------------------------------- scene:addEventListener( "createScene", scene ) scene:addEventListener( "exitScene", scene ) scene:addEventListener( "destroyScene", scene ) return scene --[[local sheetDataFunny = {width=80, height=175, numFrames=8}         local imageSheetFunny = graphics.newImageSheet("funnySprite1.png", sheetDataFunny)         local sequenceDataFunny = {             { name="walking", start=1, count=8, time=1000}         }         local funny = display.newSprite(imageSheetFunny, sequenceDataFunny)         group:insert ( funny )         funny.x = 270; funny.y = 80,         funny:scale (.9, .9)         funny:setSequence("walking")         funny:play()                  ]]--

Thank you Rob. And I don’t know if I can trust in Corona Jobs.

This line needs to go:   local group = display.newGroup()

It’s overriding the scene’s display group and is likely your problem.

Thanks Rob.

I remove that line…gone!

still the same problem here

if jockey1.x \>= 1000 then     if jockey1.win == false then         jockey1.win = true         horse\_place = 1         horse\_count = horse\_count + 1     end     if winner == 0 then         winner = 1     end end

This is line 159

if jockey1.x \>= 1000 then

And I get this error

File: …ormbarba/Desktop/Racetrack Plus/workingPlayRace2.lua
Line: 159

Attempt to compare number with nil
 

I don’t get it.

Read the error:   Attempt to compare a number with a nil.

Look at the line:  Can 1000 be nil here?  No, it’s a number.  jockey1.x however can be nil and obviouslly one of the two values is nil.  So why is jockey1 or jockey1.x nil?  If you can figure that out, then you can solve the problem.  I would put some prints at the top of decideWinner() and print out jockey1 and jockey1.x and see which is nil.   Then you need to determine why it’s nil since they are obviously getting created or it would have error-ed out higher up. 

The decideWinner() function is getting called in your enterFrame handler which mean’s it’s getting called 30 times per second (or perhaps 60 if you set the app to run at 60fps) and I don’t see anything obvious in there that is nilling out jockey1.

You will have to add some print statements and see where jockey1 is getting trashed.

Hi Rob. I think we are almost there…

I moved some variables out of the createScene.

And I notice that when the race start… the 6 horses are moving… to reach the 1000 x line

There is a function that is waiting to decide who wins…

If I finish the race, and ALL the 6 images have reached the 1000 x line, I go to another scene, and the images are gone! PERFECT.

The problem is if people go to another scene, in the middle of the race.

I remember somewhere that you can cancel a function. Maybe I need that. Can you tell me what it;s the function to cancel something – like in the exitScene put

if any jockey is > 1000 then

     cancel the decideWinner function or removeRuntime Listener

end

something like that.

Thanks

Runtime:removeEventListener(“enterFrame”, whateveryourfunctionis)

It’s easier to just copy the Runtime:addEventListener call and change “add” to “remove” where you want it to stop running at.

Hi Rob.

I think finally I got it. Thanks to everything you have told me.

But I had to do a lot of thinking. I did not sleep last night.

in the exitScene I had the remove Listener, but still kept on calling the decideWinner function

where I had the “if” statements that had the problem.

So I decided to put the remove Listener also, inside each of the functions that takes me to another scene.

So when I press the button, to go to another scene…

the program will run {thisFuntion}

so inside that function I put removeEventListener also…

But it did not work —

So I remember you told me once that I had to make the local or global variables so the program can read those from different places…

I changed the decide winner function for global

and put it on the very top of the program

so the decideWinner can be read from anywhere…

I put the removeEventListener right after the storyboard.gotoScene

And it works! I think finally we got it. Yes!

Now I will keep working in the next step…

Thanks for everything Rob.