Collision Filters Still having some problems

oky so if i understand this is correct ?

function newCollisionHandler( self, event )    print("oh hello i have a Collision")    if randomStar.myName == "BCloud1" then         print("Collided with star1")    elseif event.other.randomStar.myName == "BCloud2" then         print("Collided with star2")    elseif event.other.randomStar.myName == "BCloud3" then         print("Collided with star3")    end end  

Not exactly… in a “local-style” collision, one object is represented by “self” and the other by “event.other”. Those are the direct references to the two objects involved in the collision, so you should deal with them at that level.

Hi Andrew

line 296 is: player:addEventListener( “collision”, newCollisionHandler )

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) local newCollisionHandler player:addEventListener( "collision", newCollisionHandler ) 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})  

Regards Kevin,

Hi Kevin,

Looks like the problem is that newCollisionHandler is in fact nil.  The line 295 “local newCollisionHandler” sets up newCollisionHandler as a local variable with a default value of nil.  You then immediately try to add it as a collision listener to the player object, but since it’s nil, you’ll get an error.  Instead, you need to first define newCollisionHandler as a function, and then add it as a listener.  It looks like from your original post, you may have defined newCollisionHandler as a global function, but the line “local newCollisionHandler” will overwrite that, rescoping newCollisionHandler as local and giving it a default value of nil.

See some of the samples here: http://developer.coronalabs.com/content/game-edition-collision-detection

Hope this helps.

  • Andrew

Hi Andrew,

so when i try this :

    function newCollisionHandler()       playeraddEventListener( "collision", newCollisionHandler )     end

The errors go but now its not detecting any collisions.

-Kevin

Hi Kevin,

Looks like there are two issues with what you pasted there.  First, there’s a colon missing between “player” and “addEventListener”.  But more importantly, you’re defining newCollisionHandler as a function which adds itself(?) as a collision listener.

I’d suggest taking a close look at the example called “Local collision listeners” on this page: http://developer.coronalabs.com/content/game-edition-collision-detection

A quick look at your original post, and nothing is jumping out at me as wrong except that you define newCollisionHandler after you attempt to add as a listener.  You need to define the function before.  In your original post, just move the line “player:addEventListener( “collision”, newCollisionHandler )” below where you define the newCollisionHandler function.

  • Andrew

Oky thanks Andrew, 

i will have a look at it :smiley:

-kevin

oky so from you comments Andrew i have done 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)] -- Get a random star from starTable     local randomStar = display.newImage(temp.imgpath) -- Set image path for object          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          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--END getRandomStar()     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}) 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 function scene:enterScene(event)     player:addEventListener( "collision", newCollisionHandler ) end  

and now i got the error : attempt to index local event (a nil value).

But this time the error corespondents to the image it collides whit, (so that a good sign ?)

ps if i add ‘function newCollisionHandler() end’ to the codel like so : 

   

 function newCollisionHandler() 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})

its not detecting any collision

-kevin

Hi Kevin,

When you get an error, it’ll always refer to the line number in your code it occurred on.  What line number did it refer to, and which line does that correspond to in your code above?

I’m not sure I understood what you mean by your P.S.

  • Andrew

sorry :

if collision on star1 error is on line: “if event.other.myName == “star1” then”

if collision on star2 error is on line: “if event.other.myName == “star2” then”

if collision on star3 error is on line: “if event.other.myName == “star3” then”

from:

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

-kevin

Hi there,

In your enterScene event, try replacing

[lua]

player:addEventListener( “collision”, newCollisionHandler )

[/lua]

with

[lua]

player.collision = newCollisionHandler

player:addEventListener( “collision”, player )

[/lua]

Hi Andrew,

when i do this :

function newCollisionHandler( self, event )         print("oh hello i have a Collision")    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 function scene:enterScene(event)     player.collision = newCollisionHandler     player:addEventListener( "collision", player )  

The terminal prints : ‘oh hello i have a Collision’ but not the ‘Collided with star1/2/3’ ?

-kevin

Hi Kevin,

My suggestion would be to put the statement “print_r(event)” in your newCollisionHandler function.  It’ll print out the entire contents of the event table so you can inspect it and see exactly what it’s reporting about the collision.

You can get an implementation of print_r here: http://developer.coronalabs.com/code/printr-implementation-dumps-everything-human-readable-text

  • Andrew

looks like it cant find the  ‘myName’ in the code if i add ‘print( "test " … myName )’ to the newCollisionHandler it cant find it end trows a global ‘newCollisionHandler’ a nil value.

snip: 

function getRandomStar()     local temp = starTable[math.random(1, #starTable)] -- Get a random star from starTable     local randomStar = display.newImage(temp.imgpath) -- Set image path for object          if ( temp.imgpath == "BCloud1.png" ) then     local object1 =      physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc1CollisionFilter } )     randomStar.myName = "BCloud1"     temp.imgpath = "BCloud"..tostring(math.random(1, 3))..".png"; print( "BC1 print name test " .. randomStar.myName )      end          if ( temp.imgpath == "BCloud2.png" ) then     physics.addBody( randomStar, { density=.1, bounce=0.1, friction=.2, radius=45, filter=badc2CollisionFilter } )     randomStar.myName = "BCloud2"     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 = "BCloud3"     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--END getRandomStar() function newCollisionHandler( self, event )         print("oh hello i have a Collision")         print( "test " .. myName )     if myName == "BCloud1" then         print("Collided with star1")    elseif event.other.myName == "BCloud2" then         print("Collided with star2")    elseif event.other.myName == "BCloud3" then         print("Collided with star3")    end end  

Hi Kevin,

When you do this:

[lua]

print( "test " … myName )

[/lua]

myName is undefined. You haven’t specified that it’s a property on the object, so Lua looks for it as a global variable and can’t find it. You need to specifiy it as a property of either “self” or “event.other”, just like you do in the lines below it.

oky so  i’m trying this in a other way now :

local function onCollision(event)     if event.phase == "began" and gameIsActive == true then         local obj1 = event.object1;          local obj2 = event.object2;          if obj1.name == "player" and obj2.name == "BCloud1" then             print("hello 1")          elseif obj1.name == "player" and obj2.name == "BCloud2" then             print("hello 2")                       elseif obj1.name == "player" and obj2.name == "BCloud3" then             print("hello 3")                       elseif obj1.name == "player" and obj2.name == "wall" then             print("hello im a wall")                  end     end end

Is this correct?

kevin-

Hi Kevin,

This looks correct at first glance, but you’ll need to test it. Of course, I assume you’ve applied the “name” property to everything involved in collisions. :slight_smile:

Brent

Hi Brent,

i am using  randomStar.myName = “BCloud1”  the privies errors are gone, but still it is not printing the  print(“hello im a wall”)

​in the terminal, i will have a play about whit it but its getting there :smiley: ps dos corona handel the publication to the app/play store as well or only export the native app?

Kevin-

Hi Kevin,

Remember to check that the either the player or the wall is a “dynamic” physics body type. At least one body in a collision needs to be dynamic… you can’t get collisions from a “static” + “kinematic” event, for example.

And FYI, Corona doesn’t handle the app submission (to market). It just builds the compiled file which you’ll need to submit to Apple, Google, etc. separately. 

Take care,

Brent

physics.addBody(player, “dynamic”, {density=.1, bounce=0.1, friction=.2, radius=10,} ) 

right ?