Several collisions using the same type of object

Just for fun i want to create a game with a jet and falling enemies that you have to dodge. My problem is that i would be using the same object ( same enemy ) to spawn several times. Now, the first time the object gets spawned and it collides with the jet or the lower invisible wall it disappears as it should, but the following objects prompt me to an error message. I get a nill value. So, I guess the problem is that the second object that is created doesn’t have any fields on it and neither do the ones that follow it. I tried using tables to create the objects and it doesn’t work. I tried to spawn a new object when the previous one gets destroyed and it doesn’t work either, changing the names gave me the same result, a nil value!

local objects = {}

local objectCount = 5

for i = 1, objectCount do

    local startX = math.random(display.contentWidth*0.2,display.contentWidth*0.9)

local startY = math.random(display.contentWidth*0.2,display.contentWidth*0.4)

bomb = display.newImage( “bomb1.png”, startX, -300)

  bomb.myName = “bomb”

        physics.addBody( bomb )

        bomb.enterFrame = offscreen

end

local function onLocalCollision( self, event )

if ( event.phase == “began” ) then

elseif ( event.phase == “ended” ) then

bomb:removeSelf()

end

end

bomb.collision = onLocalCollision

bomb:addEventListener( “collision” )

jet.collision = onLocalCollision

jet:addEventListener( “collision” )

The rest of the program works fine

In your for loop, every time you create a new bomb, you’re losing the handle on the old one. You’re basically saying, let bomb be this, now let bomb be this, etc, so that when you are done, bomb is only the last display object that you created. After you say bomb:removeSelf() once, bomb becomes nil, so the next time you call bomb:removeSelf(), you get an error. To keep track of your bombs you could have a table called bombs and add your bombs into it…

local bombs = {} for i = 1, objectCount do local startX = math.random(display.contentWidth\*0.2,display.contentWidth\*0.9) local startY = math.random(display.contentWidth\*0.2,display.contentWidth\*0.4) bombs[i]= display.newImage( "bomb1.png", startX, -300) end

You could add the collision handler to these bombs either inside this for loop or another one, or you could use a Runtime collision listener, check the id of each collision object and handle them accordingly.

What you suggested unfortunately didnt work, however I ran into this:
https://coronalabs.com/blog/2011/09/14/how-to-spawn-objects-the-right-way/
and implemented it. But now it seems like the problem is being how to tell it which item to remove.

" spawns.myName:removeSelf() " does not work, gives me a nil value

“object2.myName:removeSelf()” prints the name of the correct spawn, but it doesnt work either 

I changed to using global collisions and it works well if i spawn the same object several times when the other one is destroyed, using the timer ( the commented out section ) but that is not what I need. I need several of the same objects on screen at the same time.

local function onGlobalCollision( event )

if ( event.phase == “began” ) then

elseif ( event.phase == “ended” ) then

if(event.object1.myName== “bottom”) then  

spawn.myName:removeSelf()

– timer.performWithDelay( 0, createBomb, 1 )

M.add(100)

elseif(event.object1.myName== “right”) then

print(“doesnt matter”) 

print(event.object2.myName)

elseif(event.object1.myName== “left”) then

print(“doesnt matter”) 

elseif(event.object1.myName== “jets”) then

system.vibrate()

print(“doesnt matter”) 

else M.add(-100)

damageCharacter(50)

print(event.object2.myName)

spawn.myName:removeSelf()

– timer.performWithDelay( 0, createBomb, 1 )

end

end

end

Runtime:addEventListener( “collision”, onGlobalCollision )

Assuming that you have a spawn() function, and that this function puts your objects into a table called spawnTable, then when there is a collision, you can iterate through the spawnTable, find the right object and remove it if necessary. In your collision handler you can include:

for i = #spawnTable, 1, -1 do if event.object1 == spawnTable[i] and event.object2 == bottom then -- I'm assuming that whatever has myName = "bottom" is just called bottom spawnTable[i]:removeSelf() spawnTable[i] = nil table.remove(spawnTable, i) end

Additionally, you’ll need to account for the possibility that the object to destroy might be event.object2 and the bottom be event.object1.

I haven’t tested this, so I hope I haven’t made a mistake, but I’m optimistic.

this line did the trick:

event.object2:removeSelf() ( or object1 in some cases )

I printed the values given by spawnTable[i] and it prints the ID of the objects.
Thanks a lot hasty yours was the right approach, I had to check which item was being used, I tought the physics engine was going to do that by itself, wouldnt have figured it out without you!!

In your for loop, every time you create a new bomb, you’re losing the handle on the old one. You’re basically saying, let bomb be this, now let bomb be this, etc, so that when you are done, bomb is only the last display object that you created. After you say bomb:removeSelf() once, bomb becomes nil, so the next time you call bomb:removeSelf(), you get an error. To keep track of your bombs you could have a table called bombs and add your bombs into it…

local bombs = {} for i = 1, objectCount do local startX = math.random(display.contentWidth\*0.2,display.contentWidth\*0.9) local startY = math.random(display.contentWidth\*0.2,display.contentWidth\*0.4) bombs[i]= display.newImage( "bomb1.png", startX, -300) end

You could add the collision handler to these bombs either inside this for loop or another one, or you could use a Runtime collision listener, check the id of each collision object and handle them accordingly.

What you suggested unfortunately didnt work, however I ran into this:
https://coronalabs.com/blog/2011/09/14/how-to-spawn-objects-the-right-way/
and implemented it. But now it seems like the problem is being how to tell it which item to remove.

" spawns.myName:removeSelf() " does not work, gives me a nil value

“object2.myName:removeSelf()” prints the name of the correct spawn, but it doesnt work either 

I changed to using global collisions and it works well if i spawn the same object several times when the other one is destroyed, using the timer ( the commented out section ) but that is not what I need. I need several of the same objects on screen at the same time.

local function onGlobalCollision( event )

if ( event.phase == “began” ) then

elseif ( event.phase == “ended” ) then

if(event.object1.myName== “bottom”) then  

spawn.myName:removeSelf()

– timer.performWithDelay( 0, createBomb, 1 )

M.add(100)

elseif(event.object1.myName== “right”) then

print(“doesnt matter”) 

print(event.object2.myName)

elseif(event.object1.myName== “left”) then

print(“doesnt matter”) 

elseif(event.object1.myName== “jets”) then

system.vibrate()

print(“doesnt matter”) 

else M.add(-100)

damageCharacter(50)

print(event.object2.myName)

spawn.myName:removeSelf()

– timer.performWithDelay( 0, createBomb, 1 )

end

end

end

Runtime:addEventListener( “collision”, onGlobalCollision )

Assuming that you have a spawn() function, and that this function puts your objects into a table called spawnTable, then when there is a collision, you can iterate through the spawnTable, find the right object and remove it if necessary. In your collision handler you can include:

for i = #spawnTable, 1, -1 do if event.object1 == spawnTable[i] and event.object2 == bottom then -- I'm assuming that whatever has myName = "bottom" is just called bottom spawnTable[i]:removeSelf() spawnTable[i] = nil table.remove(spawnTable, i) end

Additionally, you’ll need to account for the possibility that the object to destroy might be event.object2 and the bottom be event.object1.

I haven’t tested this, so I hope I haven’t made a mistake, but I’m optimistic.

this line did the trick:

event.object2:removeSelf() ( or object1 in some cases )

I printed the values given by spawnTable[i] and it prints the ID of the objects.
Thanks a lot hasty yours was the right approach, I had to check which item was being used, I tought the physics engine was going to do that by itself, wouldnt have figured it out without you!!