Collision Detection Problem

I’m having a persistent problem with a collision listener.  I’m creating a car group and applying the physics shape to that group.  I give the group the attribute car.objType = “carBody”.  Then I create another object and the collision listener applies to that object.  I’ve place print statements in the collision function printing the objType of what collides with that object the listener applies to.  

When going into the game, everything works just fine… the first time.  I get the reaction I expect including the print statements.  

However, if I restart the level (using composer.gotoScene, “restart”… which then after a time delay goes right back into game.lua) and the car collides with the object, the print statement sees the car.objType as nil.

I also get the exact same behavior using car.myName instead of objType.

Does anyone know if there are unique limitations with applying physics characteristics to groups instead of just objects… or anything else I am missing?

You need to post some code.

https://forums.coronalabs.com/topic/55780-ask-a-better-question-get-a-better-answer/

Thanks for the reply horacebury.  Here is the code showing how the car is built, how the object is built, and how I have the collision listener set up.  Everything works beautifully the first time through, but after a restart (leaving the scene and returning via composer.gotoScene()… the collision event sees the car as nil.

--========================================================================= --Build Player Car --========================================================================= local car = display.newGroup() local bodyGroup = display.newGroup() local backWheelGroup = display.newGroup() local frontWheelGroup = display.newGroup() local carBodyImage = carProperties.carBodyImageGold local carBody2Image = carProperties.carBody2ImageGold local carBodyWidth = carProperties.carBodyWidth local carBodyHeight = carProperties.carBodyHeight local carBody2Width = carProperties.carBody2Width local carBody2Height = carProperties.carBody2Height local carBody3Image = carProperties.carBody3Image local carBody3Height = carProperties.carBody3Height local bodyGroupOrg = carProperties.bodyGroupOrg local backWheelOrg = carProperties.backWheelOrg local frontWheelOrg = carProperties.frontWheelOrg local carShape = carProperties.carShape local wheelYOrg = carProperties.wheelYOrg local body = display.newImageRect(car, carBodyImage, carBodyWidth, carBodyHeight) local body2 = display.newImageRect(car, carBody2Image, carBody2Width, carBody2Height) local spriteLayout1 = carProperties.spriteLayout1 local carsheetImage1 = graphics.newImageSheet( carBody3Image, spriteLayout1) local spriteLayout2 = carProperties.spriteLayout2 local spriteSequence1 = carProperties.spriteSequence1 local body3 = display.newSprite(carsheetImage1, spriteSequence1) body3:setSequence("noBoost") body3:play() car:insert(backWheelGroup) car:insert(frontWheelGroup) local backWheel1 = display.newImageRect(backWheelGroup, ( globals.collectTable.wheelTable[carTable.WHEEL] ), 34, 34) local frontWheel1 = display.newImageRect(frontWheelGroup, ( globals.collectTable.wheelTable[carTable.WHEEL] ), 34, 34) local directionArrow = display.newImageRect("images/directionArrow.png", 70, 60) directionArrow.alpha = .5 bodyGroup:insert(directionArrow) backWheelGroup.alpha = carProperties.wheelAlpha frontWheelGroup.alpha = carProperties.wheelAlpha bodyGroup:insert(body3) bodyGroup:insert(body) bodyGroup:insert(body2) bodyGroup:insert(backWheelGroup) bodyGroup:insert(frontWheelGroup) ----------------------------------------- -- Get everything in the right place ----------------------------------------- bodyGroup.x = 0 bodyGroup.y = \_H\*-.25 - bodyGroupOrg backWheelGroup.x = 0 - backWheelOrg backWheelGroup.y = \_H\*-.25 frontWheelGroup.x = 0 + frontWheelOrg frontWheelGroup.y = \_H\*-.25 ----------------------------------------- -- put all components into single group ----------------------------------------- car:insert(bodyGroup) car:insert(backWheelGroup) car:insert(frontWheelGroup) ----------------------------------------- -- Make into physics objects ----------------------------------------- physics.addBody(bodyGroup, "dynamic", {density = 0.07, friction = 0.5, bounce = 0, shape = carShape }) physics.addBody(backWheelGroup, "dynamic", {density=carTable.CAR\_WEIGHT, bounce = 0.3, friction = carTable.WHEEL\_STICKY, radius=\_H\*.046875}, { shape={\_H\*.020,-\_H\*.020,\_H\*.020,\_H\*.020,-\_H\*.020,\_H\*.020,-\_H\*.020,-\_H\*.020}, isSensor=true }) physics.addBody(frontWheelGroup, "dynamic", {density=carTable.CAR\_WEIGHT, bounce = 0.3, friction = carTable.WHEEL\_STICKY, radius=\_H\*.046875}, { shape={\_H\*.020,-\_H\*.020,\_H\*.020,\_H\*.020,-\_H\*.020,\_H\*.020,-\_H\*.020,-\_H\*.020}, isSensor=true }) bodyGroup.objType = "carBody" backWheelGroup.objType = "backWheel" frontWheelGroup.objType = "frontWheel" bodyGroup.isBullet = true backWheelGroup.isBullet = true frontWheelGroup.isBullet = true bodyGroup.isSleepingAllowed = false backWheelGroup.isSleepingAllowed = false frontWheelGroup.isSleepingAllowed = false bodyGroup.isAwake = true backWheelGroup.isAwake = true frontWheelGroup.isAwake = true ----------------------------------------- -- Create joints to define behaviour ----------------------------------------- local backWheelJoint = physics.newJoint ("pivot", bodyGroup, backWheelGroup, backWheelGroup.x, backWheelGroup.y) local frontWheelJoint = physics.newJoint ("pivot", bodyGroup, frontWheelGroup, frontWheelGroup.x, frontWheelGroup.y) local swayBarJoint = physics.newJoint("distance", backWheelGroup, frontWheelGroup, backWheelGroup.x, backWheelGroup.y, frontWheelGroup.x, frontWheelGroup.y) ------------------------------------------------ -- Turn the pivot joints into motors. ------------------------------------------------ backWheelJoint.isMotorEnabled = true backWheelJoint.motorSpeed = 0 backWheelJoint.maxMotorTorque = 10000 frontWheelJoint.isMotorEnabled = true frontWheelJoint.motorSpeed = 0 frontWheelJoint.maxMotorTorque = 10000 swayBarJoint.dampingRatio = .10 swayBarJoint.frequency = 1 ------------------------------------------------ -- Wheel and car rotation behavior ------------------------------------------------ bodyGroup.angularDamping = 100 --car rotation resistance backWheelGroup.angularDamping = 1 --slow down wheels naturally frontWheelGroup.angularDamping = 1 --slow down wheels naturally ----------------------------------------- -- Set spin of pivot joints to power car ----------------------------------------- local function car:setSpeed(s) backWheelJoint.motorSpeed = s frontWheelJoint.motorSpeed = s end --========================================================================= --Build BallDoor Object --========================================================================= local ballDoor = display.newImageRect(levelObjectsFront, "levels/level18/goldBall.png", 182, 182) ballDoor.x = 2068 ballDoor.y = -2102 ballDoor.objType = "ballDoor" physics.addBody( ballDoor, { density=.001, friction=0.3, bounce=0, radius=91 } ) local goldBallSensor = display.newRect(levelObjectsBack, 2350, -2102, 50, 400) physics.addBody(goldBallSensor, {density= 0, bounce = 0, friction = 0, isSensor = true}) goldBallSensor.bodyType = "static" goldBallSensor.objType = "doorBallSensor" goldBallSensor.rotation = 0 goldBallSensor.alpha = 0 --========================================================================= --Ball Door Collision Listener --========================================================================= local function goldBallTouch(self, event) if (event.phase == "began") then --print("goldBallTouch called") --After Restart, this event happens --print(event.other.objType) --But this shows the event.other.objType = nil (Should be frontWheel, backWheel, or carBody) -This works fine on first run, just not after restart. if globals.redWheelCollected == true then if event.other.objType == "carBody" or event.other.objType == "backWheel" or event.other.objType == "frontWheel" then print("Contact with some part of car.") elseif event.other.objType == "doorBallSensor" and globals.fireBallHit == true then print("Contact with Ball Door Sensor") end end end return true end ballDoor.collision = goldBallTouch ballDoor:addEventListener( "collision", ballDoor )

Does anyone have any suggestions?

Hi @kthompson200,

It’s rarely (if ever) a good idea to add a physics body to an entire group of objects. It causes all sorts of potential problems. I would avoid doing so… there are almost always better ways.

Brent

You need to post some code.

https://forums.coronalabs.com/topic/55780-ask-a-better-question-get-a-better-answer/

Thanks for the reply horacebury.  Here is the code showing how the car is built, how the object is built, and how I have the collision listener set up.  Everything works beautifully the first time through, but after a restart (leaving the scene and returning via composer.gotoScene()… the collision event sees the car as nil.

--========================================================================= --Build Player Car --========================================================================= local car = display.newGroup() local bodyGroup = display.newGroup() local backWheelGroup = display.newGroup() local frontWheelGroup = display.newGroup() local carBodyImage = carProperties.carBodyImageGold local carBody2Image = carProperties.carBody2ImageGold local carBodyWidth = carProperties.carBodyWidth local carBodyHeight = carProperties.carBodyHeight local carBody2Width = carProperties.carBody2Width local carBody2Height = carProperties.carBody2Height local carBody3Image = carProperties.carBody3Image local carBody3Height = carProperties.carBody3Height local bodyGroupOrg = carProperties.bodyGroupOrg local backWheelOrg = carProperties.backWheelOrg local frontWheelOrg = carProperties.frontWheelOrg local carShape = carProperties.carShape local wheelYOrg = carProperties.wheelYOrg local body = display.newImageRect(car, carBodyImage, carBodyWidth, carBodyHeight) local body2 = display.newImageRect(car, carBody2Image, carBody2Width, carBody2Height) local spriteLayout1 = carProperties.spriteLayout1 local carsheetImage1 = graphics.newImageSheet( carBody3Image, spriteLayout1) local spriteLayout2 = carProperties.spriteLayout2 local spriteSequence1 = carProperties.spriteSequence1 local body3 = display.newSprite(carsheetImage1, spriteSequence1) body3:setSequence("noBoost") body3:play() car:insert(backWheelGroup) car:insert(frontWheelGroup) local backWheel1 = display.newImageRect(backWheelGroup, ( globals.collectTable.wheelTable[carTable.WHEEL] ), 34, 34) local frontWheel1 = display.newImageRect(frontWheelGroup, ( globals.collectTable.wheelTable[carTable.WHEEL] ), 34, 34) local directionArrow = display.newImageRect("images/directionArrow.png", 70, 60) directionArrow.alpha = .5 bodyGroup:insert(directionArrow) backWheelGroup.alpha = carProperties.wheelAlpha frontWheelGroup.alpha = carProperties.wheelAlpha bodyGroup:insert(body3) bodyGroup:insert(body) bodyGroup:insert(body2) bodyGroup:insert(backWheelGroup) bodyGroup:insert(frontWheelGroup) ----------------------------------------- -- Get everything in the right place ----------------------------------------- bodyGroup.x = 0 bodyGroup.y = \_H\*-.25 - bodyGroupOrg backWheelGroup.x = 0 - backWheelOrg backWheelGroup.y = \_H\*-.25 frontWheelGroup.x = 0 + frontWheelOrg frontWheelGroup.y = \_H\*-.25 ----------------------------------------- -- put all components into single group ----------------------------------------- car:insert(bodyGroup) car:insert(backWheelGroup) car:insert(frontWheelGroup) ----------------------------------------- -- Make into physics objects ----------------------------------------- physics.addBody(bodyGroup, "dynamic", {density = 0.07, friction = 0.5, bounce = 0, shape = carShape }) physics.addBody(backWheelGroup, "dynamic", {density=carTable.CAR\_WEIGHT, bounce = 0.3, friction = carTable.WHEEL\_STICKY, radius=\_H\*.046875}, { shape={\_H\*.020,-\_H\*.020,\_H\*.020,\_H\*.020,-\_H\*.020,\_H\*.020,-\_H\*.020,-\_H\*.020}, isSensor=true }) physics.addBody(frontWheelGroup, "dynamic", {density=carTable.CAR\_WEIGHT, bounce = 0.3, friction = carTable.WHEEL\_STICKY, radius=\_H\*.046875}, { shape={\_H\*.020,-\_H\*.020,\_H\*.020,\_H\*.020,-\_H\*.020,\_H\*.020,-\_H\*.020,-\_H\*.020}, isSensor=true }) bodyGroup.objType = "carBody" backWheelGroup.objType = "backWheel" frontWheelGroup.objType = "frontWheel" bodyGroup.isBullet = true backWheelGroup.isBullet = true frontWheelGroup.isBullet = true bodyGroup.isSleepingAllowed = false backWheelGroup.isSleepingAllowed = false frontWheelGroup.isSleepingAllowed = false bodyGroup.isAwake = true backWheelGroup.isAwake = true frontWheelGroup.isAwake = true ----------------------------------------- -- Create joints to define behaviour ----------------------------------------- local backWheelJoint = physics.newJoint ("pivot", bodyGroup, backWheelGroup, backWheelGroup.x, backWheelGroup.y) local frontWheelJoint = physics.newJoint ("pivot", bodyGroup, frontWheelGroup, frontWheelGroup.x, frontWheelGroup.y) local swayBarJoint = physics.newJoint("distance", backWheelGroup, frontWheelGroup, backWheelGroup.x, backWheelGroup.y, frontWheelGroup.x, frontWheelGroup.y) ------------------------------------------------ -- Turn the pivot joints into motors. ------------------------------------------------ backWheelJoint.isMotorEnabled = true backWheelJoint.motorSpeed = 0 backWheelJoint.maxMotorTorque = 10000 frontWheelJoint.isMotorEnabled = true frontWheelJoint.motorSpeed = 0 frontWheelJoint.maxMotorTorque = 10000 swayBarJoint.dampingRatio = .10 swayBarJoint.frequency = 1 ------------------------------------------------ -- Wheel and car rotation behavior ------------------------------------------------ bodyGroup.angularDamping = 100 --car rotation resistance backWheelGroup.angularDamping = 1 --slow down wheels naturally frontWheelGroup.angularDamping = 1 --slow down wheels naturally ----------------------------------------- -- Set spin of pivot joints to power car ----------------------------------------- local function car:setSpeed(s) backWheelJoint.motorSpeed = s frontWheelJoint.motorSpeed = s end --========================================================================= --Build BallDoor Object --========================================================================= local ballDoor = display.newImageRect(levelObjectsFront, "levels/level18/goldBall.png", 182, 182) ballDoor.x = 2068 ballDoor.y = -2102 ballDoor.objType = "ballDoor" physics.addBody( ballDoor, { density=.001, friction=0.3, bounce=0, radius=91 } ) local goldBallSensor = display.newRect(levelObjectsBack, 2350, -2102, 50, 400) physics.addBody(goldBallSensor, {density= 0, bounce = 0, friction = 0, isSensor = true}) goldBallSensor.bodyType = "static" goldBallSensor.objType = "doorBallSensor" goldBallSensor.rotation = 0 goldBallSensor.alpha = 0 --========================================================================= --Ball Door Collision Listener --========================================================================= local function goldBallTouch(self, event) if (event.phase == "began") then --print("goldBallTouch called") --After Restart, this event happens --print(event.other.objType) --But this shows the event.other.objType = nil (Should be frontWheel, backWheel, or carBody) -This works fine on first run, just not after restart. if globals.redWheelCollected == true then if event.other.objType == "carBody" or event.other.objType == "backWheel" or event.other.objType == "frontWheel" then print("Contact with some part of car.") elseif event.other.objType == "doorBallSensor" and globals.fireBallHit == true then print("Contact with Ball Door Sensor") end end end return true end ballDoor.collision = goldBallTouch ballDoor:addEventListener( "collision", ballDoor )

Does anyone have any suggestions?

Hi @kthompson200,

It’s rarely (if ever) a good idea to add a physics body to an entire group of objects. It causes all sorts of potential problems. I would avoid doing so… there are almost always better ways.

Brent