[RESOLVED] Physics.pause() displaces dynamic sensor bodies after pyhsics.start()

Hello,

I just came across a problem in my game. I am using the physics engine to run nearly all game logic, so I wanted to implement a pause function via physics.pause(). The game is paused correctly at the beginning, but after resuming the physics objects are being displaced to the location where they are expected to be if not paused. I narrowed down the problem to something physics related as I gone through my code and tested many eventual error sources in my pause calling.

This is how I create my physics bodies. I add joints etc, but disabling them did not change anything.

physics.addBody(anti\_particle, "dynamic", {radius = 64-16,friction=0.0, density=1.0, bounce= 0.0,filter={categoryBits=8,maskBits=5}}) -- disable physical response anti\_particle.isSensor = true -- add linear movement anti\_particle:setLinearVelocity( 0, speed)true -- add rotation anti\_particle.angularVelocity = 30

I appreciate every tiny clue, so I can look further into the issue myself. But atm I don’t know where to look anymore.

Thank you Dominik

Hi @Dominik,

We would need to see more code to help solve this. For example, where you pause the physics engine, how you “disable” the joints (joints can’t really be disabled, in fact), and other info. Please try to post a little more code, but not necessarily the entire Storyboard/Composer scene (unless it’s absolutely relevant to the pausing functionality).

Thanks,

Brent

Of course. These are all lua files which are connected to the problem. In game_scene I’m calling game_manager function to start/stop the game. Which calls the physics.start/stop. I didn’t mean disabling joints. Sry, I meant to say I just didn’t create them to check if there anything wrong with the joints.

My console output says (if i check the game_manager function are called):

"game_manager.start()

game_manager.pause()

game_manager.start()"

game_scene.lua (managing scene related stuff) [lua]

function scene:show(event) local sceneGroup = self.view if(event.phase == "will") then elseif(event.phase == "did") then game\_manager.start() end end function scene.resume() timer.performWithDelay( 1, function() game\_manager.start() end) end function scene.finish(score, combo, life, \_resume) timer.performWithDelay( 1, function() game\_manager.pause() composer.showOverlay( "scripts.scenes.game\_menu\_overlay", { effect = "slideDown", time = 500, isModal = true, params={resume = \_resume}} ) end ) end

[/lua]

game_manager.lua (adding physics world, ui etc):[lua]

 local function setupPhysics() physics.start(false) -- initiate --sleeping bodies disabled physics.setGravity( 0, 0 ) -- no gravity physics.setDrawMode( "normal" ) -- for debug hybrid else normal physics.setContinuous( true ) -- no tunneling physics.setPositionIterations( 8 ) -- default is 8 physics.setReportCollisionsInContentCoordinates( true ) -- cordiantes in pixels physics.setTimeStep(0) -- time based end local function setup(pipe\_number) setupHelpers() setupPhysics() -- ... -- setupUI() physics.pause() end function manager.start() physics.start() enemy\_manager.start() end function manager.pause() enemy\_manager.pause() physics.pause() end

[/lua]

anti_particle.lua(physics part):[lua]

 physics.addBody(anti\_particle, "dynamic", {radius = 64-16,friction=0.0, density=1.0, bounce= 0.0, filter={categoryBits=8,maskBits=5}}) -- disable physical response anti\_particle.isSensor = true -- add rotation anti\_particle:setLinearVelocity( 0, speed) anti\_particle.angularVelocity = 30 --setup collision lsitener anti\_particle:addEventListener("collision", onCollision) --- shields setup shield\_manager = shield\_manager.create(anti\_particle, layer, speed) for i=1,#shields do shield\_manager:createShield(shields[i]) end

[/lua]

shield_manager.lua: ( just physics part)

physics.addBody(s, "dynamic", {radius = 64, friction=0.0, density=1.0, bounce = 0.0, filter={categoryBits=64,maskBits=0}}) s.isSensor = true s.angularVelocity = -30 -- create pivot joint local shield\_joint = physics.newJoint( "pivot", anti\_particle, s, anti\_particle.x, anti\_particle.y,s.x, s.y ) -- make motor to rotate shield shield\_joint.isMotorEnabled = true shield\_joint.motorSpeed = 100 shield\_joint.maxTorque = 10000 s:setLinearVelocity( 0, speed )

Thanks Dominik

Hi Dominik,

Do you mean that the objects move slightly when you pause/resume the game? Is there a specific reason why you’re calling the pause and resume functions after a 1 ms timer? This may be resulting in another frame (app time step) to occur, and the physics bodies will make one more iteration as well.

Best regards,

Brent

I thought you have to do it with a delay so there isn’t any collision ongoing. The objects doesn’t just move 1 frame. After resuming the physics the object are teleported to the position where they would be if the game hasn’t ever been paused. So the longer it was paused the more/farther the objects would move/teleport.

Greetings Dominik

Hi Dominik,

I think I know the issue. You’ve set the physics to be time-based, not frame-based. So, when you resume, it’s acting like you never paused it. Remove the “physics.setTimeStep()” line and it should work (time-based is not commonly used, except in very specific cases).

Brent

Thank you very much! That did the trick.

Hi @Dominik,

We would need to see more code to help solve this. For example, where you pause the physics engine, how you “disable” the joints (joints can’t really be disabled, in fact), and other info. Please try to post a little more code, but not necessarily the entire Storyboard/Composer scene (unless it’s absolutely relevant to the pausing functionality).

Thanks,

Brent

Of course. These are all lua files which are connected to the problem. In game_scene I’m calling game_manager function to start/stop the game. Which calls the physics.start/stop. I didn’t mean disabling joints. Sry, I meant to say I just didn’t create them to check if there anything wrong with the joints.

My console output says (if i check the game_manager function are called):

"game_manager.start()

game_manager.pause()

game_manager.start()"

game_scene.lua (managing scene related stuff) [lua]

function scene:show(event) local sceneGroup = self.view if(event.phase == "will") then elseif(event.phase == "did") then game\_manager.start() end end function scene.resume() timer.performWithDelay( 1, function() game\_manager.start() end) end function scene.finish(score, combo, life, \_resume) timer.performWithDelay( 1, function() game\_manager.pause() composer.showOverlay( "scripts.scenes.game\_menu\_overlay", { effect = "slideDown", time = 500, isModal = true, params={resume = \_resume}} ) end ) end

[/lua]

game_manager.lua (adding physics world, ui etc):[lua]

 local function setupPhysics() physics.start(false) -- initiate --sleeping bodies disabled physics.setGravity( 0, 0 ) -- no gravity physics.setDrawMode( "normal" ) -- for debug hybrid else normal physics.setContinuous( true ) -- no tunneling physics.setPositionIterations( 8 ) -- default is 8 physics.setReportCollisionsInContentCoordinates( true ) -- cordiantes in pixels physics.setTimeStep(0) -- time based end local function setup(pipe\_number) setupHelpers() setupPhysics() -- ... -- setupUI() physics.pause() end function manager.start() physics.start() enemy\_manager.start() end function manager.pause() enemy\_manager.pause() physics.pause() end

[/lua]

anti_particle.lua(physics part):[lua]

 physics.addBody(anti\_particle, "dynamic", {radius = 64-16,friction=0.0, density=1.0, bounce= 0.0, filter={categoryBits=8,maskBits=5}}) -- disable physical response anti\_particle.isSensor = true -- add rotation anti\_particle:setLinearVelocity( 0, speed) anti\_particle.angularVelocity = 30 --setup collision lsitener anti\_particle:addEventListener("collision", onCollision) --- shields setup shield\_manager = shield\_manager.create(anti\_particle, layer, speed) for i=1,#shields do shield\_manager:createShield(shields[i]) end

[/lua]

shield_manager.lua: ( just physics part)

physics.addBody(s, "dynamic", {radius = 64, friction=0.0, density=1.0, bounce = 0.0, filter={categoryBits=64,maskBits=0}}) s.isSensor = true s.angularVelocity = -30 -- create pivot joint local shield\_joint = physics.newJoint( "pivot", anti\_particle, s, anti\_particle.x, anti\_particle.y,s.x, s.y ) -- make motor to rotate shield shield\_joint.isMotorEnabled = true shield\_joint.motorSpeed = 100 shield\_joint.maxTorque = 10000 s:setLinearVelocity( 0, speed )

Thanks Dominik

Hi Dominik,

Do you mean that the objects move slightly when you pause/resume the game? Is there a specific reason why you’re calling the pause and resume functions after a 1 ms timer? This may be resulting in another frame (app time step) to occur, and the physics bodies will make one more iteration as well.

Best regards,

Brent

I thought you have to do it with a delay so there isn’t any collision ongoing. The objects doesn’t just move 1 frame. After resuming the physics the object are teleported to the position where they would be if the game hasn’t ever been paused. So the longer it was paused the more/farther the objects would move/teleport.

Greetings Dominik

Hi Dominik,

I think I know the issue. You’ve set the physics to be time-based, not frame-based. So, when you resume, it’s acting like you never paused it. Remove the “physics.setTimeStep()” line and it should work (time-based is not commonly used, except in very specific cases).

Brent

Thank you very much! That did the trick.