Problem with removeSelf() when adding bodys to table

Hi,

To create objects objects in my game I use:

physics.addBody( j, { radius=r, density=1, friction=0, bounce=0.3} )  
table.insert(bTable, {b=j})  

Where j is the image with some text added to it…

Then later when the game is over I call this:

function destroyItemsInTable(t)  
 i = 1  
 l = #t  
 while i \<= l do  
 if(t[i]~=nil) then  
 t[i].b.isVisible = false  
 t[i].b.isBodyActive = false  
 t[i].b:removeSelf()  
 end  
 i = i + 1  
 end  
  
 while #t \> 0 do  
 table.remove(t)  
 end  
end  

I get the following error:

main.lua:91: attempt to call method 'removeSelf' (a nil value)  
  
stack traceback:  
[C]: in function 'removeSelf'  
main.lua:91: in function 'destroyItemsInTable'  
main.lua:1231: in function '\_listener'  
?: in function <?:441>  
?: in function <?:214>  

In other places in the code I use removeSelf() without any problems…

Can anyone shed any light on this???

Thanks,

Gary
PS. Using Game Edition Public Beta [import]uid: 4415 topic_id: 1917 reply_id: 301917[/import]

Mine is similar with the same error

[lua]function mScreen()

local mbg = display.newImage(‘mbg.png’,true)
local sb = display.newImage(‘sb.png’,true)

local startGame = function()
mbg:removeSelf()
sb:removeSelf()
changeLevel()
end

local moveStuff = function(event)
transition.to(mbg,{time=1500,alpha=0})
transition.to(sb,{time=1500,alpha=0})
timer.performWithDelay(1510,startGame);
end

sb:addEventListener(“touch”,moveStuff);
end[/lua]

But I’ve noticed if I change the eventListener to trigger startGame I don’t get the error, so is it because I’m setting the alpha to 0 on my image or is it because of the way I’m calling or setting up the functions?

Thanks,
Bob. [import]uid: 8485 topic_id: 1917 reply_id: 5715[/import]

Bob,

The problem is your listener is calling moveStuff twice – once for “begin” and then for “ended” events.

Here is how I modify your code to work:

 local function moveStuff(event)  
 print( event.phase )  
 if "ended" == event.phase then  
 transition.to(mbg,{time=1500,alpha=0})  
 transition.to(sb,{time=1500,alpha=0})  
 timer.performWithDelay(1510, startGame);  
 end  
 end  

You should also remove the listener for sb after you remove the object.

@Gary, I’m not sure if your listener function has the same problem but it could explain why you are getting the removeSelf error. Try adding a print statement in your function to see when it’s being called. Also print out the index (“i”) to see where it’s failing.

-Tom [import]uid: 7559 topic_id: 1917 reply_id: 5723[/import]

That worked great - Thanks!

Bob. [import]uid: 8485 topic_id: 1917 reply_id: 5781[/import]

@Tom,

Thanks for your reply… I really appreciate it…

Your suggestion put me on the right track… Under some circumstances removeSelf() was being called during the game before destroyItemsInTable() was called.

Many thanks!

Gary
[import]uid: 4415 topic_id: 1917 reply_id: 5785[/import]

Hi,

I’m having the same issue but I don’t know what there’s wrong in my code. It would be nice if someone could have a look at it because sometimes four eyes see more than two :wink:

I made a simple game where the goal is to “destroy” some rectangles (called fluffies). Sounds pretty simple, but the fluffies can only be destroyed if they’re in a collision with a fluffie which’s the same color.

My objects (called Fluffies) are created with the following code.

fluffies = display.newGroup()  
 for i=0, 8, 1 do -- Rows  
 for d=0, 5, 1 do  
 color = math.random(1,4)  
 if(color == 1) then  
 fluffie = display.newImage("red\_thing.png")  
 fluffie.color = "red"  
 elseif(color == 2) then  
 fluffie = display.newImage("green\_thing.png")   
 fluffie.color = "green"  
 elseif(color == 3) then  
 fluffie = display.newImage("blue\_thing.png")  
 fluffie.color = "blue"  
 elseif(color == 4) then  
 fluffie = display.newImage("yellow\_thing.png")  
 fluffie.color = "yellow"  
 elseif(color == 5) then  
 fluffie = display.newImage("purple\_thing.png")  
 fluffie.color = "purple"  
 end  
 fluffie:setReferencePoint(display.TopLeftReferencePoint)  
 fluffie.x = 15 + (d \* 75)  
 fluffie.y = 15 + (i \* 75)  
 fluffie.width = 75  
 fluffie.height = 75  
 fluffie.id = fluffies.numChildren + 1  
 fluffie:setReferencePoint(display.CenterReferencePoint)  
 fluffie:addEventListener('touch', onTouch)  
 fluffie.collisions = {}  
 physics.addBody( fluffie, { density = 1.5, friction = 0.1, bounce = 0})  
 fluffies:insert(fluffie)  
 end  
 end  

Then I have the following code for the collision, as you can see above every fluffie has a table in which all it’s ‘neighbours’ are stored:

function hitTest( event)   
 if ( event.phase == "began" ) then  
 if(event.object1.color == event.object2.color) then  
 event.object1.collisions[event.object2.id] = event.object2  
 event.object2.collisions[event.object1.id] = event.object1  
 return true  
 end  
 end  
 if ( event.phase == "ended" ) then  
 if(event.object1.color == event.object2.color) then  
 event.object1.collisions[event.object2.id] = nil  
 event.object2.collisions[event.object1.id] = nil  
 return true  
 end  
 end  
end  

And finally here’s my code to destroy the fluffies, it uses the table to destroy all the fluffies which have the same color and are in a collision with each other:

function onTouch(event)  
 local phase = event.phase  
 if(phase == "began") then  
 combo = 0  
 for i,v in pairs(event.target.collisions) do  
 for d,v in pairs(event.target.collisions[i].collisions) do  
 event.target.collisions[i].collisions[d]:removeSelf()  
 combo = combo + 1  
 anzfluffies = anzfluffies + 1  
 end  
 event.target.collisions[i]:removeSelf()  
 combo = combo + 1  
 anzfluffies = anzfluffies + 1  
 end  
 if(combo \> 0) then  
 print(combo)  
 event.target:removeSelf()  
 anzfluffies = anzfluffies + 1  
 scoreDisplay:setText( anzfluffies.." / 54" )  
 else  
 print('not enough neighboours')  
 end  
 end  
 return true;  
end  

The problem is, that sometimes - I don’t know why - some fluffies aren’t destroyed and the following error message appears in the console:

Runtime error path/main.lua:148: attempt to call method 'removeSelf' (a nil value)  

Sometimes I can kill all the fluffies without any error and sometimes every third group of fluffies can’t be destroyed because of that error.

Maybe I am doing something wrong in my code, I don’t know but I’m trying to fix this problem for hours now and it would be nice if you could help me :slight_smile:

Thank you very much,

Michael [import]uid: 8121 topic_id: 1917 reply_id: 8837[/import]

Sorry for pushing this thread but I really need help with this :slight_smile: I’m stuck and I don’t know if it’s something in Corona or my code that is wrong.

Thank you,

Michael [import]uid: 8121 topic_id: 1917 reply_id: 9153[/import]

Michael,

A few things that might help you (and us)…

  1. First a question: Which line is line 148 in your main.lua file?

  2. I am wondering if there are two sets of collisions events, one for A->B and one for B->A… If that is so when the B->A collisions event happens you may have already deleted B during the A->B collision.

  3. You could try putting a test for nil around each of your calls to removeSelf to see if this helps and also to print out some debug information so you can hunt down the error…

  4. It is almost certainly a logic error on your part… All those collisions, combos etc… Looks like something is trying to be removed twice.

I hope this helps,

Gary [import]uid: 4415 topic_id: 1917 reply_id: 9282[/import]

Hi,

thank you for your reply!

1.) It’s this line:

event.target.collisions[i].collisions[d]:removeSelf()

2.) Well I thought because I’m returning true at the end of each collision, no other collision event on those two objects will be fired:

As of Alpha 3, any collision event handler that returns true will stop further propagation of that collision event, even if there are further listeners that would otherwise have received it. This allows you to further limit the number of events that are created and passed to the Lua side. While individual events are not very expensive, large numbers of them can affect overall performance, so limiting event propagation is a good practice.

3.) I tried this, but I’m still getting the error :S That’s really strange! I tried to print some debug information such as the ID of the fluffie etc. but this works fine, but it just can’t remove it -.-

4.) The problem is, that they aren’t removed at all, if I call removeSelf twice, I would get the error ok, but the Fluffie would be removed. That’s what I can’t understand at the moment, why can’t they be removed?

I don’t think that the problem is, that my object is nil, because if I try to remove something that IS nil, the error message looks different…

Argh, I’m really stuck on this… But it has to be a logical error somewhere in the code… but it’s damn hard to find it :slight_smile:
[import]uid: 8121 topic_id: 1917 reply_id: 9298[/import]

Okay, sorry folks :slight_smile:

I finally could fix the error. The problem was, that some fluffies weren’t removed out of the collision tables of the others. I fixed it by simple creating a new table were I store all the id’s of the deleted objects, then before deleting an object, I check wether or not the object’s id is in the table or not.

Well learned my lesson today, but thanks for helping me anyway. Finally I can go on and try to finish my app!

Regards,
Michael [import]uid: 8121 topic_id: 1917 reply_id: 9299[/import]