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.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (7 votes, average: 4.71 out of 5)
Loading ... Loading ...
Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 7 comments

  1. Danhezee

    on January 7, 2010 at 1:50 am

    That is the key to creating a cool matrix effect in box2d

  2. Emanuele Feronato

    on January 7, 2010 at 2:26 am

    nice idea, a bullet time… (idea for next tutorial…)

  3. ShahSoft

    on January 7, 2010 at 9:55 am

    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/

  4. rishabh

    on January 7, 2010 at 10:00 am

    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?

  5. rishabh

    on January 7, 2010 at 5:14 pm

    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

  6. Way of an Idea Box2D prototype – Step 2 : Emanuele Feronato - italian geek and PROgrammer

    on January 7, 2010 at 5:17 pm

    [...] 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 [...]

  7. Emanuele Feronato

    on January 7, 2010 at 5:25 pm

    nice! if you want to share it with blog readers, write me at info[at]emanueleferonato.com