Calling composer.gotoScene removes DisplayObjects but not bodies.

I have a main and two scenes. I can’t understand why composer doesn’t automatically remove the bodies behavior added with physics.addBody. According to http://forums.coronalabs.com/topic/37792-physics-bodies-still-remain-upon-switching-scenes/ physics body should be removed along with the display objects. In addition to the above link, I believe also the guy that posted http://forums.coronalabs.com/topic/21807-physics-body-goes-crazy-when-changing-scenes/ struggled with the same issue, but I’m guessing that he never turned on debug/hybrid draw mode and never realized that the bodies were going crazy because probably they were colliding with other invisibile objects from the previous scene. Here is my code.

main.lua

local composer = require("composer") composer.gotoScene("scene1")

scene1.lua

local composer = require("composer") local s = composer.newScene() function s:create(event)     local group = self.view          local physics = require("physics")     physics.start()     physics.setGravity(0, 1)     physics.setDrawMode("hybrid")          local t = display.newText(group, "Scene 1", display.contentWidth / 2, 20, native.systemFont, 16)          local widget = require("widget")     local button = widget.newButton     {         label = "Go to scene 2",         onEvent = function (event)             if event.phase == "ended" then                 composer.gotoScene("scene2")             end         end     }     button.x = display.contentWidth / 2     button.y = display.contentHeight / 2 - 100     group:insert(button)          local body = display.newRect(group, 0, 0, 60, 30)     body.x = display.contentWidth / 2     body.y = display.contentHeight / 2     physics.addBody(body, "dynamic") end s:addEventListener("create", s) return s

scene2.lua

local composer = require("composer") local s = composer.newScene() function s:create(event)     local group = self.view          local t = display.newText(group, "Scene 2", display.contentWidth / 2, 20, native.systemFont, 16) end s:addEventListener("create", s) return s

Among the things that fix the problem, are calling one of these functions right before gotoScene:

  • group[3]:removeSelf()
  • physics.removeBody(group[3])
  • physics.stop()

Interestingly, the following call does’t fix the issue:

  • group:removeSelf()

Is there an official guide/tutorial about using physics and composer together?

Changing scenes doesn’t automatically remove things, it just transitions them off screen.  Part of Composer’s feature set is that it caches those objects in case you bring the scene back on the screen.  Since the objects still exist, but are hidden, their physics bodies are still active.

Rbo

Thank you for your reply. So basically the composer makes the group invisible (akin to what a user could do by setting isVisible=false or alpha=0 or something like that) and doesn’t necessarily remove it.

I have one more question; I’m pretty sure that this is not a good practice, but why (as mentioned in the original post) the following code fails in removing the scene 1 group (i.e. hybrid mode shows that the display object are still there):

                group:removeSelf()                 composer.gotoScene("scene2")

while the following code succeeds?

                composer.gotoScene("scene2")                 group:removeSelf()

To question one, yes, the scene is either transitioned to alpha 0 (Fade, CrossFade) or it’s moved off screen (most of the other transitions).  Everything still exists.

For the 2nd question, if you remove the display group you are in effect removing the scene.  The second one, you go to a new scene then kill the old one.  That makes sense.   In the first example you’re in effect trying to remove the scene while it’s still on the screne.

Just as an aside, if “group” is the scene’s view you should not remove it.  Let the scene manager handle it.  Your best bet is to either pause or stop physics in the hide event.

Rob

Changing scenes doesn’t automatically remove things, it just transitions them off screen.  Part of Composer’s feature set is that it caches those objects in case you bring the scene back on the screen.  Since the objects still exist, but are hidden, their physics bodies are still active.

Rbo

Thank you for your reply. So basically the composer makes the group invisible (akin to what a user could do by setting isVisible=false or alpha=0 or something like that) and doesn’t necessarily remove it.

I have one more question; I’m pretty sure that this is not a good practice, but why (as mentioned in the original post) the following code fails in removing the scene 1 group (i.e. hybrid mode shows that the display object are still there):

                group:removeSelf()                 composer.gotoScene("scene2")

while the following code succeeds?

                composer.gotoScene("scene2")                 group:removeSelf()

To question one, yes, the scene is either transitioned to alpha 0 (Fade, CrossFade) or it’s moved off screen (most of the other transitions).  Everything still exists.

For the 2nd question, if you remove the display group you are in effect removing the scene.  The second one, you go to a new scene then kill the old one.  That makes sense.   In the first example you’re in effect trying to remove the scene while it’s still on the screne.

Just as an aside, if “group” is the scene’s view you should not remove it.  Let the scene manager handle it.  Your best bet is to either pause or stop physics in the hide event.

Rob