Whats The Best Way To Create Objects In A Table And Delete Them.

I have a game where zombies spawn every 2 seconds.

Each Zombie instance has:

  • a timer property that is used for their AI.

  • a deleteMe function that kills the zombie, and removes all of its properties

-  other functions such as attack(), run()… blah blah blah… (you get the point)

Whenever an instance of a Zombie is created, i add it to a TableOfZombies.

My help is this:

Q1 How can i remove a particular Zombie from the table when it is shot dead by the player?

Q2 How can i pause the timer of all the on-screen Zombies when the game is paused?

Q3 (similar to Q2) How can i kill all the Zombies when the game is over?

Heres how i spawn my zombies

function spawnZombie() table.insert(TableOfZombies, newEnemy(math.random(0,4), math.random(1,3), MainCharacter, SpawnLocation[math.random(0,7)], math.random())) GameActionLayer:insert(TableOfZombies[#TableOfZombies]) timer.resume(TableOfZombies[#TableOfZombies].timer) TableOfZombies[#TableOfZombies].Index = ZombieIndex + 1 end

Heres how i delete a particular Zombie when it’s shot

table.remove(TableOfZombies,ThisEnemy.Index)

Heres how i try to pause their time , but i keep getting an error saying: attempt to index a nil value

 for Kount = 1, #TableOfZombies, 1 do if(TableOfZombies[Kount] ~= nil) then timer.pause(TableOfZombies[Kount].timer) end end

Any help will greatly be appriciated… thanks

Hey there!

Q1 How can i remove a particular Zombie from the table when it is shot dead by the player?
     I believe the remove Zombie logic is inside a function? If it is I have a question, how do you manage to save Index?

    To properly remove the zombie on screen you should do this:
    

"first" table.remove(TableOfZombies, ThisEnemy.Index) "second in order to remove the zombie on screen" ThisEnemy:removeSelf() "third in order to release the memory used by that zombie" ThisEnemy = nil "fourth you need to update the index of all zombies on screen" "for example the zombie died has index 4 and there are zombies after that index on screen. If you remove index 4 zombie in the table what will happen is index 5 zombie will take over index 4 but the index stored now in index 4 zombie is still index 5 so you need to update it" for i = #TableOfZombies, 1, -1 do TableOfZombies[i].Index = i end "this should do it"  

Q2 How can i pause the timer of all the on-screen Zombies when the game is paused?
      There are two ways to do this. First looping your TableOfZombies and pausing it 1 by 1 using 

for i = 1, #TableOfZombies do timer.pause(TableOfZombies[index].timer) end

 

      Second way to prevent you having a hard loop on pausing all timers what you will do is do all of the work inside 1 timer only. Yes 1 timer for all zombies or use enterFrame.
 

Q3 (similar to Q2) How can i kill all the Zombies when the game is over?
      The answer relies on question 1 =D. You will do it like this.
 

for i = #TableOfZombies, 1, -1 do TableOfZombies[i]:removeSelf() TableOfZombies[i] = nil table.remove(TableOfZombies, i) end

Hope this helps =)

WOW! thanks i will try this asap.

Greatly appreciated.

I use another approach, if zombie dead - mark it dead and remove from table on update

[lua]

– kill zombie (you also want to hide him )

zombie.dead = true

– on update remove all dead zombies

– make attantion that when you remove something indexes shift down and i could be invalid, 

– so we remove from end, and they shift after new value of i, so its OK

for i = #TableOfZombies, 1, -1 do

    if TableOfZombies[i].dead then

        local z = table.remove(TableOfZombies, i) – remove returns removed item

        z:removeSelf()

    end

end

[/lua]

@Indigo thats another good idea, thanks

Hey there!

Q1 How can i remove a particular Zombie from the table when it is shot dead by the player?
     I believe the remove Zombie logic is inside a function? If it is I have a question, how do you manage to save Index?

    To properly remove the zombie on screen you should do this:
    

"first" table.remove(TableOfZombies, ThisEnemy.Index) "second in order to remove the zombie on screen" ThisEnemy:removeSelf() "third in order to release the memory used by that zombie" ThisEnemy = nil "fourth you need to update the index of all zombies on screen" "for example the zombie died has index 4 and there are zombies after that index on screen. If you remove index 4 zombie in the table what will happen is index 5 zombie will take over index 4 but the index stored now in index 4 zombie is still index 5 so you need to update it" for i = #TableOfZombies, 1, -1 do TableOfZombies[i].Index = i end "this should do it"  

Q2 How can i pause the timer of all the on-screen Zombies when the game is paused?
      There are two ways to do this. First looping your TableOfZombies and pausing it 1 by 1 using 

for i = 1, #TableOfZombies do timer.pause(TableOfZombies[index].timer) end

 

      Second way to prevent you having a hard loop on pausing all timers what you will do is do all of the work inside 1 timer only. Yes 1 timer for all zombies or use enterFrame.
 

Q3 (similar to Q2) How can i kill all the Zombies when the game is over?
      The answer relies on question 1 =D. You will do it like this.
 

for i = #TableOfZombies, 1, -1 do TableOfZombies[i]:removeSelf() TableOfZombies[i] = nil table.remove(TableOfZombies, i) end

Hope this helps =)

WOW! thanks i will try this asap.

Greatly appreciated.

well i tried these methods but i am still getting the error that i am pointing to a nil object

i have a table similer to this with fishes in them and when i kill one of the fish i call removeSelf() on that fish

but when i want to clear all the table i am getting an error

function clearObjects()
 local i = 0;
 print (#R2LObjects)
  for i=#R2LObjects,1,-1 do
   local child = table.remove(R2LObjects, i)    – Remove from table
   if child ~= nil then
   print ("object deleted = "… i)
     child:removeSelf()
     child = nil
   end
  end
 R2LObjects = nil
 R2LObjects = {}
 collectgarbage()

 

end

mtayyar, why are you recreating the table at the end. (Second to last line in the code you posted)?

I use another approach, if zombie dead - mark it dead and remove from table on update

[lua]

– kill zombie (you also want to hide him )

zombie.dead = true

– on update remove all dead zombies

– make attantion that when you remove something indexes shift down and i could be invalid, 

– so we remove from end, and they shift after new value of i, so its OK

for i = #TableOfZombies, 1, -1 do

    if TableOfZombies[i].dead then

        local z = table.remove(TableOfZombies, i) – remove returns removed item

        z:removeSelf()

    end

end

[/lua]

@Indigo thats another good idea, thanks

well i tried these methods but i am still getting the error that i am pointing to a nil object

i have a table similer to this with fishes in them and when i kill one of the fish i call removeSelf() on that fish

but when i want to clear all the table i am getting an error

function clearObjects()
 local i = 0;
 print (#R2LObjects)
  for i=#R2LObjects,1,-1 do
   local child = table.remove(R2LObjects, i)    – Remove from table
   if child ~= nil then
   print ("object deleted = "… i)
     child:removeSelf()
     child = nil
   end
  end
 R2LObjects = nil
 R2LObjects = {}
 collectgarbage()

 

end

mtayyar, why are you recreating the table at the end. (Second to last line in the code you posted)?