Problem removing objects

I am trying to create an attack that spawns multiple walls with small loopholes through them, it is currently a work in progress. I am having trouble removing the objects. After 50 seconds, there is a timer that is supposed to remove the walls, but I keep getting this error at the 50 second mark:

ERROR: Runtime error attack.lua:73: attempt to perform arithmetic on field 'x' (a nil value) stack traceback: attack.lua:73: in function '?' ?: in function \<?:172\>

This is my code:

math.randomseed(os.time()) local lifetime = 50000 local attack = {} function attack.horizontalAttack(blockadeNumber, spaceApart, speed, change) local function moveBlockades(self) --Line 73 if self.x + 15 \> 0 then self.x = self.x - speed end end local function removeBlockades(self) display.remove(self) self:removeEventListener("enterFrame", self) end for i = 1, blockadeNumber do local blockadeBottom = display.newRect(right + (i \* spaceApart), bottom, 15, 200 + (i \* change)) blockadeBottom.anchorY = 1 blockadeBottom:setFillColor(0.56, 0.13, 0.94) --physics.addBody(blockadeBottom, "dynamic", {isSensor = true}) local blockadeTop = display.newRect(blockadeBottom.x, top, 15, 200 - (i \* change)) blockadeTop.anchorY = 0 blockadeTop:setFillColor(0.56, 0.13, 0.94) --physics.addBody(blockadeTop, "dynamic", {isSensor = true}) blockadeBottom.enterFrame = moveBlockades Runtime:addEventListener("enterFrame", blockadeBottom) blockadeTop.enterFrame = moveBlockades Runtime:addEventListener("enterFrame", blockadeTop) blockadeTop.timer = removeBlockades timer.performWithDelay(lifetime, blockadeTop) blockadeBottom.timer = removeBlockades timer.performWithDelay(lifetime, blockadeBottom) end end return attack

I think it is a problem with the removal of the objects and their eventListeners. Any help would be greatly appreciated. Thank you.

Here is a hack I sometimes use to remove objects after a fixed period.

local obj = display.newCircle( 100, 100, 10 ) -- co-opt transition.to() call display.remove() on obj after 10 seconds -- Auto cancelled if object is removed before 10 seconds transition.to( obj, { delay = 10000, time = 0, alpha = 0, onComplete = display.remove } )

or you could do this:

local obj = display.newCircle( 100, 100, 10 ) obj.timer = display.remove timer.performWithDelay( 10000, obj )

If this does not work for you then, you probably do have some listeners or transitions that need to ignored/cancelled.

Post back if you are still stuck after trying the above.

The same error occurs after I try both. I think the problem might be the eventListeners.

Hey, how is ‘function attack.horizontalAttack(blockadeNumber, spaceApart, speed, change)’ called?  

Is that an enterFrame listener?

 SSK2 supplies the solution…

https://roaminggamer.github.io/RGDocs/pages/SSK2/extensions/#display

 local function moveBlockades(self) --Line 73 if( not display.isValid( self ) then return end -- Extended function added by SSK2 if self.x + 15 \> 0 then self.x = self.x - speed end end

It is called like so:

attack.horizontalAttack(100, 20, 10, 15) -- Just normally like attack.fire(turrets\_circle, target)

Sorry having trouble reading the code.  Reviewing again.

Now, this error appears: 

ERROR: Runtime error error loading module 'attack' from file 'attack.lua': attack.lua:73: ')' expected near 'then' stack traceback: [C]: ? [C]: in function 'require' ?: in function 'require' main.lua:8: in main chunk

Oh, ok.

Dude, you can track down the typo right?

look at the code I posted then compare it to this.

if( not display.isValid( self ) ) then return end -- Extended function added by SSK2

Once you type that in, how is it working. OK?  Any more errors?

I think I found the original source of your problem.
 
This is in the wrong order:

 local function removeBlockades(self) display.remove(self) self:removeEventListener("enterFrame", self) -- WRONG NO MATTER WHAT end 

Order of execution is CRITICAL.  Should be:

 local function removeBlockades(self) --self:removeEventListener("enterFrame", self) -- WRONG NO MATTER WHAT ignore( "enterFrame", self ) -- From SSK2 -- Equivalent to: Runtime:removeEventListener( "enterFrame", self ) display.remove(self) end

Key learnings:

  1. Remove listeners, then delete.

  2. ‘enterFrame’ is a Runtime listener, not a table listener, you’re syntax made no sense.  :wacko:

  3. Use SSK2 ignore() and listen() intstead of longhand Runtime:* calls. ick!

One final post by me, this is how I would write the code w/ SSK2

(May contain typos)

local lifetime = 50000 local attack = {} function attack.horizontalAttack(blockadeNumber, spaceApart, speed, change) local function moveBlockades(self) if( autoIgnore( "enterFrame", self ) ) then return end if self.x + 15 \> 0 then self.x = self.x - speed end end local function removeBlockades(self) ignore("enterFrame", self) display.remove(self) end for i = 1, blockadeNumber do local blockadeBottom = ssk.display.newRect( nil, right + (i \* spaceApart), bottom, { w = 15, h = 200 + (i \* change), enterFrame = moveBlockades, anchorY = 1, fill = { 0.56, 0.13, 0.94 } }, { isSensor = true } ) local blockadeTop = ssk.display.newRect( nil, blockadeBottom.x, top, { w = 15, h = 200 - (i \* change), enterFrame = moveBlockades, anchorY = 0, fill = { 0.56, 0.13, 0.94 } }, { isSensor = true } ) blockadeTop.timer = removeBlockades timer.performWithDelay(lifetime, blockadeTop) blockadeBottom.timer = removeBlockades timer.performWithDelay(lifetime, blockadeBottom) end end return attack

Thank you, it works now.

Here is a hack I sometimes use to remove objects after a fixed period.

local obj = display.newCircle( 100, 100, 10 ) -- co-opt transition.to() call display.remove() on obj after 10 seconds -- Auto cancelled if object is removed before 10 seconds transition.to( obj, { delay = 10000, time = 0, alpha = 0, onComplete = display.remove } )

or you could do this:

local obj = display.newCircle( 100, 100, 10 ) obj.timer = display.remove timer.performWithDelay( 10000, obj )

If this does not work for you then, you probably do have some listeners or transitions that need to ignored/cancelled.

Post back if you are still stuck after trying the above.

The same error occurs after I try both. I think the problem might be the eventListeners.

Hey, how is ‘function attack.horizontalAttack(blockadeNumber, spaceApart, speed, change)’ called?  

Is that an enterFrame listener?

 SSK2 supplies the solution…

https://roaminggamer.github.io/RGDocs/pages/SSK2/extensions/#display

 local function moveBlockades(self) --Line 73 if( not display.isValid( self ) then return end -- Extended function added by SSK2 if self.x + 15 \> 0 then self.x = self.x - speed end end