physic.pause / resume problem with composer.showOverlay

I have a problem about a physic.pause/resume with composer.showOverlay:

here the sit:

I am in a scene of name ‘parent’.

On on double tap event I show with composer.showOverlay the scene “pause_resume” and I froze all the physic game.
Then I resume game, or quit going to the “menu” scene.

from main the composer scene are:
menu-> parent–> overlay pause_resume

all works fine the first time: the physics stops and restart when desired.

But when I go back from scene “menu” to “parent” scene and call again the scene “pause_resume” the physics.pause() won’t works.

I made a very simple demo that explain the problem that you can downolad.

Physics.zip (25.3 KB)

please someone can have a look ?

If you want a quick view here the code:
main.lua–start-------------------------------------------------------------------------
require(“mobdebug”).start()

local composer = require( "composer" )

composer.gotoScene ( "menu" )
main.lua--end-------------------------------------------------------------------------
menu.lua--start-------------------------------------------------------------------------
local composer = require( "composer" )
local widget = require( "widget" )

local scene = composer.newScene()

-- -----------------------------------------------------------------------------------
-- Code outside of the scene event functions below will only be executed ONCE unless
-- the scene is removed entirely (not recycled) via "composer.removeScene()"
-- -----------------------------------------------------------------------------------
local function handleButtonEvent( event )
    if ( "ended" == event.phase ) then
      --print( "Button was pressed and released" )
      if event.target.id == "game" then
        composer.gotoScene ( "parent" )
      end
    end
end

-- -----------------------------------------------------------------------------------
-- Scene event functions
-- -----------------------------------------------------------------------------------

-- create()
function scene:create( event )

	local sceneGroup = self.view
	-- Code here runs when the scene is first created but has not yet appeared on screen
  local interline = display.contentHeight/8
  local tabBtn = display.contentWidth/4
  local tabBtn2 = display.contentWidth/4*3
  
  local buttonGame = widget.newButton(
    {
        id = "game",
        label = "GAME",
        x = display.contentWidth/4,
        y = display.contentCenterY,
        width = display.contentWidth/2,
        height = display.contentHeight/6,
        fontSize = display.contentHeight/12,
        --defaultFile = "Immagini/buttonDefault.png",
        --overFile = "Immagini/buttonOver.png",
        onEvent = handleButtonEvent
    }
  )
  sceneGroup:insert(buttonGame)

end


-- show()
function scene:show( event )

	local sceneGroup = self.view
	local phase = event.phase

	if ( phase == "will" ) then
		-- Code here runs when the scene is still off screen (but is about to come on screen)

	elseif ( phase == "did" ) then
		-- Code here runs when the scene is entirely on screen

	end
end


-- hide()
function scene:hide( event )

	local sceneGroup = self.view
	local phase = event.phase

	if ( phase == "will" ) then
		-- Code here runs when the scene is on screen (but is about to go off screen)
    display:remove(sceneGroup)

	elseif ( phase == "did" ) then
		-- Code here runs immediately after the scene goes entirely off screen
    composer.removeScene("menu")
	end
end


-- destroy()
function scene:destroy( event )

	local sceneGroup = self.view
	-- Code here runs prior to the removal of scene's view

end


-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------

return scene
menu.lua--end-------------------------------------------------------------------------
parent.lua--start---------------------------------------------------------------------
local physics = require( "physics" )
local composer = require( "composer" )

local scene = composer.newScene()

function scene:resumeGame(wantExit)
  if wantExit == true then
    --exit game
      composer.gotoScene( "menu" )
  else
    --resume game
    physics.start()
    transition:resume()
  end
end

-- create()
function scene:create( event )

	local sceneGroup = self.view
	-- Code here runs when the scene is first created but has not yet appeared on screen
  
  physics.start(0,0)
  physics.setGravity(0,1)
  physics.setDrawMode( "hybrid" )

  local bigRect = display.newLine( sceneGroup, 0, 480, 320, 480)
  physics.addBody(bigRect, "static")
  
  local ball = display.newCircle( sceneGroup, 50, 0, 10)
  physics.addBody(ball, "dynamic", {bounce=1, radius=10})  
  ball:setLinearVelocity(0, 20)

end


-- show()
function scene:show( event )

	local sceneGroup = self.view
	local phase = event.phase

	if ( phase == "will" ) then
		-- Code here runs when the scene is still off screen (but is about to come on screen)

	elseif ( phase == "did" ) then
		-- Code here runs when the scene is entirely on screen

	end
end


-- hide()
function scene:hide( event )

	local sceneGroup = self.view
	local phase = event.phase

	if ( phase == "will" ) then
		-- Code here runs when the scene is on screen (but is about to go off screen)
    Runtime:removeEventListener(tapListener)
    display:remove(sceneGroup)

    transition:pause()
    physics.pause()
    
    local result = physics.stop()
    if result == false then
      print("Wait a moment...")
      timer.performWithDelay( 2000, function() physics.stop() end)
    end

	elseif ( phase == "did" ) then
		-- Code here runs immediately after the scene goes entirely off screen
    composer.removeScene("parent")
	end
end

-- destroy()
function scene:destroy( event )

	local sceneGroup = self.view
	-- Code here runs prior to the removal of scene's view

end

function tapListener ( event )
  if ( event.numTaps == 2 ) then
    physics.pause()

    composer.showOverlay( "pause_resume", {isModal=true} )
  end
end

-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------
Runtime:addEventListener( "tap", tapListener )

return scene
parent.lua--end------------------------------------------------------------------------
pause_resume.lua--start----------------------------------------------------------------
--V 1.0 by RRE del 9/5/20. Se vuoi uscire riporta sulla principale wantExit = true

local composer = require( "composer" )
local widget = require( "widget" )

local scene = composer.newScene()

local wantExit = false

-- -----------------------------------------------------------------------------------
-- Code outside of the scene event functions below will only be executed ONCE unless
-- the scene is removed entirely (not recycled) via "composer.removeScene()"
-- -----------------------------------------------------------------------------------
local function handleButtonEvent( event )
    if ( "ended" == event.phase ) then
      --print( "Button was pressed and released" )
      if event.target.id == "resume" then
        wantExit = false
      elseif event.target.id == "quit" then
        wantExit = true
      end
      composer.hideOverlay( "fade" )
    end
end
-- -----------------------------------------------------------------------------------
-- Scene event functions
-- -----------------------------------------------------------------------------------

-- create()
function scene:create( event )

	local sceneGroup = self.view
	-- Code here runs when the scene is first created but has not yet appeared on screen
  local interline = display.contentHeight/8
  local tabBtn = display.contentWidth/4
  local tabBtn2 = display.contentWidth/4*3
  
  btnGroup = display.newGroup()

  local buttonResume = widget.newButton(
    {
        id = "resume",
        label = "RESUME",
        x = display.contentWidth/4,
        y = display.contentCenterY,
        width = display.contentWidth/2,
        height = display.contentHeight/6,
        fontSize = display.contentHeight/12,
        --defaultFile = "Immagini/buttonDefault.png",
        --overFile = "Immagini/buttonOver.png",
        onEvent = handleButtonEvent
    }
  )
  btnGroup:insert(buttonResume)

  local buttonQuit = widget.newButton(
    {
        id = "quit",
        label = "QUIT",
        x = display.contentWidth/4*3,
        y = display.contentCenterY,
        width = display.contentWidth/2,
        height = display.contentHeight/6,
        fontSize = display.contentHeight/12,
        --defaultFile = "Immagini/buttonDefault.png",
        --overFile = "Immagini/buttonOver.png",
        onEvent = handleButtonEvent
    }
  )
  btnGroup:insert(buttonQuit)
  
  sceneGroup:insert(btnGroup)

end

-- show()
function scene:show( event )

	local sceneGroup = self.view
	local phase = event.phase

	if ( phase == "will" ) then
		-- Code here runs when the scene is still off screen (but is about to come on screen)

	elseif ( phase == "did" ) then
		-- Code here runs when the scene is entirely on screen

	end
end


-- hide()
function scene:hide( event )

	local sceneGroup = self.view
	local phase = event.phase
  local parent = event.parent  -- Reference to the parent scene object

	if ( phase == "will" ) then
		-- Code here runs when the scene is on screen (but is about to go off screen)
    parent:resumeGame(wantExit)
	elseif ( phase == "did" ) then
		-- Code here runs immediately after the scene goes entirely off screen

	end
end


-- destroy()
function scene:destroy( event )

	local sceneGroup = self.view
	-- Code here runs prior to the removal of scene's view

end

-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------

return scene
pause_resume.lua--end------------------------------------------------------------------

Thank you
Renato

Runtime:removeEventListener("tap", tapListener)

You should remove the listener like this. It solves the issue. Also suggest changing physics.start(0,0) to physics.start(). Both are in parent.lua file.

Thank you for suggestion!

I have removed the line

Runtime:removeEventListener(tapListener)

on scene:hide( event )
and changed on physics.start()

But stil not stop the physics on pause_resume scene.

The EventListener doesn’t have to remove quitting scene ?

Thank you
Renato

I’m sorry, I wasn’t clear enough. You should remove the listener like I wrote earlier. You should change your removeEventListener line to the one I suggested and it works. Replace the line in your code with this Runtime:removeEventListener("tap", tapListener) Mind the “tap” detail.

2 Likes

You are a great!

In fact, I wrote the function badly!

Thanks a lot, it works perfectly.
I am indebted to you :wink:

Renato