Hi,
I spawn objects and clean up as below but there seem to be memory leak.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | local function spawnBomb() local bomb = display.newImage("bomb.png") bombs[bomb] = bomb bombs[bomb].x = math.random(_W/2, _W/2) bombs[bomb].name = "bomb" physics.addBody(bombs[bomb], {bounce=0}) bombs[bomb].bodyType = "kinematic" bombs[bomb].isSensor = true bombs[bomb].y = math.random(-100, -10) bombGroup:insert(bombs[bomb]) bombs[bomb]:setLinearVelocity(0, math.random(100, 110)) function onCollision(e) if e.phase == "began" then bombs[bomb]:removeSelf() bombs[bomb] = nil end end bombs[bomb]:addEventListener("collision", onCollision) end tmrSpawnBomb = timer.performWithDelay(200, spawnBomb, 0) local function cleanUp() if bombGroup.numChildren then for i=bombGroup.numChildren, 1, -1 do if bombGroup[i].y > 150 then bombGroup[i]:removeEventListener("collision", onCollision) bombGroup[i]:removeSelf() end end end end tmrCheckBubble = timer.performWithDelay(20, cleanUp, 0) |
I think the cleanUp function only remove the display object, but the table structure of the object is there unless we set the object to nil, thus causing the memory leak.
bombGroup[i] = nil
will generate WARNING: Attempting to set property(1) with nil.
How to set object to nil with such cleapUp function or any other function? Is there a better way to spawn objects with the same file name and object name and clean it up after its Y or X exceed certain point?
Steve
This part here;
1 2 3 4 5 6 | function onCollision(e) if e.phase == "began" then bombs[bomb]:removeSelf() bombs[bomb] = nil end end |
Thanks, Peach Pellen. Thought I don't have the delay, it doesn't make any error at the moment but to be safe I'll add delay timer. How about cleanUp function? Does it make sense?
Steve
Hi. This is how you should be doing your spawns...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | local function spawnBomb() local bomb = display.newImage("bomb.png") bomb.x = math.random(_W/2, _W/2) bomb.name = "bomb" physics.addBody(bomb, {bounce=0}) bomb.bodyType = "kinematic" bomb.isSensor = true bomb.y = math.random(-100, -10) bomb.index = #bombs + 1 bombGroup:insert(bomb) bomb:setLinearVelocity(0, math.random(100, 110)) function onCollision(e) if e.phase == "began" then bomb:removeSelf() bomb = nil end end bomb:addEventListener("collision", onCollision) bombs[bomb.index] = bomb return bomb end |
@Danny, how can I remove bomb when it goes off screen? I can do it by setting up an off screen object to collide with bomb, but is there any other ways? Thank you.
Steve
The way you suggested is probably the best way.
However you can also remove them this way (in a for loop, in a runtime listener)
1 2 3 4 5 6 7 8 | for i, v in pairs(bombs) do --if bomb leaves right side of screen if bombs[i].x + bombs[i].width / 2 > display.contentWidth then bombs[i]:removeSelf() table.remove(bombs, i) bombs[i] = nil end end |
@Danny, it removes the object if there is only one passing the threshold line, but if there are more, some are not removed. I put together the code below for your review just in case I've done something wrong.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | _W = display.contentWidth _H = display.contentHeight local physics = require("physics") physics.start() local bombs = {} local bombGroup = display.newGroup() local function spawnBomb() local bomb = display.newImage("bomb.png") bomb.x = math.random(0, _W) bomb.name = "bomb" physics.addBody(bomb, {bounce=0, filter=b}) bomb.bodyType = "kinematic" bomb.isSensor = true bomb.y = math.random(-100, -10) bomb.index = #bombs + 1 bombGroup:insert(bomb) bomb:setLinearVelocity(0, math.random(100, 110)) function onCollision(e) if e.phase == "began" then hello() bomb:removeSelf() bomb = nil end end bomb:addEventListener("collision", onCollision) bombs[bomb.index] = bomb return bomb end tmrSpawnBomb = timer.performWithDelay(1000, spawnBomb, 0) local function removeBomb() for i, v in pairs(bombs) do if bombs[i].y >100 then bombs[i]:removeSelf() table.remove(bombs, i) bombs[i] = nil end end end Runtime:addEventListener("enterFrame", removeBomb) |
send message and call to a person
Forum: Report Spam + PM
[INSTALL_PARSE_FAILED_NO_CERTIFICATES]
[SOLVED] Director ERROR: Failed to execute new( params ) function on 'screen1'
Too many (200) local variables
Corona SVG Level Builder released. Drag and drop physics level editor with Inkscape and SVG.
Small bug in Collectible Items example
Pivot Joints and apparent elasticity
Can't make removeSelf() delayed
Openfeint testing?
pass variable by refernce
Hiring Developer
OpenFeint -> Game Center crash
How to Stack physics Objects Properly
What is the lucky number for today?
Display your app on About.com
App no longer auto spinning
Detecting when a finger slides off a display object