Pausing a Box2D simulation
There is a Box2D feature easy to implement and capable to add interesting gameplay that I haven’t found explained anywhere: the pause.
I want to stop a Box2D simulation when I click the mouse, and to play it again with another click.
The core function of this feature is Step.
Normally is called this way:
b2World.Step(timestep, iterations)
where timestep is the amount of time to simulate (normally 1/30 or 1/60 seconds) and iterations the number of iterations to be used by the constraint solver.
So, playing with timestep is the key to success. In this script, copied/pasted from A smart way to manage sleeping objects with Box2D I am going to stop the simulation with a mouse click, and let it play again with another mouse click.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | package { import flash.display.Sprite; import flash.events.Event; import flash.utils.Timer; import flash.events.TimerEvent; import flash.events.MouseEvent; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; public class demo extends Sprite { var the_world:b2World; var time_count:Timer=new Timer(1500); var timestep:Number=1/30; public function demo() { var environment:b2AABB = new b2AABB(); environment.lowerBound.Set(-100.0, -100.0); environment.upperBound.Set(100.0, 100.0); var gravity:b2Vec2=new b2Vec2(0.0,10.0); the_world=new b2World(environment,gravity,true); var final_body:b2Body; var the_body:b2BodyDef; var the_box:b2PolygonDef; the_body = new b2BodyDef(); the_body.position.Set(8.5, 14); the_box = new b2PolygonDef(); the_box.SetAsBox(8.5, 0.5); the_box.friction=0.3; the_box.density=0; final_body=the_world.CreateBody(the_body); final_body.CreateShape(the_box); final_body.SetMassFromShapes(); addEventListener(Event.ENTER_FRAME, on_enter_frame); stage.addEventListener(MouseEvent.CLICK,on_click); time_count.addEventListener(TimerEvent.TIMER, on_time); time_count.start(); } public function on_click(e:MouseEvent) { if (timestep) { timestep=0; } else { timestep=1/30; } } public function on_time(e:Event) { if (timestep) { var final_body:b2Body; var the_body:b2BodyDef; var the_box:b2PolygonDef; var box_width=Math.random()+0.1; var box_height=Math.random()+0.1; the_body = new b2BodyDef(); the_body.position.Set(Math.random()*10+2, 0); the_body.userData = new cubeface(); the_body.userData.width=box_width*60; the_body.userData.height=box_height*60; the_box = new b2PolygonDef(); the_box.SetAsBox(box_width,box_height); the_box.friction=0.3; the_box.density=1; final_body=the_world.CreateBody(the_body); final_body.CreateShape(the_box); final_body.SetMassFromShapes(); addChild(the_body.userData); } } public function on_enter_frame(e:Event) { the_world.Step(timestep, 10); for (var bb:b2Body = the_world.m_bodyList; bb; bb = bb.m_next) { if (bb.m_userData is Sprite) { bb.m_userData.x=bb.GetPosition().x*30; bb.m_userData.y=bb.GetPosition().y*30; bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI); if (bb.IsSleeping()) { bb.m_userData.gotoAndStop(2); } else { bb.m_userData.gotoAndStop(1); } } } } } } |
Let’s see the interesting lines:
Line 69: Step function is performed with a timestep variable declared at line 15 and set at 1/30
Line 35: Adding a mouse listener waiting for clicks and calling on_click function
Line 39-45: on_click function switches timestep variable between 1/30 and 0. This way we can stop and resume the simulation. The other check for timestep value at line 47 is just to avoid a lot of new boxes to be generated while the simulation is paused
And this is the result:
Click mouse button to pause/play the simulation, and notice how unsleeping objects do not sleep while paused.
No need to download anything, just copy/paste this code in the example you can find at A smart way to manage sleeping objects with Box2D.
They can be easily customized to meet the unique requirements of your project.















(7 votes, average: 4.71 out of 5)









This post has 7 comments
Danhezee
That is the key to creating a cool matrix effect in box2d
Emanuele Feronato
nice idea, a bullet time… (idea for next tutorial…)
ShahSoft
In my game “Word Cannon” I simply don’t call World Step while paused. I never thought of Sleeping bodies but there seems 2 b no problem if I pause for a While.
Link: http://www.king.com/games/sponsored-games/word-cannon/
rishabh
Emanuele Feronato
i have created something like that
but I used a variable called paused and if it is false,I call world.step(1/30,10) note:i usually put all stuff like framerate and ratio into a class called physivals and for the timestep, i sometimes use a seprate class called timeMaster which has 3 functions
1. getTimeStep() < for the timestep
2.slowDown() < slows down the timestep
3.backToNormal() < returns timestep to normal
for the matrix effect
how about a bullet which has 2 shapes the real bullets shape and a sensor around 50×50 px big
when the sensor collides with an object you
call slowDown() and when it is removed you call backTNomal()
mind if i send you a demo of that soon?
rishabh
i finished the matrix thing
in 2 ways
1. check the location of the sprite which represents it and then slows down time when it is in range
2.the sensor way i explained before
Way of an Idea Box2D prototype – Step 2 : Emanuele Feronato - italian geek and PROgrammer
[...] time to apply the concepts seen at Pausing a Box2D simulation with Way of an Idea Box2D prototype to create a paused Box2D simulation that will start only when [...]
Emanuele Feronato
nice! if you want to share it with blog readers, write me at info[at]emanueleferonato.com