Collision event listener calls function but doesnt provide an event object.

Corona detects the collision but when it calls the collision(fight) function it doesn’t pass a meaningful event object. I’m unable to access event.phase or event.target although the event object exists.

Here’s the code:

local version = 0 -- Hide status bar display.setStatusBar(display.HiddenStatusBar) -- Screen Coordinates centerX = display.contentCenterX centerY = display.contentCenterY screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight local physics = require("physics") physics.setDrawMode("normal") local json = require("json") math.randomseed(os.time()); physics.start(); physics.setGravity( 0, 0 ) local function fight(event) ----- This is where its happening. event.phase return nil. print(event.phase); if ( event.phase == "began" ) then print( self.myName .. ": collision began with " .. event.other.myName ) end end local enemy; local floor = display.newRect(centerX, screenBottom, 10000, 50) floor.anchorX = 0.5; floor.anchorY = 1; local function spawn\_enemy() enemy = display.newRect(0, 0, 50, 100); enemy:setFillColor(.7) enemy.anchorY = 1; enemy.x = screenLeft; enemy.y = floor.y - floor.height; enemy.speed = -1; enemy.collision = fight; physics.addBody(enemy); enemy.isSleepingAllowed = false; enemy:addEventListener("collision", enemy); end player = display.newRect(0, 0, 50, 100); player:setFillColor(.7) player.anchorY = 1; player.x = screenRight; player.y = floor.y - floor.height; player.speed = 1; player.collision = fight; physics.addBody(player); player.isSleepingAllowed = false; player:addEventListener("collision", player); local walk = function( event ) --for i, v in ipairs(mob) do player.x = player.x - player.speed; enemy.x = enemy.x - enemy.speed; --end end Runtime:addEventListener( "enterFrame", walk); spawn\_enemy();

Look over my spaghetti code if any, I’ve tried just about everything I could come up with.

Any Suggestions?

Thanks :slight_smile:

Maybe consider dumping the whole event table.

You can require the json module and do a:

print( json.prettify( event ) )

to dump the table.

Rob

{ "\_class":{ "removeEventListener":"\<type 'function' is not supported by JSON.\>", "addEventListener":"\<type 'function' is not supported by JSON.\>", "\_\_index":"\<reference cycle\>" }, "\_proxy":"\<type 'userdata' is not supported by JSON.\>", "\_tableListeners":{ "collision":["\<reference cycle\>"] }, "collision":"\<type 'function' is not supported by JSON.\>", "speed":-1 }

Thanks for the reply Rob, above is the table structure output.

Well, I was hoping this wouldn’t be the case. The collision entry is a “Userdata” type, which can’t be dumped with JSON. You’re going to have to dump it by hand. See:

http://docs.coronalabs.com/api/event/collision/index.html

Go down to the “Property” section and then print each of the values:

print(event.contact)

print(event.name)

etc.

Rob

All nil except event.x and event.y

could this have something to do with the way I’m moving the display objects in the “walk” function?

You need to read the docs…  The correct function declaration for collision would be

local function fight( self, event )

Self is not required, read the docs…

I’m fully convinced that it has something to do with the way I’m moving the objects through the enterframe. Regardless I’ve moved on an used a global collision event but it would still be nice to know the reason why this doesn’t work locally.

self IS required for local collision handlers.  Try it and you will see it fixes your issue.

It’s not required, and I already tried it, same problem.

From the docs (for anyone else reading this)

Local Collision Handling

Local collision handling is best utilized in a one-to-many collision scenario, for example one player object which may collide with multiple enemies, power-ups, etc. For local collision handling, each collision event includes a  self  table ID, representing the object itself, and event.other which contains the table ID of the other Corona display object involved in the collision.

 

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html#handling

Nowhere does it say self is required, it says it’s included so you have a choice of using it. Either way your suggestion did not work and was also the first thing I tried.

That is just not correct.  Self is the first parameter passed and event is the second.  Global handlers do not have self as the first parameter. 

My suggestion worked just fine - I did test it.  I just pasted your code and fixed the function definition. 

In what way did it not work exactly?

Maybe consider dumping the whole event table.

You can require the json module and do a:

print( json.prettify( event ) )

to dump the table.

Rob

{ "\_class":{ "removeEventListener":"\<type 'function' is not supported by JSON.\>", "addEventListener":"\<type 'function' is not supported by JSON.\>", "\_\_index":"\<reference cycle\>" }, "\_proxy":"\<type 'userdata' is not supported by JSON.\>", "\_tableListeners":{ "collision":["\<reference cycle\>"] }, "collision":"\<type 'function' is not supported by JSON.\>", "speed":-1 }

Thanks for the reply Rob, above is the table structure output.

Well, I was hoping this wouldn’t be the case. The collision entry is a “Userdata” type, which can’t be dumped with JSON. You’re going to have to dump it by hand. See:

http://docs.coronalabs.com/api/event/collision/index.html

Go down to the “Property” section and then print each of the values:

print(event.contact)

print(event.name)

etc.

Rob

All nil except event.x and event.y

could this have something to do with the way I’m moving the display objects in the “walk” function?

You need to read the docs…  The correct function declaration for collision would be

local function fight( self, event )

Self is not required, read the docs…

I’m fully convinced that it has something to do with the way I’m moving the objects through the enterframe. Regardless I’ve moved on an used a global collision event but it would still be nice to know the reason why this doesn’t work locally.

self IS required for local collision handlers.  Try it and you will see it fixes your issue.

It’s not required, and I already tried it, same problem.