Clearly, something is not properly removed between scenes

I have a character in my game that is made up of several parts. When each part collides with the platform it moves over it makes a dust trail.

The main problem is when I restart the level, the dust trail becomes thicker and thicker for each time, and the performance is getting worse and worse. The memory leakage is about 3kb each restart.

If I comment out the collision EventListener, all is good. No leakage, no performance problems.  Clearly, something is not properly removed between scenes.

Could it be the transistion? No matter how im trying to remove the transistion in the function it will stop other transistions. Probably because it cant distinguish what transistion is what. So to properly distinguish all dust display objects should i insert them in a table? If so, could someone point me in the right direction? 

 I’m using composer with a restart level lua. 

Dust making part in level lua

[lua]

llocal function ferdi()

      display.remove(stov) 

      stov = nil

end

local tran 

local function onCollision2(event)

if event.phase == “began” then

if  (event.object1.type == “del1” and event.object2.type == “firkant1”) or

    (event.object1.type == “del2” and event.object2.type == “firkant1”) or

    (event.object1.type == “del3” and event.object2.type == “firkant1”) or

    (event.object1.type == “del4” and event.object2.type == “firkant1”) or

    (event.object1.type == “del5” and event.object2.type == “firkant1”) or

    (event.object1.type == “del6” and event.object2.type == “firkant1”) or

    (event.object1.type == “del7” and event.object2.type == “firkant1”) or

    (event.object1.type == “del8” and event.object2.type == “firkant1”) or

    (event.object1.type == “del9” and event.object2.type == “firkant1”) or

    (event.object1.type == “del1” and event.object2.type == “firkant2”) or

    (event.object1.type == “del2” and event.object2.type == “firkant2”) or

    (event.object1.type == “del3” and event.object2.type == “firkant2”) or

    (event.object1.type == “del4” and event.object2.type == “firkant2”) or

    (event.object1.type == “del5” and event.object2.type == “firkant2”) or

    (event.object1.type == “del6” and event.object2.type == “firkant2”) or

    (event.object1.type == “del7” and event.object2.type == “firkant2”) or

    (event.object1.type == “del8” and event.object2.type == “firkant2”) or

    (event.object1.type == “del9” and event.object2.type == “firkant2”) or

    (event.object1.type == “del1” and event.object2.type == “firkant3”) or

    (event.object1.type == “del2” and event.object2.type == “firkant3”) or

    (event.object1.type == “del3” and event.object2.type == “firkant3”) or

    (event.object1.type == “del4” and event.object2.type == “firkant3”) or

    (event.object1.type == “del5” and event.object2.type == “firkant3”) or

    (event.object1.type == “del6” and event.object2.type == “firkant3”) or

    (event.object1.type == “del7” and event.object2.type == “firkant3”) or

    (event.object1.type == “del8” and event.object2.type == “firkant3”) or

    (event.object1.type == “del9” and event.object2.type == “firkant3”) or

    (event.object1.type == “del1” and event.object2.type == “firkant4”) or

    (event.object1.type == “del2” and event.object2.type == “firkant4”) or

    (event.object1.type == “del3” and event.object2.type == “firkant4”) or

    (event.object1.type == “del4” and event.object2.type == “firkant4”) or

    (event.object1.type == “del5” and event.object2.type == “firkant4”) or

    (event.object1.type == “del6” and event.object2.type == “firkant4”) or

    (event.object1.type == “del7” and event.object2.type == “firkant4”) or

    (event.object1.type == “del8” and event.object2.type == “firkant4”) or

    (event.object1.type == “del9” and event.object2.type == “firkant4”) then

local   stov        = display.newImageRect(“stov.png”, 20,20)

        stov.width  = 10+(math.random(10, 50)) 

        stov.height = stov.width

        stov.x      = event.object1.x+(math.random(1, 10)) 

        stov.y      = event.object1.y-(math.random(1, 10))

        rot         = (math.random(1,360)) 

        stov.alpha  = 0.5

        stov:rotate( rot )

        grp:insert(stov)

        camera:add (stov,1,false)

tran = transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 0,

                                    time       = 2000,

                                    onComplete = ferdi 

                                    })

–[[               

    if tran ~= nil then

    transition.cancel(tran)

    end

–]]

            return stov

        end

    end

end

Runtime:addEventListener(“collision”, onCollision2)

[/lua]

Function when the caracter “die”

[lua]

local function goto( event )

physics.pause( )

Runtime:removeEventListener(“collision”, onCollision)

Runtime:removeEventListener(“collision”, onCollision1)

Runtime:removeEventListener(“collision”, onCollision2)

composer.showOverlay( “dodmenu1”,{isModal = true,effect = “fade”,time = 500,})

end

[/lua]

Function when tapping restart button

[lua]

local function resume(event)

Runtime:removeEventListener( “touch”, trykk_knapp)

Runtime:removeEventListener( “tap”, trykk_knapp)

composer.gotoScene( “gotolevel1”,{effect = “fade” , time = 1}) 

pausemenu.alpha=0

physics.start()

liv.endreliv(1)

liv.lagreliv()

end

pausemenuretry:addEventListener (“touch”, resume)

[/lua]

gotolevel1 lua

[lua]

local function goto( event )

composer.gotoScene( “level1”,{effect = “fade” , time = 500})  

end

– “scene:show()”

function scene:show( event )

    local sceneGroup = self.view

    local phase = event.phase

    if ( phase == “will” ) then

       

    elseif ( phase == “did” ) then

      

        

timer.performWithDelay( 1500, goto)

    end

end

[/lua]

I have tried to remove the transition, but it does not change anything other than that the dust trail does not transition away. 

Also tried this on the onComplete part, and alpha to 1 so i could se that all “stov” display object is removed. And it does. But the problem still persist. After level restart the trail is getting thicker. 

[lua]

tran= transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 1,

                                    time       = 2000,

                                    onComplete = function ()display.remove( stov ) 

    end} ) 

[/lua]

Does anybody have a clue about what i`m doing wrong? Have i not explained my problem proper?

Your first listing is wrong in that the function ‘ferdi’ does nothing. Stov does not exist to this function, as it is local to onCollision2.

Your second post is better, can you try setting stov = nil in the onComplete function, and make the transition local?

Thank you for the reply.

Like this?

[lua]

local tran= transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 0,

                                    time       = 2000,

                                    onComplete = function ()display.remove( stov ) stov = nil

    end} ) 

[/lua]

Unfortunately, nothing changes in relation to the fact that the trail becomes thicker.

This is after five restart. 

I believe what Nick said was that when you create “stov”, you create it locally inside the onCollision2 function. This means that, even if you return it, your ferdi function cannot actually remove or set “stov” to nil because no such variable actually exists within ferdi’s scope.

 

local function ferdi() -- print(stov) -- based on what I am seeing, this should print out nil display.remove(stov) -- that is because stov is not within the scope of this function stov = nil end

All this function does is try to remove stov as a display object and set it to nil, but the way that you are doing this is wrong. This would work if you had a single variable named “stov” and you had declared it before ferdi. You, however, create numerous local variables under that name within the onCollision2 function, but the variable name itself remains local to the collision function. You probably want to create a table full of those display objects and then refer to each individual object as you delete them.

Yes sorry for not mentioning it, I do not use the ferdi function anymore. As you guys said, it do not work.

Thats why i thought this would work.

[lua]

onComplete = function ()display.remove( stov ) stov = nil

end} ) 

[/lua]

If I do this 

[lua]

onComplete = function ()display.remove( stov )

                                                            print(stov)

                                                            stov = nil

                                                            print(stov) 

    end} ) 

[/lua]

the consol return this:

15:38:44.332  table: 078255A0

15:38:44.332  nil

15:38:44.447  table: 07825640

15:38:44.447  nil

15:38:44.778  table: 07825A28

15:38:44.778  nil

Would not this indicate that stov is proper nil?

 When you say"create a table full of those display objects" do you mean adding them to a table when created?

Try some print messages within your collision function, to see if it is called more often the more times you restart. This could indicate it’s either running multiple instances or there are multiple versions of something that is being collided with.

I seem to remember sometimes having trouble removing runtime listeners, if it was not in scope to the function that tried to remove it.

So I tried what you suggested. First death it printed 1503 lines, second death  2255 lines and third death  3007 lines.

Of course I did not interact with anything, so it should be the same. 

Possible or more likely, the runtime eventlistner is not removed? Is there a way to check if it`s the case, or prevent it stick around after the restart?

[lua]

local function onCollision2(event)

if event.phase == “ended” then

print( “a” )

if  

    (event.object1.type == “del1” and event.object2.type == “firkant1”) or

    (event.object1.type == “del2” and event.object2.type == “firkant1”) or

    (event.object1.type == “del3” and event.object2.type == “firkant1”) or

    (event.object1.type == “del4” and event.object2.type == “firkant1”) or

    (event.object1.type == “del5” and event.object2.type == “firkant1”) or

    (event.object1.type == “del6” and event.object2.type == “firkant1”) or

    (event.object1.type == “del7” and event.object2.type == “firkant1”) or

    (event.object1.type == “del8” and event.object2.type == “firkant1”) or

    (event.object1.type == “del9” and event.object2.type == “firkant1”) or

    (event.object1.type == “del1” and event.object2.type == “firkant2”) or

    (event.object1.type == “del2” and event.object2.type == “firkant2”) or

    (event.object1.type == “del3” and event.object2.type == “firkant2”) or

    (event.object1.type == “del4” and event.object2.type == “firkant2”) or

    (event.object1.type == “del5” and event.object2.type == “firkant2”) or

    (event.object1.type == “del6” and event.object2.type == “firkant2”) or

    (event.object1.type == “del7” and event.object2.type == “firkant2”) or

    (event.object1.type == “del8” and event.object2.type == “firkant2”) or

    (event.object1.type == “del9” and event.object2.type == “firkant2”) or

    (event.object1.type == “del1” and event.object2.type == “firkant3”) or

    (event.object1.type == “del2” and event.object2.type == “firkant3”) or

    (event.object1.type == “del3” and event.object2.type == “firkant3”) or

    (event.object1.type == “del4” and event.object2.type == “firkant3”) or

    (event.object1.type == “del5” and event.object2.type == “firkant3”) or

    (event.object1.type == “del6” and event.object2.type == “firkant3”) or

    (event.object1.type == “del7” and event.object2.type == “firkant3”) or

    (event.object1.type == “del8” and event.object2.type == “firkant3”) or

    (event.object1.type == “del9” and event.object2.type == “firkant3”) or

    (event.object1.type == “del1” and event.object2.type == “firkant4”) or

    (event.object1.type == “del2” and event.object2.type == “firkant4”) or

    (event.object1.type == “del3” and event.object2.type == “firkant4”) or

    (event.object1.type == “del4” and event.object2.type == “firkant4”) or

    (event.object1.type == “del5” and event.object2.type == “firkant4”) or

    (event.object1.type == “del6” and event.object2.type == “firkant4”) or

    (event.object1.type == “del7” and event.object2.type == “firkant4”) or

    (event.object1.type == “del8” and event.object2.type == “firkant4”) or

    (event.object1.type == “del9” and event.object2.type == “firkant4”) then

 print( “b” )

local   stov        = display.newImageRect(“stov.png”, 20,20)

        stov.width  = 10+(math.random(10, 50)) 

        stov.height = stov.width

        stov.x      = event.object1.x+(math.random(1, 10)) 

        stov.y      = event.object1.y-(math.random(1, 10))

        rot         = (math.random(1,360)) 

        stov.alpha  = 0.1

        stov:rotate( rot )

        grp:insert(stov)

        camera:add (stov,1,false)

print( “c” )

local tran= transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 0,

                                    time       = 2000,

                                    onComplete = function ()display.remove( stov ) stov = nil

    end} ) 

print( “d” )                           

              

            return stov

         end   

   end

print( “e” )

end

Runtime:addEventListener(“collision”, onCollision2)

[/lua]

Corona does remove all event listeners attached to display objects when they are removed, but you are responsible for removing any and all runtime listeners. Since you have a runtime listener, you need to remove it once you no longer need it.

 

Ah ok but I thought I did it with the goto function when the character died, as I posted in my first post?

[lua]

        local function goto( event )

        physics.pause( )

        Runtime:removeEventListener(“collision”, onCollision)

        Runtime:removeEventListener(“collision”, onCollision1)

        Runtime:removeEventListener(“collision”, onCollision2)

        composer.showOverlay( “dodmenu1”,{isModal = true,effect = “fade”,time = 500,})

        end

[/lua]

I seem to have missed that as I was skimming through the post.

Have tried to change where i remove the runtimeeventlistener after i read about scope for beginners in the docs. But no luck so far. I`m quite lost…

Is there a way to get some sort of statement if a runtime is active or removed?

I have tried to remove the transition, but it does not change anything other than that the dust trail does not transition away. 

Also tried this on the onComplete part, and alpha to 1 so i could se that all “stov” display object is removed. And it does. But the problem still persist. After level restart the trail is getting thicker. 

[lua]

tran= transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 1,

                                    time       = 2000,

                                    onComplete = function ()display.remove( stov ) 

    end} ) 

[/lua]

Does anybody have a clue about what i`m doing wrong? Have i not explained my problem proper?

Your first listing is wrong in that the function ‘ferdi’ does nothing. Stov does not exist to this function, as it is local to onCollision2.

Your second post is better, can you try setting stov = nil in the onComplete function, and make the transition local?

Thank you for the reply.

Like this?

[lua]

local tran= transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 0,

                                    time       = 2000,

                                    onComplete = function ()display.remove( stov ) stov = nil

    end} ) 

[/lua]

Unfortunately, nothing changes in relation to the fact that the trail becomes thicker.

This is after five restart. 

I believe what Nick said was that when you create “stov”, you create it locally inside the onCollision2 function. This means that, even if you return it, your ferdi function cannot actually remove or set “stov” to nil because no such variable actually exists within ferdi’s scope.

 

local function ferdi() -- print(stov) -- based on what I am seeing, this should print out nil display.remove(stov) -- that is because stov is not within the scope of this function stov = nil end

All this function does is try to remove stov as a display object and set it to nil, but the way that you are doing this is wrong. This would work if you had a single variable named “stov” and you had declared it before ferdi. You, however, create numerous local variables under that name within the onCollision2 function, but the variable name itself remains local to the collision function. You probably want to create a table full of those display objects and then refer to each individual object as you delete them.

Yes sorry for not mentioning it, I do not use the ferdi function anymore. As you guys said, it do not work.

Thats why i thought this would work.

[lua]

onComplete = function ()display.remove( stov ) stov = nil

end} ) 

[/lua]

If I do this 

[lua]

onComplete = function ()display.remove( stov )

                                                            print(stov)

                                                            stov = nil

                                                            print(stov) 

    end} ) 

[/lua]

the consol return this:

15:38:44.332  table: 078255A0

15:38:44.332  nil

15:38:44.447  table: 07825640

15:38:44.447  nil

15:38:44.778  table: 07825A28

15:38:44.778  nil

Would not this indicate that stov is proper nil?

 When you say"create a table full of those display objects" do you mean adding them to a table when created?

Try some print messages within your collision function, to see if it is called more often the more times you restart. This could indicate it’s either running multiple instances or there are multiple versions of something that is being collided with.

I seem to remember sometimes having trouble removing runtime listeners, if it was not in scope to the function that tried to remove it.

So I tried what you suggested. First death it printed 1503 lines, second death  2255 lines and third death  3007 lines.

Of course I did not interact with anything, so it should be the same. 

Possible or more likely, the runtime eventlistner is not removed? Is there a way to check if it`s the case, or prevent it stick around after the restart?

[lua]

local function onCollision2(event)

if event.phase == “ended” then

print( “a” )

if  

    (event.object1.type == “del1” and event.object2.type == “firkant1”) or

    (event.object1.type == “del2” and event.object2.type == “firkant1”) or

    (event.object1.type == “del3” and event.object2.type == “firkant1”) or

    (event.object1.type == “del4” and event.object2.type == “firkant1”) or

    (event.object1.type == “del5” and event.object2.type == “firkant1”) or

    (event.object1.type == “del6” and event.object2.type == “firkant1”) or

    (event.object1.type == “del7” and event.object2.type == “firkant1”) or

    (event.object1.type == “del8” and event.object2.type == “firkant1”) or

    (event.object1.type == “del9” and event.object2.type == “firkant1”) or

    (event.object1.type == “del1” and event.object2.type == “firkant2”) or

    (event.object1.type == “del2” and event.object2.type == “firkant2”) or

    (event.object1.type == “del3” and event.object2.type == “firkant2”) or

    (event.object1.type == “del4” and event.object2.type == “firkant2”) or

    (event.object1.type == “del5” and event.object2.type == “firkant2”) or

    (event.object1.type == “del6” and event.object2.type == “firkant2”) or

    (event.object1.type == “del7” and event.object2.type == “firkant2”) or

    (event.object1.type == “del8” and event.object2.type == “firkant2”) or

    (event.object1.type == “del9” and event.object2.type == “firkant2”) or

    (event.object1.type == “del1” and event.object2.type == “firkant3”) or

    (event.object1.type == “del2” and event.object2.type == “firkant3”) or

    (event.object1.type == “del3” and event.object2.type == “firkant3”) or

    (event.object1.type == “del4” and event.object2.type == “firkant3”) or

    (event.object1.type == “del5” and event.object2.type == “firkant3”) or

    (event.object1.type == “del6” and event.object2.type == “firkant3”) or

    (event.object1.type == “del7” and event.object2.type == “firkant3”) or

    (event.object1.type == “del8” and event.object2.type == “firkant3”) or

    (event.object1.type == “del9” and event.object2.type == “firkant3”) or

    (event.object1.type == “del1” and event.object2.type == “firkant4”) or

    (event.object1.type == “del2” and event.object2.type == “firkant4”) or

    (event.object1.type == “del3” and event.object2.type == “firkant4”) or

    (event.object1.type == “del4” and event.object2.type == “firkant4”) or

    (event.object1.type == “del5” and event.object2.type == “firkant4”) or

    (event.object1.type == “del6” and event.object2.type == “firkant4”) or

    (event.object1.type == “del7” and event.object2.type == “firkant4”) or

    (event.object1.type == “del8” and event.object2.type == “firkant4”) or

    (event.object1.type == “del9” and event.object2.type == “firkant4”) then

 print( “b” )

local   stov        = display.newImageRect(“stov.png”, 20,20)

        stov.width  = 10+(math.random(10, 50)) 

        stov.height = stov.width

        stov.x      = event.object1.x+(math.random(1, 10)) 

        stov.y      = event.object1.y-(math.random(1, 10))

        rot         = (math.random(1,360)) 

        stov.alpha  = 0.1

        stov:rotate( rot )

        grp:insert(stov)

        camera:add (stov,1,false)

print( “c” )

local tran= transition.to (stov, {

                                    x          = stov.x      - (math.random(-50, 50)),

                                    y          = stov.y      - (math.random( 1, 50)),

                                    width      = stov.width  + (math.random(1, 50)),

                                    height     = stov.height + (math.random(1, 50)),

                                    alpha      = 0,

                                    time       = 2000,

                                    onComplete = function ()display.remove( stov ) stov = nil

    end} ) 

print( “d” )                           

              

            return stov

         end   

   end

print( “e” )

end

Runtime:addEventListener(“collision”, onCollision2)

[/lua]

Corona does remove all event listeners attached to display objects when they are removed, but you are responsible for removing any and all runtime listeners. Since you have a runtime listener, you need to remove it once you no longer need it.