attempt to index field '?' (a nil value) when I try to remove an object from an object group

Hi so I have a function that adds rectangles in a grid

function draw\_background() for y = 9, -300, -1 do for x = 7, 0, -1 do backX = x backY = y createX = (x \* rectWidth) - 50 createY = (y \* rectHeight) - 72 local rect = display.newRect(createX, createY, rectWidth, rectHeight) rect:setFillColor(0.5) rect.name = (x .. y) mapGroup:insert(rect) end end generate\_moves() end

and I do some calculations to figure out what rectangles I need to remove from the objectGroup. I already have the calculation and detection part working to know what rectangle to remove. I am just stuck with the error attempt to index field ‘?’ (a nil value) from trying mapGroup:remove(d) in this code

function make\_tile(x, y) --function to spawn the tile on the playboard if x \< 1 then --if the tile too far left then spawn it as far left x = 1 elseif x \> 7 then --if the tile is too far right the spawn it as far right x = 7 end tileX = (x \* rectWidth) - 50 --calculations to make the screen a 7x9 tile board with rectangles fitting tileY = (y \* rectHeight) - 72 --rect = display.newRect(tileX, tileY, rectWidth, rectHeight) for d = 1, mapGroup.numChildren do thisTile = mapGroup[d].name if thisTile == x .. "" .. y then mapGroup:remove(d) \<---------------- I get the error from this end end end

Thank you if you can help me out.

Hmm… I didn’t think you could get an error from that, but you’ll surely get a warning from it.

You might want to use display.remove() or removeSelf() to remove display objects. The way how your loop works is that you loop up starting from 1, but whenever a display object is removed using your current method, it shifts all other display objects after it down by one, i.e. if you delete child #1, then child #2 becomes new #1 and so on. If the loop then tried to remove that child #2, it would actually remove child #3 since #2 is now in the place of #1, and now every child shifts down again, etc.

Here’s a visual demonstration via code. 
 

local group = display.newGroup() local txt = {} for i = 1, 10 do txt[i] = display.newText( group, i, 100+i\*20, 100, native.systemFontBold, 16 ) end -- removes every other child for i = 1, group.numChildren do group:remove(i) end -- -- removes every display object and sets them to nil -- for i = 1, group.numChildren do -- display.remove(txt[i]) -- txt[i] = nil -- end

Iterating in reverse generally works around any issues with elements shifting when making holes:

for d = mapGroup.numChildren, 1, -1 do
– etc.
end

Thank you for the help! I ended up moving the tiles off of the screen to y = 2000. Then I now have a function that checks of any tiles y is more than 2000, if so remove it. Richard11’s solution of starting from the top of the array and working backwards removed alot of issues I was getting. Thanks!

Hmm… I didn’t think you could get an error from that, but you’ll surely get a warning from it.

You might want to use display.remove() or removeSelf() to remove display objects. The way how your loop works is that you loop up starting from 1, but whenever a display object is removed using your current method, it shifts all other display objects after it down by one, i.e. if you delete child #1, then child #2 becomes new #1 and so on. If the loop then tried to remove that child #2, it would actually remove child #3 since #2 is now in the place of #1, and now every child shifts down again, etc.

Here’s a visual demonstration via code. 
 

local group = display.newGroup() local txt = {} for i = 1, 10 do txt[i] = display.newText( group, i, 100+i\*20, 100, native.systemFontBold, 16 ) end -- removes every other child for i = 1, group.numChildren do group:remove(i) end -- -- removes every display object and sets them to nil -- for i = 1, group.numChildren do -- display.remove(txt[i]) -- txt[i] = nil -- end

Iterating in reverse generally works around any issues with elements shifting when making holes:

for d = mapGroup.numChildren, 1, -1 do
– etc.
end

Thank you for the help! I ended up moving the tiles off of the screen to y = 2000. Then I now have a function that checks of any tiles y is more than 2000, if so remove it. Richard11’s solution of starting from the top of the array and working backwards removed alot of issues I was getting. Thanks!