Collision Function Only Runs Once

The game I’m working on uses a function to set everything up, wherein this line is run:

Runtime:addEventListener( "collision", onCollision )

When the collision function is run, I call my gameOver function. Here is the code for my collision:

function onCollision( event )         if(event.phase == "began") then             gameOver()         end     end

Which leads here:

    local function gameOver()         transition.cancel()         timer.cancel( tmr\_progress )         display.remove(playerCircle)         Runtime:removeEventListener("touch", movePlayer)         setUpScene()     end

And thus, the cycle restarts. The collision works just fine the first time, however, it won’t recognize it the second time. The second run-through ends up crashing at some point. My theory is that the game never realizes that the collision is over because I used to get an error saying that I cannot add physics body (which happens in my setup function) while a collision is still happening. I’ve since changed it so that the bodies will only be added if they don’t already have one. I invite you to criticize my code so that I may learn. Please.

Hi @r_burmeister,

The most important part of the code we’d need to see is how/when you’re adding physics bodies. As the warning message indicated, there are some physics-based functions which can’t be performed in the same “time step” as a collision, so you need to delay it by one frame. These are documented in this guide about halfway down:

https://docs.coronalabs.com/guide/physics/collisionDetection/index.html

Take care,

Brent

I am having a similar issue.

When I investigated, I found that it has changed between the previous public release (2015.2731) and 2015.2741.

The issue seems to be adding and removing collision event listener.

In my project, as you do, I add collision listener at the beginning of each screen initialisation. Then I remove it just before changing the screen. It was working perfectly until 2015.2741.

Now I realised that, I am calling remove event listener unnecessarily just for one time, and this causes the issue.

Therefore, never call remove collision event if it is not added to Runtime already.

I hope this helps.

Hi @aragorn991402,

This sounds odd and I don’t know what would have changed between those builds in this regard.

Can you be more specific about how you’re handling these listeners? Are you using the Composer scene manager? If so, when do you add and remove the collision listeners?

Brent

Hi Brent,

Sorry for giving a little information, I will try to be more specific.

I am not using Composer Scene Manager, I have my own GameManager. I have different screens, each one is an individual .lua file. And a GameManager.lua file that manages those screens. Each screen has ScreenIn and ScreenOut functions.

Screen.screenIn () --load display objects, add event listeners Screen.screenOut () --remove display objects, remove event listeners GameManager.changeScreen ( prevScreen, nextScreen ) --prevScreen.screenOut() nextScreen.screenIn()

To speak about collision specifically:

It was before :

Screen.screenIn = function () if there are physical objects in the screen then Runtime:addEventListener("collision", onCollision) end end Screen.screenOut = function () -- without checking whether there are any physical objects in the screen Runtime:removeEventListener("collision", onCollision) end

It was working flawlessly with 2015.2731, but not working with 2015.2741. What I found is, there is a screen that does not have any physical objects in it. Here is the scenario : 

Screen1 (with physical objects in it)

Screen2 (with no physical objects in it)

Screen1.screenIn() --collision event is added GameManager.changeScreen(Screen1, Screen2) Screen1.screenOut() --collision event is removed Screen2.screenIn() -- collision event is not added because Screen2 has no physical objects in it GameManager.changeScreen(Screen2, Screen1) Screen2.screenOut() -- collision event is removed although it has not added before Screen1.screenIn() -- collision event is added with 2015.2731, but not added with 2015.2741

When I found this, I modified my functions as follows :

Screen.screenIn = function () if there are physical objects in the screen then Runtime:addEventListener("collision", onCollision) end end Screen.screenOut = function () if there are physical objects in the screen then Runtime:removeEventListener("collision", onCollision) end end

Therefore it became :

Screen1 (with physical objects in it)

Screen2 (with no physical objects in it)

Screen1.screenIn() --collision event is added GameManager.changeScreen(Screen1, Screen2) Screen1.screenOut() --collision event is removed Screen2.screenIn() -- collision event is not added because Screen2 has no physical objects in it GameManager.changeScreen(Screen2, Screen1) Screen2.screenOut() -- collision event is not removed because Screen2 has no physical objects in it (It wasn't added already) Screen1.screenIn() -- collision event is added with 2015.2731 and 2015.2741 flawlessly

As a result, this is how I solved the issue.

I hope it is more clear now and it helps you.

Please paste your code in by clicking on the blue <> button in the edit bar and pasting the text in the window that pops up please.

Thanks

Rob

Hi @r_burmeister,

The most important part of the code we’d need to see is how/when you’re adding physics bodies. As the warning message indicated, there are some physics-based functions which can’t be performed in the same “time step” as a collision, so you need to delay it by one frame. These are documented in this guide about halfway down:

https://docs.coronalabs.com/guide/physics/collisionDetection/index.html

Take care,

Brent

I am having a similar issue.

When I investigated, I found that it has changed between the previous public release (2015.2731) and 2015.2741.

The issue seems to be adding and removing collision event listener.

In my project, as you do, I add collision listener at the beginning of each screen initialisation. Then I remove it just before changing the screen. It was working perfectly until 2015.2741.

Now I realised that, I am calling remove event listener unnecessarily just for one time, and this causes the issue.

Therefore, never call remove collision event if it is not added to Runtime already.

I hope this helps.

Hi @aragorn991402,

This sounds odd and I don’t know what would have changed between those builds in this regard.

Can you be more specific about how you’re handling these listeners? Are you using the Composer scene manager? If so, when do you add and remove the collision listeners?

Brent

Hi Brent,

Sorry for giving a little information, I will try to be more specific.

I am not using Composer Scene Manager, I have my own GameManager. I have different screens, each one is an individual .lua file. And a GameManager.lua file that manages those screens. Each screen has ScreenIn and ScreenOut functions.

Screen.screenIn () --load display objects, add event listeners Screen.screenOut () --remove display objects, remove event listeners GameManager.changeScreen ( prevScreen, nextScreen ) --prevScreen.screenOut() nextScreen.screenIn()

To speak about collision specifically:

It was before :

Screen.screenIn = function () if there are physical objects in the screen then Runtime:addEventListener("collision", onCollision) end end Screen.screenOut = function () -- without checking whether there are any physical objects in the screen Runtime:removeEventListener("collision", onCollision) end

It was working flawlessly with 2015.2731, but not working with 2015.2741. What I found is, there is a screen that does not have any physical objects in it. Here is the scenario : 

Screen1 (with physical objects in it)

Screen2 (with no physical objects in it)

Screen1.screenIn() --collision event is added GameManager.changeScreen(Screen1, Screen2) Screen1.screenOut() --collision event is removed Screen2.screenIn() -- collision event is not added because Screen2 has no physical objects in it GameManager.changeScreen(Screen2, Screen1) Screen2.screenOut() -- collision event is removed although it has not added before Screen1.screenIn() -- collision event is added with 2015.2731, but not added with 2015.2741

When I found this, I modified my functions as follows :

Screen.screenIn = function () if there are physical objects in the screen then Runtime:addEventListener("collision", onCollision) end end Screen.screenOut = function () if there are physical objects in the screen then Runtime:removeEventListener("collision", onCollision) end end

Therefore it became :

Screen1 (with physical objects in it)

Screen2 (with no physical objects in it)

Screen1.screenIn() --collision event is added GameManager.changeScreen(Screen1, Screen2) Screen1.screenOut() --collision event is removed Screen2.screenIn() -- collision event is not added because Screen2 has no physical objects in it GameManager.changeScreen(Screen2, Screen1) Screen2.screenOut() -- collision event is not removed because Screen2 has no physical objects in it (It wasn't added already) Screen1.screenIn() -- collision event is added with 2015.2731 and 2015.2741 flawlessly

As a result, this is how I solved the issue.

I hope it is more clear now and it helps you.

Please paste your code in by clicking on the blue <> button in the edit bar and pasting the text in the window that pops up please.

Thanks

Rob