Pausing the PhysicsWorld?

Hi, I’m trying to implement a pause function for my app, so that at certain times all the sprites and physicsbodies stop moving and I can display some other stuff. Does anyone know a good way to do this? pauseSchedulerAndActions() doesn’t stop the physicsBodies (and the associated sprites) from updating, and pausing using the director means that I can’t continue any UI animations in the scene.

Any ideas?

Thanks :smile:

hmm, good question.

Could you do something like:
sprite->unscheduleAllSelectors(); sprite->getPhysicsBody()->setVelocity(cocos2d::Vect(0,0)); sprite->getPhysicsBody()->setVelocityLimit(0);

Or I also see a function: void setUpdateRate (int rate)

Perhaps using 0 may stop updating. I haven’t tried it.

if (!_paused)
{
_world->Step(dt, 8, 8);
}

@slackmoehrle, thanks very much, what you’ve said doesn’t quite work (setUpdateRate doesn’t seem to work, at least not with zero). However, the following does work for pausing the physicsWorld:

Director::getInstance()->getRunningScene()->getPhysicsWorld()->setSpeed(0);

Setting it to one again should resume.

@sillyatom, what you’re suggesting might work if I was manually updating the world, but it’s handled by the physicsWorld so I can’t change the update function (as far as I know).

1 Like

Thanks for telling me about this.

Thanks for posting this. I had troubles pausing my game this worked for me. Took a couple hours to find your post, but hey what can you say.

I have a situation where I need to pause the physics world in order to stop all things in it from moving around for awhile… Then I need to have a few of those things to start running again, they won’t collide with any other object unless it’s “alive” too. I was thinking it would be easiest to use another PhysicsWorld for this but it seems that cocos2d-x only supports one PhysicsWorld per scene? Is there any other way to pause just one object? FYI I pause the world like this:

this->getScene()->getPhysicsWorld()->setSpeed(0);

I used this as previously suggested, in update():

node->getPhysicsBody()->setVelocity(Vec2(0,0));

I used these too but they didn’t really seem to make any difference:

node->getPhysicsBody()->resetForces();
node->getPhysicsBody()->setResting(true);

I just wanted to chime in as this answer appears for people that are also using coocs creator.

I didnt find anywhere else so here is how you do it in cocos creator (JS).

        cc.director.getPhysicsManager().enabled = true;

to pause, and

        cc.director.getPhysicsManager().enabled = false;

to unpause.

I had to read the actual code to find out – it literally stops the box2D steps, as suggested by @sillyatom

If you are making a menu, you may want to also pause all animations, all actions and schedulers for all nodes that are not on the pause menu:

Lets say your node that contains the game itself is called gameplayArea. To stop all animations:

this.gameplayArea.getComponentsInChildren(cc.Animation).forEach(function(anim){ anim.pause() });

To stop all actions and schedulers:

      cc.director.getActionManager().pauseTarget(node);
      cc.director.getScheduler().pauseTarget(node);

But this time recursively, to gameplayArea and all itschildren nodes.

And use the respective resume methods to go continue everything.

///
Please note that updates will still be called, and the game time will still tick, so you can implement your menus freely with animations and all, and even read input from HTML5 joypads, for example