advice on creating temporary group

My game has a different number of balls per level so at the beginning of each level I am populating a group with all the balls being used for that level.

The group that the balls are stored in is declared only once when the game first loads as follows:

  
local allBallsGroup = display.newGroup()  
  

At the outset, I create an array to store all the balls i.e the maximum number of balls that can be displayed in any level (which is 10). The idea is that i can use this array every level to populate the allBallsGroup depending on how many balls are required for the level

  
local ballTable = {}  
   
   
for i = 1, 10 do  
   
 ballTable[i] = display.newGroup()  
   
 local ball1Layer1 = display.newImage(ballTable[i],"ballLayer1.png")  
 local ball1Layer2 = display.newImage(ballTable[i],"ballLayer2.png")  
  
end  
   
  

So for the first level where there are 10 balls required I populate the allBallsGroup as follows:

  
for i = 1, numberOfBallsForLevel do  
  
 allBallsGroup:insert( ballTable[i] )  
  
end  
  

In the game, if a ball goes out of a fixed area it becomes a dead ball and I remove it as follows:

  
if (allBallsGroup[i].x \> 340) then  
  
 allBallsGroup:remove( i )  
  
end  
  

At the end of the level i also remove any remaining balls as follows:

  
local function removeAllBalls()  
  
 for i = allBallsGroup.numChildren, 1, -1 do  
  
 allBallsGroup:remove(i)   
  
 end  
  
end  
  

Now this all works fine so far. The problem occurs when I start the next level and attempt to populate allBallsGroup using the same code as used for the first level

  
for i = 1, numberOfBallsForLevel do  
  
 allBallsGroup:insert( ballTable[i] )  
  
end  
  

I am getting the following error for the line of code that says allBallsGroup:insert( ballTable[i] )

**Runtime error

bad argument #-2 to ‘insert’ (Proxy expected, got nil)**

Any ideas why this is not working and how to fix it?

Thanks

Paul
[import]uid: 7863 topic_id: 2792 reply_id: 302792[/import]

It’s my understanding that when you remove a display object, the graphic will be deleted, leaving an empty table behind.

I have a similar situation. But when I no longer need an item, I remove the graphics, and nil the reference. Then I repopulate the slots that are empty, by inserting a new display object. This technique actually works really well, speed-wise. I also keep copies of the images in another table, to keep them cached. Otherwise, there may be a bit of a noticeable delay upon loading them again.

Mike
[import]uid: 4454 topic_id: 2792 reply_id: 8350[/import]

Those copies have their isVisible set to false, btw. [import]uid: 4454 topic_id: 2792 reply_id: 8352[/import]

Thanks oz-machine

Ah I didn’t realise that is what happens when you remove an item from a group.

I could just repopulate the ballTable array every level but I was attempting to do things as efficiently as possible. I guess repopulating it will not result in any caching benefits. Would I need to just create another table storing all the balls in to ensure a cached copy is always available?

i.e in addition to the ballTable creation create another table as follows and never touch this table again?

  
local ballTableCache = {}  
   
   
for i = 1, 10 do  
   
 ballTableCache[i] = display.newGroup()  
   
 local ball1Layer1 = display.newImage(ballTableCache[i],"ballLayer1.png")  
 local ball1Layer2 = display.newImage(ballTableCache[i],"ballLayer2.png")  
  
end  

Actually thinking about it, as all 10 balls (maximum number required) all use the same 2 images, would the cache table need only 1 element rather than 10?

I guess the other option is to just add an “active” flag for each ball and never remove the balls from the group. It would however I assume have a performance hit as my game logic would need to process an if active == true branch in all scenarios where it is moving and doing collision detection on balls.

Thanks

Paul

[import]uid: 7863 topic_id: 2792 reply_id: 8360[/import]

When you remove a displayobject, normally it is totally removed. Unless you gave that object custom properties. Then Corona removes the reference to the image, removes all default displayobject properties and then leaves a table with your custom properties in memory. This table you have to NIL out to get it collected by the garbage collector. [import]uid: 5712 topic_id: 2792 reply_id: 8363[/import]

Ah I think I get it now.

In my case I have given it custom properties

  
allBallsGroup[i].ballId = i  
allBallsGroup[i].horizontalVelocity = 0  
allBallsGroup[i].verticalVelocity = 0  
  
allBallsGroup[i].xReference = xRef  
allBallsGroup[i].yReference = yRef  
  
allBallsGroup[i][2].xReference = -1  
allBallsGroup[i][2].yReference = -2  
  

So when I remove all balls using the following:

  
local function removeAllBalls()  
   
 for i = allBallsGroup.numChildren, 1, -1 do  
   
 allBallsGroup:remove(i)   
  
 end  
   
end  

Corona is leaving the allBallsGroup table with only the custom properties? And therefore all the images added to ballTable are gone?

Is that correct? [import]uid: 7863 topic_id: 2792 reply_id: 8364[/import]

That’s right. The displayObject becomes a regular table object.

I’d merely keep the two images referenced somewhere before the game begins, and hide them. The creation of new objects is really fast, and as Corona reuses bitmap data, once the image is in the display list somewhere, generating more copies is instantaneous.

Mike [import]uid: 4454 topic_id: 2792 reply_id: 8452[/import]