Collision Filters Not Working (Code Update)

as to continue my post at : link

 

i am following the instruction at : link& i have updated the code to :

 

 

badc1CollisionFilter = { categoryBits = 1, maskBits = 16 } badc2CollisionFilter = { categoryBits = 2, maskBits = 16 } badc3CollisionFilter = { categoryBits = 4, maskBits = 16 } wallCollisionFilter = { categoryBits = 8, maskBits = 16 } playerCollisionFilter = { categoryBits = 16, maskBits = 15 } function getRandomStar()     local temp = starTable[math.random(1, #starTable)]     local randomStar = display.newImage(temp.imgpath)          if ( temp.imgpath == "BCloud1.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc1CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          if ( temp.imgpath == "BCloud2.png" ) then     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     physics.addBody( randomStar, "static", { density=.1, bounce=.1, friction=.2, radius=45 } )         end          if ( temp.imgpath == "BCloud3.png" ) then     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     physics.addBody( randomStar, "static", { density=.1, bounce=.1, friction=.2, radius=45 } )         end          randomStar.myName = "star" -- Set the name of the object to star     randomStar.movementSpeed = temp.movementSpeed; -- Set how fast the object will move     randomStar.x = math.random(-30, \_W);         randomStar.y = -35;     randomStar.rotation = math.random(0,20) -- Rotate the object          starMove = transition.to(randomStar, {         time=randomStar.movementSpeed,          y=500,         onComplete = function(self) self.parent:remove(self); self = nil;          end         }) -- Move the star end     playerSpriteSheet = sprite.newSpriteSheet("player.png", 113, 55)     playerSprites = sprite.newSpriteSet(playerSpriteSheet, 1, 4)     sprite.add(playerSprites, "players", 1, 4, 1000, 0)     player = sprite.newSprite(playerSprites)     player.x = -80     player.y = 350     player:prepare("players")     player:play()     player.collided = false     player:setReferencePoint(display.CenterReferencePoint);         physics.addBody(player, "static", {density=.1, bounce=0.1, friction=.2, radius=10, filter=playerCollisionFilter } )         player.gravityScale = 0     screenGroup:insert(player)     playerIntro = transition.to(player,{time=2000, x=150, onComplete=playerReady})  local collision = function( badc1CollisionFilter )  if badc1CollisionFilter.phase == 'began' then    print("Hello i am  badc1CollisionFilter")  end end     Runtime:addEventListener("badc1CollisionFilter", collision)

 

 

 

so i like the ‘player’ to collide whit badc1CollisionFilter but nothing is happening, and i don’t understand what i am doing wrong

 

Hi @mmk.verheijden,

I see a couple issues here:

  1. Try naming your collision function something other than “collision”. It might be messing things up. Name it something like “playerCollision”.

  2. Try using just “event” as the argument to it, instead of “badc1CollisionFilter”. You’re using the same name as your collision filter, which also might be messing up Lua references.

  3. Most importantly, your first parameter to the Runtime listener is not valid. It should be “collision”, not “badc1CollisionFilter”. And of course, if you change the function name (point #1), don’t forget to change it here as well.

Try these things and let me know what happens.

Thanks,

Brent

Hi Brent if i try this :

 

 

 

 

badc1CollisionFilter = { categoryBits = 1, maskBits = 16 } badc2CollisionFilter = { categoryBits = 2, maskBits = 16 } badc3CollisionFilter = { categoryBits = 4, maskBits = 16 } wallCollisionFilter = { categoryBits = 8, maskBits = 16 } playerCollisionFilter = { categoryBits = 16, maskBits = 15 }    function getRandomStar()   local temp = starTable[math.random(1, #starTable)]     local randomStar = display.newImage(temp.imgpath)            if ( temp.imgpath == "BCloud1.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc1CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          if ( temp.imgpath == "BCloud2.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc2CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          if ( temp.imgpath == "BCloud3.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc3CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          randomStar.myName = "star" -- Set the name of the object to star     randomStar.movementSpeed = temp.movementSpeed; -- Set how fast the object will move     randomStar.x = math.random(-30, \_W);         randomStar.y = -35;     randomStar.rotation = math.random(0,20) -- Rotate the object          starMove = transition.to(randomStar, {         time=randomStar.movementSpeed,          y=500,         onComplete = function(self) self.parent:remove(self); self = nil;          end         }) -- Move the star end     ceiling = display.newImage("invisibleTile.png")     ceiling:setReferencePoint(display.BottomLeftReferencePoint)     ceiling.x = 0     ceiling.y = 0     physics.addBody(ceiling, "static", {density=.1, bounce=0.1, friction=.2, filter=wallCollisionFilter } )         screenGroup:insert(ceiling)          theFloor = display.newImage("invisibleTile.png")     theFloor:setReferencePoint(display.BottomLeftReferencePoint)     theFloor.x = 0     theFloor.y = 510     physics.addBody(theFloor, "static", {density=.1, bounce=0.1, friction=.2, filter=wallCollisionFilter } )             screenGroup:insert(theFloor)     playerSpriteSheet = sprite.newSpriteSheet("player.png", 113, 55)     playerSprites = sprite.newSpriteSet(playerSpriteSheet, 1, 4)     sprite.add(playerSprites, "players", 1, 4, 1000, 0)     player = sprite.newSprite(playerSprites)     player.x = -80     player.y = 350     player:prepare("players")     player:play()     player.collided = false     player:setReferencePoint(display.CenterReferencePoint);         physics.addBody(player, "static", {density=.1, bounce=0.1, friction=.2, radius=10, filter=playerCollisionFilter } )         player.gravityScale = 0     screenGroup:insert(player)     playerIntro = transition.to(player,{time=2000, x=150, onComplete=playerReady})  local badc1collision = function( badc1CollisionFilter )  if badc1CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter1")  end end  local badc2collision = function( badc2CollisionFilter )  if badc2CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter2")  end end  local badc3collision = function( badc3CollisionFilter )  if badc3CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter3")  end end  local wallcollision = function( wallCollisionFilter )  if wallCollisionFilter.phase == 'began' then    print("Hello i am the wall")  end end     Runtime:addEventListener("collision", badc1collision)     Runtime:addEventListener("collision", badc2collision)     Runtime:addEventListener("collision", badc3collision)         Runtime:addEventListener("collision", wallcollision)  

 

 

 

The terminal prints :

 

Hello i am CollisionFilter1

Hello i am CollisionFilter2

Hello i am CollisionFilter3

Hello i am the wall

 

on every collision 

 

Regards Kevin

Hi Kevin,
It’s not necessary to create so many collision listeners. One Runtime collision listener is sufficient (you could also do a local collision listener, which accomplishes the same basic thing, just in a slightly different coding method). What’s important is how you conditionally handle the objects involved in the collision, using collision filters.
 
[lua]

local gameCollision = function( event )

if event.phase == ‘began’ then

print(“a collision occurred”)

end

end

[/lua]
 
Hope this helps,
Brent

P.S. as a side note, I see you’re using the deprecated “sprite” library. You should convert your sprites to the current method which uses the “display” library. Here’s a tutorial on it: http://www.coronalabs.com/blog/2012/10/02/animated-sprites-and-methods/

Hi Brent, is if i try :

 

 

 local onCollision = function( badc1CollisionFilter )  if badc1CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter1")  end end  local onCollision = function( badc2CollisionFilter )  if badc2CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter2")  end end  local onCollision = function( badc3CollisionFilter )  if badc3CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter3")  end end  local onCollision = function( wallCollisionFilter )  if wallCollisionFilter.phase == 'began' then    print("Hello i am the wall")  end end Runtime:addEventListener( "collision", onCollision )  

 

im printing Hello i am the wall for every collision, ? i don’t understand what i am doing wrong here

Hi Kevin,

Please attempt to reduce your code down to just one collision listener. In the above example you have 4 functions named the same thing. Also, you shouldn’t be passing your collision filter(s) as argument(s) to the collision function. Use “event” or something like I described.

Hi Brent i failing to understand how to assign different actions to the collisions 

 

 

local collisions = function( event )   if event.phase == 'began' then     if badc1CollisionFilter.phase == 'began' then     print("Hello i am CollisionFilter1")     end     if badc2CollisionFilter.phase == 'began' then     print("Hello i am CollisionFilter2")     end     if badc3CollisionFilter.phase == 'began' then     print("Hello i am CollisionFilter3")     end          if wallCollisionFilter.phase == 'began' then     print("Hello i am the wall")     end       end end Runtime:addEventListener("collision", collisions)

 

Also this is not the way of doing it. any pointers ?

 

Regards kevin

Hi @mmk.verheijden,

I see a couple issues here:

  1. Try naming your collision function something other than “collision”. It might be messing things up. Name it something like “playerCollision”.

  2. Try using just “event” as the argument to it, instead of “badc1CollisionFilter”. You’re using the same name as your collision filter, which also might be messing up Lua references.

  3. Most importantly, your first parameter to the Runtime listener is not valid. It should be “collision”, not “badc1CollisionFilter”. And of course, if you change the function name (point #1), don’t forget to change it here as well.

Try these things and let me know what happens.

Thanks,

Brent

Hi Kevin,

Collision filters aren’t really intended for checking the “type” of objects, merely to dictate what objects collide (or don’t collide) with others. To conditionally handle the collision that DO occur (with your collision filters established), you should add a parameter (i.e. “myName”) to each object, then when the collision occurs, you check this parameter and handle it however you like.

[lua]

local theFloor = display.newRect( [your parameters] )

physics.addBody(theFloor, “static”, {density=.1, bounce=0.1, friction=.2, filter=floorCollisionFilter } )

theFloor.myName = “floor”
local collisions = function( event )

if ( event.phase == ‘began’ ) then

print( "began: " … event.object1.myName … " & " … event.object2.myName )

end

end

[/lua]

Hi Brent if i try this :

 

 

 

 

badc1CollisionFilter = { categoryBits = 1, maskBits = 16 } badc2CollisionFilter = { categoryBits = 2, maskBits = 16 } badc3CollisionFilter = { categoryBits = 4, maskBits = 16 } wallCollisionFilter = { categoryBits = 8, maskBits = 16 } playerCollisionFilter = { categoryBits = 16, maskBits = 15 }    function getRandomStar()   local temp = starTable[math.random(1, #starTable)]     local randomStar = display.newImage(temp.imgpath)            if ( temp.imgpath == "BCloud1.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc1CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          if ( temp.imgpath == "BCloud2.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc2CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          if ( temp.imgpath == "BCloud3.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc3CollisionFilter } )     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png";     end          randomStar.myName = "star" -- Set the name of the object to star     randomStar.movementSpeed = temp.movementSpeed; -- Set how fast the object will move     randomStar.x = math.random(-30, \_W);         randomStar.y = -35;     randomStar.rotation = math.random(0,20) -- Rotate the object          starMove = transition.to(randomStar, {         time=randomStar.movementSpeed,          y=500,         onComplete = function(self) self.parent:remove(self); self = nil;          end         }) -- Move the star end     ceiling = display.newImage("invisibleTile.png")     ceiling:setReferencePoint(display.BottomLeftReferencePoint)     ceiling.x = 0     ceiling.y = 0     physics.addBody(ceiling, "static", {density=.1, bounce=0.1, friction=.2, filter=wallCollisionFilter } )         screenGroup:insert(ceiling)          theFloor = display.newImage("invisibleTile.png")     theFloor:setReferencePoint(display.BottomLeftReferencePoint)     theFloor.x = 0     theFloor.y = 510     physics.addBody(theFloor, "static", {density=.1, bounce=0.1, friction=.2, filter=wallCollisionFilter } )             screenGroup:insert(theFloor)     playerSpriteSheet = sprite.newSpriteSheet("player.png", 113, 55)     playerSprites = sprite.newSpriteSet(playerSpriteSheet, 1, 4)     sprite.add(playerSprites, "players", 1, 4, 1000, 0)     player = sprite.newSprite(playerSprites)     player.x = -80     player.y = 350     player:prepare("players")     player:play()     player.collided = false     player:setReferencePoint(display.CenterReferencePoint);         physics.addBody(player, "static", {density=.1, bounce=0.1, friction=.2, radius=10, filter=playerCollisionFilter } )         player.gravityScale = 0     screenGroup:insert(player)     playerIntro = transition.to(player,{time=2000, x=150, onComplete=playerReady})  local badc1collision = function( badc1CollisionFilter )  if badc1CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter1")  end end  local badc2collision = function( badc2CollisionFilter )  if badc2CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter2")  end end  local badc3collision = function( badc3CollisionFilter )  if badc3CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter3")  end end  local wallcollision = function( wallCollisionFilter )  if wallCollisionFilter.phase == 'began' then    print("Hello i am the wall")  end end     Runtime:addEventListener("collision", badc1collision)     Runtime:addEventListener("collision", badc2collision)     Runtime:addEventListener("collision", badc3collision)         Runtime:addEventListener("collision", wallcollision)  

 

 

 

The terminal prints :

 

Hello i am CollisionFilter1

Hello i am CollisionFilter2

Hello i am CollisionFilter3

Hello i am the wall

 

on every collision 

 

Regards Kevin

Hi Kevin,
It’s not necessary to create so many collision listeners. One Runtime collision listener is sufficient (you could also do a local collision listener, which accomplishes the same basic thing, just in a slightly different coding method). What’s important is how you conditionally handle the objects involved in the collision, using collision filters.
 
[lua]

local gameCollision = function( event )

if event.phase == ‘began’ then

print(“a collision occurred”)

end

end

[/lua]
 
Hope this helps,
Brent

P.S. as a side note, I see you’re using the deprecated “sprite” library. You should convert your sprites to the current method which uses the “display” library. Here’s a tutorial on it: http://www.coronalabs.com/blog/2012/10/02/animated-sprites-and-methods/

Hi Brent, is if i try :

 

 

 local onCollision = function( badc1CollisionFilter )  if badc1CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter1")  end end  local onCollision = function( badc2CollisionFilter )  if badc2CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter2")  end end  local onCollision = function( badc3CollisionFilter )  if badc3CollisionFilter.phase == 'began' then    print("Hello i am CollisionFilter3")  end end  local onCollision = function( wallCollisionFilter )  if wallCollisionFilter.phase == 'began' then    print("Hello i am the wall")  end end Runtime:addEventListener( "collision", onCollision )  

 

im printing Hello i am the wall for every collision, ? i don’t understand what i am doing wrong here

Hi Kevin,

Please attempt to reduce your code down to just one collision listener. In the above example you have 4 functions named the same thing. Also, you shouldn’t be passing your collision filter(s) as argument(s) to the collision function. Use “event” or something like I described.

Hi Brent i failing to understand how to assign different actions to the collisions 

 

 

local collisions = function( event )   if event.phase == 'began' then     if badc1CollisionFilter.phase == 'began' then     print("Hello i am CollisionFilter1")     end     if badc2CollisionFilter.phase == 'began' then     print("Hello i am CollisionFilter2")     end     if badc3CollisionFilter.phase == 'began' then     print("Hello i am CollisionFilter3")     end          if wallCollisionFilter.phase == 'began' then     print("Hello i am the wall")     end       end end Runtime:addEventListener("collision", collisions)

 

Also this is not the way of doing it. any pointers ?

 

Regards kevin

Hi Kevin,

Collision filters aren’t really intended for checking the “type” of objects, merely to dictate what objects collide (or don’t collide) with others. To conditionally handle the collision that DO occur (with your collision filters established), you should add a parameter (i.e. “myName”) to each object, then when the collision occurs, you check this parameter and handle it however you like.

[lua]

local theFloor = display.newRect( [your parameters] )

physics.addBody(theFloor, “static”, {density=.1, bounce=0.1, friction=.2, filter=floorCollisionFilter } )

theFloor.myName = “floor”
local collisions = function( event )

if ( event.phase == ‘began’ ) then

print( "began: " … event.object1.myName … " & " … event.object2.myName )

end

end

[/lua]

I have been playing around and tried this :

badc1CollisionFilter = { categoryBits = 1, maskBits = 16 } badc2CollisionFilter = { categoryBits = 2, maskBits = 16 } badc3CollisionFilter = { categoryBits = 4, maskBits = 16 } wallCollisionFilter = { categoryBits = 8, maskBits = 16 } playerCollisionFilter = { categoryBits = 16, maskBits = 15 } if ( temp.imgpath == "BCloud1.png" ) then physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc1CollisionFilter } ) randomStar.myName = "star1" temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; end if ( temp.imgpath == "BCloud2.png" ) then physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc2CollisionFilter } ) randomStar.myName = "star2" temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; end if ( temp.imgpath == "BCloud3.png" ) then physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc3CollisionFilter } ) randomStar.myName = "star3" temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; end physics.addBody(player, "static", {density=.1, bounce=0.1, friction=.2, radius=10, filter=playerCollisionFilter } ) player:addEventListener( "collision", newCollisionHandler ) function newCollisionHandler( self, event ) if event.other.myName == "star1" then print( "Collided with star1" ) elseif event.other.myName == "star2" then print( "Collided with star2" ) elseif event.other.myName == "star3" then print( "Collided with star3" ) end end  

But now corona is trowing a error ? :

DkYpg.png

Any ideas ? 

Regards Kevin,

ps sorry for the late reply, but due to moving location, i was unable to work on the game.

I have been playing around and tried this :

badc1CollisionFilter = { categoryBits = 1, maskBits = 16 } badc2CollisionFilter = { categoryBits = 2, maskBits = 16 } badc3CollisionFilter = { categoryBits = 4, maskBits = 16 } wallCollisionFilter = { categoryBits = 8, maskBits = 16 } playerCollisionFilter = { categoryBits = 16, maskBits = 15 } if ( temp.imgpath == "BCloud1.png" ) then physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc1CollisionFilter } ) randomStar.myName = "star1" temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; end if ( temp.imgpath == "BCloud2.png" ) then physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc2CollisionFilter } ) randomStar.myName = "star2" temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; end if ( temp.imgpath == "BCloud3.png" ) then physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc3CollisionFilter } ) randomStar.myName = "star3" temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; end physics.addBody(player, "static", {density=.1, bounce=0.1, friction=.2, radius=10, filter=playerCollisionFilter } ) player:addEventListener( "collision", newCollisionHandler ) function newCollisionHandler( self, event ) if event.other.myName == "star1" then print( "Collided with star1" ) elseif event.other.myName == "star2" then print( "Collided with star2" ) elseif event.other.myName == "star3" then print( "Collided with star3" ) end end  

But now corona is trowing a error ? :

DkYpg.png

Any ideas ? 

Regards Kevin,

ps sorry for the late reply, but due to moving location, i was unable to work on the game.