How to access a table inside of another table

Hello all, I have my objects created in table balloons. The objects name is balloon. I put table balloons inside of localGroup. Now when the player runs out of darts I want to remove whatever balloon are left on screen before building the next level. The problem I am having is I don’t know how to access the table balloons inside of localGroup to remove the remaining balloon objects on screen. Here is my code…
[lua]function buildLevel(level)

local len = table.maxn(level)
balloons:toFront()

for i = 1, len do
for j = 1, W_LEN do
if(level[i][j] == 1) then
local balloon = display.newImage(“Blue_Base_Shadows.png”)
balloon.name = “balloon”
balloon.x = BALLOON_W * j - OFFSET
balloon.y = BALLOON_H * i

physics.addBody(balloon, {density = .5, friction = 0, bounce = 0, radius= 15})
balloon.bodyType = ‘static’
balloons.insert(balloons, balloon)

end
end
end
spawnScreenDarts()
end
-------then in the initialize function I do this
localGroup:insert(balloons)
----then I call this function
function changeLevel(event)
if dartsLeft == 0 or balloons.numChildren == 0 then
print(dartsLeft)
print(localGroup.numChildren)
localGroup:remove(balloon)

end
end

-----then in the initialize function I call changeLevel at runtime

Runtime:addEventListener(“enterFrame”, changeLevel)
[import]uid: 49863 topic_id: 29523 reply_id: 329523[/import]

I’m a noob so I may be missing the scope of the challenge with what you’re attempting.

Couldn’t you use a for loop to cycle through your balloons table removing each balloon object and setting it to nil?

[lua]for i = 1, #balloons do
balloons[i]:removeSelf()
balloons[i] = nil
end[/lua]

[import]uid: 105707 topic_id: 29523 reply_id: 118502[/import]

Hello EHO, I tried doing that. My only assumption is that you can’t do that because balloons belongs to localGroup now. I am trying to figure out how to access balloons table inside of localGroup. [import]uid: 49863 topic_id: 29523 reply_id: 118509[/import]

So that didn’t work?

I was under the impression that the group is just an association. Kind of like a flag or something. I would think you could still access and manipulate the table… [import]uid: 105707 topic_id: 29523 reply_id: 118515[/import]

Nah I couldn’t get that to work. [import]uid: 49863 topic_id: 29523 reply_id: 118529[/import]

Newb here too.

Could the problem be that you are iterating “forward” through the balloons table and there are missing balloons that stop the iteration?

Maybe try to iterate “backwards” through the table like this and see if it works.

 for i = balloons.numChildren, 1, -1 do  
 balloons:remove(i)  
 balloons[i] = nil  
 end  

Not sure if this will work, but worth a try?

Not sure how you are removing each balloon when it is popped. If you were simply declaring each balloon[i].isVisible = false on each pop, I think iterating forwards through the table, like the code posted above would work.

Hope this helps and doesn’t cause more confusion.

Nail [import]uid: 106779 topic_id: 29523 reply_id: 118570[/import]

Hey xnailbender, Thank you that does work. If you were wondering about the proper programming term for that it’s called recursion. I had tried that before but I was removing the balloons on collision so there were gaps. Once I used the .isVisible = false to remove the balloons it started working. Thanks guys for your insight on this. This problem is resolved. [import]uid: 49863 topic_id: 29523 reply_id: 118682[/import]

COOL!!! Glad it worked.

I utilize the .isVisible = false technique for pretty much everything and then clean up afterwards.

“Recursion”, got it.

Someday maybe I’ll actually be a programmer. For now, I’m happy with the “progNewber” status. and actually very proud of it. :slight_smile:

Nail

[import]uid: 106779 topic_id: 29523 reply_id: 118726[/import]

Glad to hear a solution was figured out. Although I was vaguely aware of the .isVisible property, I would not have thought of that as a solution (change visibility and then clean up afterwards). I’m glad to be able to add that to my “tool kit” of techniques.

Now that I understand the problem, I’ve realized I’ve solved this in the past by removing the table space in question and then moving any spots after it forward one.

Here’s an example where event.other is the table in question:

[lua]creep[i].num = i --when I spawn my creeps I assign them a “num” value[/lua]
[lua]if event.other.hitpoints <= 0 then
local num = event.other.num
event.other:removeSelf()
if num ~= #creep then – if not the last value in the table
for i = num, #creep - 1 do
creep[i] = creep[i + 1] – shift the next spot forward
creep[i].num = i
end
end
creep[#creep] = nil – nil out the last value in the table[/lua] [import]uid: 105707 topic_id: 29523 reply_id: 118733[/import]

Well I thought this issue was resolved however it is not. For some reason when I do this and I continue on to try and build the level again. I get this error.
Bad argument #1 to ‘maxn’ (table expected, got nil) [import]uid: 49863 topic_id: 29523 reply_id: 118899[/import]

crazypsycho wrote: Bad argument #1 to ‘maxn’ (table expected, got nil)

Without the code, I’m guessing you nil’d out the display group “balloons”.

If you have the line: balloons = nil ,then you need to create the display group again.

To clean up the popped balloon’s at the end of the level, I think you could do something like this:

if #balloon ~= nil then  
 for i = 1, #balloon do  
 display.remove(balloon[i])  
 balloon[i] = nil  
 end  
end  
  
for i = balloons.numChildren, 1, -1 do  
 balloons:remove(i)  
 balloons[i] = nil  
end  

I think you need to return balloon after you spawn the balloon. I’m not sure about line35 either: localGroup:remove(balloon) , is that right?

Nail
[import]uid: 106779 topic_id: 29523 reply_id: 118942[/import]

I should of posted the code for changing levels. Here it is. As far as I can tell we iterate through the balloons table and remove everything then we change the gameState so the code in the update function isn’t called anymore. Then we rebuild the level. I am not sure why this isn’t working.
[lua]—this appears in the update function
if balloons.numChildren ~= 0 and dartsLeft == 0 then
gameState = “removing balloons”
timer.performWithDelay(20, changeLevel(), 1)
end


---------------change levels---------------------------------------------------

local createLevel = function()
print(“in createLevel”)
gameState = “creating level”
currentLevel = currentLevel + rotDirection
changeLevel2(levels[currentLevel])

end

function changeLevel2(level)
print(“in changelevel2”)
buildLevel(level)
end

function changeLevel(event)

gameState = “changing level”
timer.performWithDelay(30000, clearScreen(), 1)

end

function clearScreen()

for i = balloons.numChildren, 1, -1 do
balloons:remove(i)
–balloons[i] = nil
end

timer.performWithDelay(20,createLevel(), 1)
return true

end
[import]uid: 49863 topic_id: 29523 reply_id: 119117[/import]

I have tried both with line 34 in and comment out and neither works. [import]uid: 49863 topic_id: 29523 reply_id: 119118[/import]

Bump [import]uid: 49863 topic_id: 29523 reply_id: 119223[/import]

It looks like it just keeps running through buildLevel until there is nothing left and then receives the error. [import]uid: 49863 topic_id: 29523 reply_id: 119285[/import]

I have used print statements. Everything is firing. I tried using the method you showed and I got a bug "attempt to get length of global ‘balloon’ a nil value. The problem is not that everything isn’t firing. The problem is that everything is firing too much. Instead of it just creating the next level it creates all of the levels one right after another until the current level is higher than the last level creating the maxn bug. [import]uid: 49863 topic_id: 29523 reply_id: 119295[/import]

@crazy…try putting print statements in your functions to see if they are being called and executing, that way you’ll know if functions are firing and where your code is stopping.

I’m not sure if you declare your clearScreen() as local. Your function may not be in scope of the timer function that is calling it.

Also, why don’t you try removing balloon first like I posted above and then clear the balloons display group?

Nail [import]uid: 106779 topic_id: 29523 reply_id: 119292[/import]

Bump [import]uid: 49863 topic_id: 29523 reply_id: 119454[/import]

OK I worked out this issue. What you do is instead of calling the start to these events in the update function you call them as an event listener then before you change the level you remove the event listener and start it again after the level is built. Since I am comparing to the amount of darts the player has left once I restart the amount of darts left to 3 the listener wont get called again until the player is back down to no darts left. [import]uid: 49863 topic_id: 29523 reply_id: 119458[/import]

I’m not sure I totally followed that but I’d like to understand your solution. Can you post a code example of how you solved this? Thanks! [import]uid: 105707 topic_id: 29523 reply_id: 119471[/import]