Adding and subtracting lives within a Collision event.

Ok…I have been trying to solve this problem for the past 3 days now and frankly speaking am about to loose my mind . I have read almost all blogs, tutorial and forum dealing with how to set up a health/lives system and still can get to a solution myself.

The problem seems to be the collision listener function.  Whenever I try to add or deduct a life during a collision (“player and enemy” or “player and power-up”) it does the calculations twice. Thus always collision always fires twice.

Please how do i get around deducting and adding number variables within a collision event. Has anyone solved this issue and how. I tried the timer.performWithdelay as suggested in some tutorials but still the same.

local function onCollision( self, event )

      if ( event.phase == “began” ) then

               if ( event.target and event.other.objType == “enemy1” ) then

                          timer.performWithDelay(1000, 

                                         function()

                                               lives = lives - 1

                                                print(lives)

                         end, 1 )

                 end

     end

end

–associate colllision handler function with character

player.collision = onCollision

player:addEventListener(“collision”, player)

add return true to your onCollision if you have handled the event

I tried that same result…sometimes it even fired 4 times.

local function onCollision( self, event )

    if ( event.phase == “began” ) then

        if ( event.target and event.other.objType == “enemy1” ) then

            timer.performWithDelay(10, 

                function()

                    lives = lives - 1

                    print(lives)

                end, 1)

   end

    end

return true

end

–associate colllision handler function with character

player.collision = onCollision

player:addEventListener(“collision”, player)

Admin note: This post seems to have gotten duplicated several times. I’ve removed the excess ones. 

Rob

Hi @uche,

Can you show the code you’re using for “physics.addBody()” on your “player” object AND on objects it collides with when this issue occurs? I might know what the cause is, but I’ll need to see that code.

Thanks,

Brent

Hello @Brent,

I think I may have discovered what caused the collision to keep firing twice or more…Thanks for pointing out the “physics.addBody()” side of the code. In my player module I added the physics body with a sensor to detect ground collision but on commenting that part of the code; I get the result i want, the event fires once.   In the enemy module i just added the physics body without any sensor.

–=========

—player.lua

–==============

    local player = display.newCircle( 100, 100, 30 )

    player:setFillColor(1,0,0)

    player.x = 400

   physics.addBody( player, “dynamic”, {density=1, friction=0, bounce=0  })

        –  {box = {halfWidth=20, halfHeight = 10, x=0, y=30}, isSensor = true})

   player.isFixedRotation = true

   --player.sensorOverlaps = 0

  local onCollision = function(self, event)

       if ( event.target and event.other.objType == “enemy1” ) then

               if ( event.phase == “ended” ) then

                          timer.performWithDelay(10, 

                                              function()

                                                         lives = lives - 1

                                                         print(lives)

                                                end, 1 )

                 end

               return true

         end

–[[

    – Confirm that the colliding elements are the foot sensor and a ground object

      if ( event.selfElement == 2 and event.other.objType == “ground” ) then

        – Foot sensor has entered (overlapped) a ground object

          if ( event.phase == “began” ) then

                 self.sensorOverlaps = self.sensorOverlaps + 1

        – Foot sensor has exited a ground object

          elseif ( event.phase == “ended” ) then

                self.sensorOverlaps = self.sensorOverlaps - 1

          end

         return true

      end–]]

  end

  --associate colllision handler function with character

   player.collision = onCollision

   player:addEventListener(“collision”, player)

–==========================================

I guess I just have to figure out another way of detecting if the player is on the ground. Any suggestion will be appreciated…

Thanks 

Uche.

Hi Uche,

You can still use this method (I assume you used this tutorial). Just in the other collision handling functions, like collisions with enemies, you need to ignore the “foot sensor” collision entirely. As you can see in the tutorial, the main player body element has an index of 1, and the foot sensor is 2. So, just use an if-then condition to honor only element #1 when the player collides with enemies, power-ups, and other things.

Hope this helps,

Brent

add return true to your onCollision if you have handled the event

I tried that same result…sometimes it even fired 4 times.

local function onCollision( self, event )

    if ( event.phase == “began” ) then

        if ( event.target and event.other.objType == “enemy1” ) then

            timer.performWithDelay(10, 

                function()

                    lives = lives - 1

                    print(lives)

                end, 1)

   end

    end

return true

end

–associate colllision handler function with character

player.collision = onCollision

player:addEventListener(“collision”, player)

Admin note: This post seems to have gotten duplicated several times. I’ve removed the excess ones. 

Rob

Hi @uche,

Can you show the code you’re using for “physics.addBody()” on your “player” object AND on objects it collides with when this issue occurs? I might know what the cause is, but I’ll need to see that code.

Thanks,

Brent

Hello @Brent,

I think I may have discovered what caused the collision to keep firing twice or more…Thanks for pointing out the “physics.addBody()” side of the code. In my player module I added the physics body with a sensor to detect ground collision but on commenting that part of the code; I get the result i want, the event fires once.   In the enemy module i just added the physics body without any sensor.

–=========

—player.lua

–==============

    local player = display.newCircle( 100, 100, 30 )

    player:setFillColor(1,0,0)

    player.x = 400

   physics.addBody( player, “dynamic”, {density=1, friction=0, bounce=0  })

        –  {box = {halfWidth=20, halfHeight = 10, x=0, y=30}, isSensor = true})

   player.isFixedRotation = true

   --player.sensorOverlaps = 0

  local onCollision = function(self, event)

       if ( event.target and event.other.objType == “enemy1” ) then

               if ( event.phase == “ended” ) then

                          timer.performWithDelay(10, 

                                              function()

                                                         lives = lives - 1

                                                         print(lives)

                                                end, 1 )

                 end

               return true

         end

–[[

    – Confirm that the colliding elements are the foot sensor and a ground object

      if ( event.selfElement == 2 and event.other.objType == “ground” ) then

        – Foot sensor has entered (overlapped) a ground object

          if ( event.phase == “began” ) then

                 self.sensorOverlaps = self.sensorOverlaps + 1

        – Foot sensor has exited a ground object

          elseif ( event.phase == “ended” ) then

                self.sensorOverlaps = self.sensorOverlaps - 1

          end

         return true

      end–]]

  end

  --associate colllision handler function with character

   player.collision = onCollision

   player:addEventListener(“collision”, player)

–==========================================

I guess I just have to figure out another way of detecting if the player is on the ground. Any suggestion will be appreciated…

Thanks 

Uche.

Hi Uche,

You can still use this method (I assume you used this tutorial). Just in the other collision handling functions, like collisions with enemies, you need to ignore the “foot sensor” collision entirely. As you can see in the tutorial, the main player body element has an index of 1, and the foot sensor is 2. So, just use an if-then condition to honor only element #1 when the player collides with enemies, power-ups, and other things.

Hope this helps,

Brent