How do you access display objects in a display group using the display object's variable name?

Having read the docs it seems that it should be possible to do this:

Object References

Because objects can be reordered in the hierarchy, using integer
indices to access display group children is fragile. If you move a child
above its sibling, all integer indices in your code must be updated.

In most cases, it’s easiest to refer to a display object by its variable name. Variables can be named whatever you wish except for names that begin with a number or names that are reserved by Lua or Corona. These naming rules apply to all variables in Lua, so please commit them to memory.

This would lead me to believe that the following works:

local g = display.newGroup() local rect = display.newRect(g, 0, 0, 50, 50) print(g[1]) -- Prints table reference to rect print(g[rect]) -- Prints nil but it should work?

I think I am misunderstanding something. I have had a look at the lua-users wiki Table Tutorial but that has not really helped me.

What I am ultimately trying to do is put 25 tiles (each tile is a display group containing 3 images) into another display group for organizational purposes so that I can reference the tile display groups by key and thus manipulate them. As the doc suggest using indexes is not really suitable for this kind of task because inserting new tiles into the group changes the order of the tiles in the table. 

You could put g.rect = rect in line 3. Then your demo would work.

edit: You would have to change line 5 to: print(g.rect) I reckon.

Another handy trick is to loop through a display group:

[lua]

for i = 1, g.numChildren do

   local child = g[i]

end

[/lua]

Thanks Jon!

If I store my display objects as a properties of the display group, i.e I am not using the g:insert(dispObj) method to insert display objects, does the display group retain all of its functionality as if I had used the insert method? Are there any gotchas associated with assigning display objects as properties of display groups in this way?

When you specify the group in the first argument in newRect like you are doing it puts it in the group for you. Its just the same as doing g:insert(rect).

No special gotchas in doing g.rect = rect except when you choose your name you could possible overwrite something like g.width or g.rotate etc.

Perhaps you have thought of it, but If you want some easy way to reference your tiles in an organized manner maybe use a table, something like this.

[lua]local g = display.newGroup()

local tiles = {}

for i = 1, 20 do

    

    for x = 1, 3 do

        if not tiles[i] then tiles[i] = {} end

        tiles[i][x] = display.newRect(g, 0, 0, 50, 50)

    end

end

– Access row 3, tile 2

print(tiles[3][2])

[/lua]

I took a similar approach initially. I used the display group to the store the tiles and used a separate table to hold the tiles for easy reference (apart from I used a single table and not a 2d table). I was actually looking to only use the display group to organise the tiles to reduce the complexity especially because I plan on moving the tiles across different display groups and I don’t want to have to also update the other table in which they are referenced.

You could put g.rect = rect in line 3. Then your demo would work.

edit: You would have to change line 5 to: print(g.rect) I reckon.

Another handy trick is to loop through a display group:

[lua]

for i = 1, g.numChildren do

   local child = g[i]

end

[/lua]

Thanks Jon!

If I store my display objects as a properties of the display group, i.e I am not using the g:insert(dispObj) method to insert display objects, does the display group retain all of its functionality as if I had used the insert method? Are there any gotchas associated with assigning display objects as properties of display groups in this way?

When you specify the group in the first argument in newRect like you are doing it puts it in the group for you. Its just the same as doing g:insert(rect).

No special gotchas in doing g.rect = rect except when you choose your name you could possible overwrite something like g.width or g.rotate etc.

Perhaps you have thought of it, but If you want some easy way to reference your tiles in an organized manner maybe use a table, something like this.

[lua]local g = display.newGroup()

local tiles = {}

for i = 1, 20 do

    

    for x = 1, 3 do

        if not tiles[i] then tiles[i] = {} end

        tiles[i][x] = display.newRect(g, 0, 0, 50, 50)

    end

end

– Access row 3, tile 2

print(tiles[3][2])

[/lua]

I took a similar approach initially. I used the display group to the store the tiles and used a separate table to hold the tiles for easy reference (apart from I used a single table and not a 2d table). I was actually looking to only use the display group to organise the tiles to reduce the complexity especially because I plan on moving the tiles across different display groups and I don’t want to have to also update the other table in which they are referenced.

Does g.rect=rect here work like g:insert(rect), but the display object gets the key “rect” in the table, so it can be accessed in another function that only has g? That is what I would like to do and it would be very neat. :) 

No, putting g.rect = rect would not physically insert the display object into the display group. It would simply make the reference to the display object a member of the group table, but not insert the object itself.

You could do something like this:

[lua]

local g = display.newGroup()

g.myObjects = {}  – setup a table belonging to the display group

for a = 1 , 10 , 1 do

      local rect = display.newRect(g, 0 , 0 , 50 , 50 )

      rect.id = a

      rect.name = “RECTANGLE”

      g.myObjects[#g.myObjects+ 1] = rect  – insert reference to the rect within the display group table

end

print (“NAME: " …g.m yObjects[4] .n ame. .” ID: " …g.m yObjects[4].id)

 – now you can reference the objects in a function than only has access to g

[/lua]

Thanks :slight_smile: Well, what I’m after is getting the displayObject by reference and not index. I.e. g[“rect”] or g.rect without having to iterate through all the displayObjects in the group. Is that possible? It would be neater than keeping track of them in a separate table.

In that case you just do g.rect = rect, but you have to also insert the display object in the group. So you have the actual object as a child of ‘g’, and in addition a reference to the object as another child of ‘g’, which you can address directly as g.rect rather than looping through g to find it.

g.rect will actually be a pointer to say g[1] or g[7] (depending on when you insert and what other objects are in ‘g’), rather than the object itself.

Will r=g.rect r:setFillColor(), r.alpha=1 etc still work?

Yup, don’t see why not.

Although you’d want to make r local so that that reference is deleted from memory when the function ends.

Does g.rect=rect here work like g:insert(rect), but the display object gets the key “rect” in the table, so it can be accessed in another function that only has g? That is what I would like to do and it would be very neat. :) 

No, putting g.rect = rect would not physically insert the display object into the display group. It would simply make the reference to the display object a member of the group table, but not insert the object itself.

You could do something like this:

[lua]

local g = display.newGroup()

g.myObjects = {}  – setup a table belonging to the display group

for a = 1 , 10 , 1 do

      local rect = display.newRect(g, 0 , 0 , 50 , 50 )

      rect.id = a

      rect.name = “RECTANGLE”

      g.myObjects[#g.myObjects+ 1] = rect  – insert reference to the rect within the display group table

end

print (“NAME: " …g.m yObjects[4] .n ame. .” ID: " …g.m yObjects[4].id)

 – now you can reference the objects in a function than only has access to g

[/lua]

Thanks :slight_smile: Well, what I’m after is getting the displayObject by reference and not index. I.e. g[“rect”] or g.rect without having to iterate through all the displayObjects in the group. Is that possible? It would be neater than keeping track of them in a separate table.

In that case you just do g.rect = rect, but you have to also insert the display object in the group. So you have the actual object as a child of ‘g’, and in addition a reference to the object as another child of ‘g’, which you can address directly as g.rect rather than looping through g to find it.

g.rect will actually be a pointer to say g[1] or g[7] (depending on when you insert and what other objects are in ‘g’), rather than the object itself.

Will r=g.rect r:setFillColor(), r.alpha=1 etc still work?