How to detect a collision using the Collision FIlter?

So guys, i using the Collision filter, to handle the collisions in my game, but now i have a problem to understand how to detect the collisions

Basically this is how i creating my Collisions: 

 local monstroPhys = {density = monstro.density, friction = monstro.friction, bounce = monstro.bounce, isSensor = monstro.isSensor} physics.addBody(monstro, "dynamic", filter:deploy( monstroPhys, monstro.name , {'NOMEFIRE'} ))

This is how i tried to listen to the collision inside my monster object:

 local function onCollision ( event ) if event.phase == "began" then if event.target.type == "monstro" and event.other.type == "fire" then print("Worked") end end end monstro.collision = onCollision monstro:addEventListener("collision", monstro) 

Sadly my debugger never printed Worked! 

The listener must be inside the monster object, because my goal is to do something like that:

IF collide with Fire, then health = health - 10

Still stucked! anyone?

What’s this code doing?  What is ‘filter’, a custom class you created?  My first suggestion would be to consult the documentation for physics.addBody() at http://docs.coronalabs.com/api/library/physics/addBody.html to make sure you’re actually creating the body correctly.

[lua]

filter:deploy( monstroPhys, monstro.name , {‘NOMEFIRE’} )

[/lua]

Also, you haven’t posted enough code to diagnose the issue.  Your collision listener checks the type of the target and the other object, but you haven’t shown us that you’ve assigned those type properties to those objects.

Insert a print statement at the top of your collision listener.  That way you can tell whether the problem is the collision listener not firing at all, or whether the problem is with part that checks the type of the target and other object.

  • Andrew

This would be the Spawn Monster Class: 

 local function spawnObj(params) local monstro = display.newImageRect(params.image, params.sizew, params.sizeh ) monstro.x = params.posX monstro.y = params.posY monstro.objTable = params.objTable monstro.type = params.type monstro.index = #monstro.objTable + 1 monstro.myName = "Object :" .. monstro.index monstro.name = params.nome monstro.vida = params.vida monstro.objTable[monstro.index] = monstro monstro.tipo = params.tipo or static monstro.density = params.density or 0 monstro.friction = params.friction or 0 monstro.bounce = params.bounce or 0 monstro.isSensor = params.isSensor or false if params.hasBody then local monstroPhys = {density = monstro.density, friction = monstro.friction, bounce = monstro.bounce, isSensor = monstro.isSensor} physics.addBody(monstro, "dynamic", filter:deploy( monstroPhys, monstro.name , {'NOMEFIRE'} )) end if params.move then monstro.tempo = params.transtime or 1000 monstro.delay = params.delay or 0 monstro.destinox = params.destinox or 200 monstro.destinoy = params.destinoy or 200 monstro.funcao = params.quandoCompletar or nil transition.to(monstro, {time = monstro.tempo, x = monstro.destinox, y = monstro.destinoy, }) end local function onCollision ( event ) print('Working') -- is printing if event.phase == "began" then if event.target.type == "monstro" and event.other.tyoe == "fire" then print("Not Working") end end end monstro.collision = onCollision monstro:addEventListener("collision", monstro) group:insert(monstro) return monstro end

And the Filter Class come from here: https://github.com/zooom/filter

This is the Fire: 

local function spawnMagic() local fire = display.newImageRect("images/fireball.png", 50, 30) local forcaX local anguloY fire.type = "fire" fire.isFixedRotation = true fire.name = "NOMEFIRE" fire.x = mago.x + 50 fire.y = mago.y - 10 -- Calcula forca do ForcaX baseado no tanto que o touch foi arrastado no rastreador if(forca \< 9) then forcaX = "0."..forca elseif(forca \< 45) then forcaX = 1 elseif(forca \< 80) then forcaX = 2 elseif(forca \< 120) then forcaX = 3 elseif(forca \< 180) then forcaX = 5 elseif(forca \< 220) then forcaX = 6.5 elseif(forca \< 300) then forcaX = 7 elseif(forca \< 5000) then forcaX = 8 end -- Calcular angulo if(angulo \< 110) then anguloY = -3 elseif(angulo \< 175) then anguloY = -2 elseif( angulo \< 300) then anguloY = 0 end -- destroirFire temporario local firephys = { density = 0.1, friction = 03, bounce = 0.4, isSensor = false } physics.addBody(fire, "dynamic", filter:deploy( firephys, 'NOMEFIRE', {'NOMEMONSTRO', 'NOMEFLOOR'} )) fire:applyLinearImpulse( forcaX, anguloY, fire.x, fire.y) -- chamarSpawn() -- Remover fogo caso saia da tela if( fire.x \> display.actualContentHeight + 50) then fire:removeSelf() end group:insert(fire) end

OK.  I see that you added the print statement to the collision filter, and that the first print is working, while the second is not.  To understand why the second isn’t printing, you need to understand why the conditions aren’t true.  To understand that, you should print out event.phase, event.target.type, and event.other.type.

  • Andrew

I think a found the problem, when i try to print event.phase, it always print nil.

Cool, so you’ve narrowed it down.  And I think I may know the reason.  If you look at the collision detection guide (http://developer.coronalabs.com/content/game-edition-collision-detection), you’ll notice that, for a local collision listener, your function should take two parameters, self and event.  But your function is only taking event.

  • Andrew

Thank you very much, for all the help!

Still stucked! anyone?

What’s this code doing?  What is ‘filter’, a custom class you created?  My first suggestion would be to consult the documentation for physics.addBody() at http://docs.coronalabs.com/api/library/physics/addBody.html to make sure you’re actually creating the body correctly.

[lua]

filter:deploy( monstroPhys, monstro.name , {‘NOMEFIRE’} )

[/lua]

Also, you haven’t posted enough code to diagnose the issue.  Your collision listener checks the type of the target and the other object, but you haven’t shown us that you’ve assigned those type properties to those objects.

Insert a print statement at the top of your collision listener.  That way you can tell whether the problem is the collision listener not firing at all, or whether the problem is with part that checks the type of the target and other object.

  • Andrew

This would be the Spawn Monster Class: 

 local function spawnObj(params) local monstro = display.newImageRect(params.image, params.sizew, params.sizeh ) monstro.x = params.posX monstro.y = params.posY monstro.objTable = params.objTable monstro.type = params.type monstro.index = #monstro.objTable + 1 monstro.myName = "Object :" .. monstro.index monstro.name = params.nome monstro.vida = params.vida monstro.objTable[monstro.index] = monstro monstro.tipo = params.tipo or static monstro.density = params.density or 0 monstro.friction = params.friction or 0 monstro.bounce = params.bounce or 0 monstro.isSensor = params.isSensor or false if params.hasBody then local monstroPhys = {density = monstro.density, friction = monstro.friction, bounce = monstro.bounce, isSensor = monstro.isSensor} physics.addBody(monstro, "dynamic", filter:deploy( monstroPhys, monstro.name , {'NOMEFIRE'} )) end if params.move then monstro.tempo = params.transtime or 1000 monstro.delay = params.delay or 0 monstro.destinox = params.destinox or 200 monstro.destinoy = params.destinoy or 200 monstro.funcao = params.quandoCompletar or nil transition.to(monstro, {time = monstro.tempo, x = monstro.destinox, y = monstro.destinoy, }) end local function onCollision ( event ) print('Working') -- is printing if event.phase == "began" then if event.target.type == "monstro" and event.other.tyoe == "fire" then print("Not Working") end end end monstro.collision = onCollision monstro:addEventListener("collision", monstro) group:insert(monstro) return monstro end

And the Filter Class come from here: https://github.com/zooom/filter

This is the Fire: 

local function spawnMagic() local fire = display.newImageRect("images/fireball.png", 50, 30) local forcaX local anguloY fire.type = "fire" fire.isFixedRotation = true fire.name = "NOMEFIRE" fire.x = mago.x + 50 fire.y = mago.y - 10 -- Calcula forca do ForcaX baseado no tanto que o touch foi arrastado no rastreador if(forca \< 9) then forcaX = "0."..forca elseif(forca \< 45) then forcaX = 1 elseif(forca \< 80) then forcaX = 2 elseif(forca \< 120) then forcaX = 3 elseif(forca \< 180) then forcaX = 5 elseif(forca \< 220) then forcaX = 6.5 elseif(forca \< 300) then forcaX = 7 elseif(forca \< 5000) then forcaX = 8 end -- Calcular angulo if(angulo \< 110) then anguloY = -3 elseif(angulo \< 175) then anguloY = -2 elseif( angulo \< 300) then anguloY = 0 end -- destroirFire temporario local firephys = { density = 0.1, friction = 03, bounce = 0.4, isSensor = false } physics.addBody(fire, "dynamic", filter:deploy( firephys, 'NOMEFIRE', {'NOMEMONSTRO', 'NOMEFLOOR'} )) fire:applyLinearImpulse( forcaX, anguloY, fire.x, fire.y) -- chamarSpawn() -- Remover fogo caso saia da tela if( fire.x \> display.actualContentHeight + 50) then fire:removeSelf() end group:insert(fire) end

OK.  I see that you added the print statement to the collision filter, and that the first print is working, while the second is not.  To understand why the second isn’t printing, you need to understand why the conditions aren’t true.  To understand that, you should print out event.phase, event.target.type, and event.other.type.

  • Andrew

I think a found the problem, when i try to print event.phase, it always print nil.

Cool, so you’ve narrowed it down.  And I think I may know the reason.  If you look at the collision detection guide (http://developer.coronalabs.com/content/game-edition-collision-detection), you’ll notice that, for a local collision listener, your function should take two parameters, self and event.  But your function is only taking event.

  • Andrew

Thank you very much, for all the help!