Cleaning up Sprites after the leave view

Hello everyone, Okay I got a lot of code working with a lot of all you help !! thanks…

In my levelOne scene I have sprites moving down the screen and when the go off screen I want to be a good newBee and clean up my mess, but the code does not seem to be working, Actually the code only removes the last sprite off the screen to be removed. 

How do I know , well I set the bottom of the screen to be +10 so I can still see if they were cleaned up. 

So what do i do?

Here is my code. 

function scene:create( event )

  local sceneGroup = self.view

  local phase = event.phase

 function timerFunction( )

    tmr = timer.cancel()

      end

function addEnemy( event )

sheetData = { 

  width = 170,

  height = 160,

  numFrames = 10,

  sheetContentWidth = 850,

  sheetContentHeight = 320 }

 mySheet = graphics.newImageSheet(“spritesheet.png”,sheetData)

 sequenceData = {

{ name = “normalRun”,start=1,count=10,time=2200},

{name = “fastRun”,frames = {1,2,3,4,5,6,7,8,9,10},time = animationTime}

}

  animation = display.newSprite(mySheet,sequenceData) 

  animation.x = math.random(20,300)

  animation.y = 160

  animation.xScale = .4

  animation.yScale = .3

  --physics.addBody (animation,“static”,{density= 10,friction= 0,bounce=0})  --,radius=25}) or shape = 

  animation:setSequence(“fastRun”)

  animation:play()

  sceneGroup:insert(animation)

   randomY = (display.contentHeight +10)

  transition.to (animation, {x = animation.x, y = randomY, time = downWardSpeed}) 

        enemieCount = enemieCount + 1

local function removeEnemy( event )

  print (“I made it to removeEnemy”)

     animation:removeSelf()

     animation = nil

    end

if enemieCount < enemiesOnStage then

tmr = timer.performWithDelay(1000,addEnemy)

  elseif enemieCount == enemiesOnStage then

    timer.performWithDelay (4000,removeEnemy)

    timer.cancel(tmr)

  end

end 

addEnemy()


end

After a quick scan of your code, it looks as though “animation” is a global variable which will be overwritten every time you call addEnemy(). So “animation” only keeps track of the last enemy to be created. What you need to do is insert each enemy into a table so that you can then keep track of ALL enemies on the screen. Then when you call the remove function you loop through the table to find all enemies whose Y position is past the screen height, then remove it from display. Don’t forget to remove it from the table as well.

As a tip, if you are removing things from a table in a for loop, it’s usually best to traverse the table starting at the end. If you start at the beginning you run the risk of accessing an index which becomes nil after removing an item.

Okay I understand. What if I just make animation a loca variable ? Then it should work ? Thanks for the help.

Making animation local is a good start but I don’t think it will fix your problem. Here is some pseudocode to help you get started.

function scene:create( event ) local sceneGroup = self.view local phase = event.phase function timerFunction( ) tmr = timer.cancel() end local enemies = {} --create the table hold all your enemies function addEnemy( event ) --blah blah local animation = display.newSprite(mySheet,sequenceData) animation.x = math.random(20,300) animation.y = 160 animation.xScale = .4 animation.yScale = .3 --physics.addBody (animation,"static",{density= 10,friction= 0,bounce=0}) --,radius=25}) or shape = animation:setSequence("fastRun") animation:play() enemies[#enemies+1] = animation --add the enemy to your table --blah blah local function removeEnemy( event ) for i=#enemies, 1, -1 do --traverse the table backwards --this is your condition to check if you need to remove if(enemies[i].y \> display.contentHeight + 10) then local animation = table.remove(enemies,i) --The table.remove function returns the object and reorders the table animation:removeSelf() animation = nil end end end --blah blah end end

Wow !! Great advice i will let you know how it works. Thanks a million. JZ

Vince , thanks so much it worked beautifully  i just had to play with the timer.performDelay (6000, removeEnemy)

and they all disappear !!

Cleaned up 

Thanks again.

JZ 

Excellent! Glad I could help :slight_smile:

After a quick scan of your code, it looks as though “animation” is a global variable which will be overwritten every time you call addEnemy(). So “animation” only keeps track of the last enemy to be created. What you need to do is insert each enemy into a table so that you can then keep track of ALL enemies on the screen. Then when you call the remove function you loop through the table to find all enemies whose Y position is past the screen height, then remove it from display. Don’t forget to remove it from the table as well.

As a tip, if you are removing things from a table in a for loop, it’s usually best to traverse the table starting at the end. If you start at the beginning you run the risk of accessing an index which becomes nil after removing an item.

Okay I understand. What if I just make animation a loca variable ? Then it should work ? Thanks for the help.

Making animation local is a good start but I don’t think it will fix your problem. Here is some pseudocode to help you get started.

function scene:create( event ) local sceneGroup = self.view local phase = event.phase function timerFunction( ) tmr = timer.cancel() end local enemies = {} --create the table hold all your enemies function addEnemy( event ) --blah blah local animation = display.newSprite(mySheet,sequenceData) animation.x = math.random(20,300) animation.y = 160 animation.xScale = .4 animation.yScale = .3 --physics.addBody (animation,"static",{density= 10,friction= 0,bounce=0}) --,radius=25}) or shape = animation:setSequence("fastRun") animation:play() enemies[#enemies+1] = animation --add the enemy to your table --blah blah local function removeEnemy( event ) for i=#enemies, 1, -1 do --traverse the table backwards --this is your condition to check if you need to remove if(enemies[i].y \> display.contentHeight + 10) then local animation = table.remove(enemies,i) --The table.remove function returns the object and reorders the table animation:removeSelf() animation = nil end end end --blah blah end end

Wow !! Great advice i will let you know how it works. Thanks a million. JZ

Vince , thanks so much it worked beautifully  i just had to play with the timer.performDelay (6000, removeEnemy)

and they all disappear !!

Cleaned up 

Thanks again.

JZ 

Excellent! Glad I could help :slight_smile: