News Apr 22: New blog post: Inverted pendulum control
Apr 7: On-screen logging class for Cocos2d-x
Mar 22: Downhill Supreme 2 released for iOS and Android
Jan 2: YouTube video: Making soft-body wheels in RUBE
2013
Oct 6: Check out Supplyfront RTS, my 7dRTS entry continued.
Sep 26: R.U.B.E v1.5 released. Customizable item labels, snap-to-grid, export filtering, full-text help search.
Sep 18: Added RUBE sample loader for Cocos2d-X.
Sep 16: Updated RUBE sample loader for Cocos2d v2.
Aug 12: RUBE loader for Nape by Zeh Fernando
Aug 7: Added RUBE sample loader for SFML.
Jul 30: Try my MiniLD 7dRTS entry.
Jul 24: Added physics-driven particles tutorial.
Jul 20: New blog post: rendering solid ground (as in Downhill Supreme)
Jul 18: R.U.B.E v1.4 released. Command-line interface for batch jobs, hotkeys for scripts, better script management.
May 22: Downhill Supreme is out now! (iOS)
Apr 2: R.U.B.E v1.3 released. Collision bitplane editing, Cocos2d-iphone loader, usability improvements.
Mar 11: R.U.B.E v1.2 released. Now supports weld, friction, motor joints and automatic image reloading.
Mar 10: RUBE loader for libGDX by Tim Scott
Jan 28: New blog post: a functional combustion engine!
Jan 22: New blog post: wind tunnel
Jan 20: Added explosions tutorial.
Jan 16: Added buoyancy tutorial.
Jan 16: AndEngine sample project to load RUBE scene by Bart Hirst
Jan 14: R.U.B.E v1.1 released, now supports custom properties.
Jan 1: All basic tutorials are now available in Chinese at ohcoder.com Huge thankyou to @OhCoder!
2012
Dec 23: Discussion forums have been set up
Dec 4: R.U.B.E v1.0 is ready !
Dec 2: YouTube video: Box2D pendulum clock
Nov 26: New blog post: rocket platform thingy
Nov 25: Video of R.U.B.E scenes in Chipmunk.
Nov 23: A sample project to load R.U.B.E scenes into Chipmunk physics! Details here.
Nov 14: An XCode sample project to load R.U.B.E scenes on iOS is now available. Details here.
Nov 11: A Java version of b2dJson is now available, based on JBox2D.
Nov 6: A Javascript version of b2dJson based on box2dweb is now available. Demo here!
Nov 2: The full specification of the JSON format used by b2dJson can be found here: b2dJson file structure
Oct 28: YouTube video: 2-minute ragdoll in R.U.B.E Box2D editor
Sep 29: YouTube video: R.U.B.E Box2D editor usage example

Box2D C++ tutorials - Moving at constant speed

Last edited: July 14 2013

Chinese version -> 中文

Moving a body at a constant speed


A common requirement in games is to make a body move at a constant speed. This could be a player character in a platform game, a spaceship or car, etc. Depending on the game, sometimes a body should gain speed gradually, in other situations you might want it to start and stop instantaneously. It is very tempting to use the SetLinearVelocity function to explicitly set the velocity for a body to accomplish this, and indeed it does get the job done, but this approach has its drawbacks. While it often looks fine on the screen, setting the velocity directly means the body is not correctly participating in the physics simulation. Let's see how we can use the more realistic forces and impulses to move a body at a desired speed.

We'll look at two situations, one where the body should immediately start moving at the desired speed, and one where it should accelerate gradually until it reaches a specified top speed. To start with we'll need a scene with one dynamic body, and we'll make some static body walls to fence it in. This fence will come in handy in some of the upcoming topics too. To keep track of what the user wants to do, we'll have a class variable to store the last received input.
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
  //enumeration of possible input states
  enum _moveState {
    MS_STOP,
    MS_LEFT,
    MS_RIGHT,
  };
  
  //class member variables
  b2Body* body;
  _moveState moveState;
  
  FooTest() {
    //body definition
    b2BodyDef myBodyDef;
    myBodyDef.type = b2_dynamicBody;
    
    //shape definition
    b2PolygonShape polygonShape;
    polygonShape.SetAsBox(1, 1); //a 2x2 rectangle
  
    //fixture definition
    b2FixtureDef myFixtureDef;
    myFixtureDef.shape = &polygonShape;
    myFixtureDef.density = 1;
    
    //create dynamic body
    myBodyDef.position.Set(0, 10);
    body = m_world->CreateBody(&myBodyDef);
    body->CreateFixture(&myFixtureDef);
    
    //a static body
    myBodyDef.type = b2_staticBody;
    myBodyDef.position.Set(0, 0);
    b2Body* staticBody = m_world->CreateBody(&myBodyDef);
    
    //add four walls to the static body
    polygonShape.SetAsBox( 20, 1, b2Vec2(0, 0), 0);//ground
    staticBody->CreateFixture(&myFixtureDef);
    polygonShape.SetAsBox( 20, 1, b2Vec2(0, 40), 0);//ceiling
    staticBody->CreateFixture(&myFixtureDef);
    polygonShape.SetAsBox( 1, 20, b2Vec2(-20, 20), 0);//left wall
    staticBody->CreateFixture(&myFixtureDef);
    polygonShape.SetAsBox( 1, 20, b2Vec2(20, 20), 0);//right wall
    staticBody->CreateFixture(&myFixtureDef);
  
    moveState = MS_STOP;
  }
Constant speed We'll need a Keyboard() function for input:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  void Keyboard(unsigned char key)
  {
    switch (key)
    {
      case 'q': //move left
        moveState = MS_LEFT;
        break;
      case 'w': //stop
        moveState = MS_STOP;
        break;
      case 'e': //move right
        moveState = MS_RIGHT;
        break;
      default:
        //run default behaviour
        Test::Keyboard(key);
    }
  }
From now, all further changes will be made in the Step() function to implement the movement behaviour depending on this input.

Setting velocity directly


Before we get started on the force/impulse methods, let's see how SetLinearVelocity works to directly specifying the velocity of the body. For many applications this may be good enough. Inside the Step() function, we will take whatever action is required each time step:
1
2
3
4
5
6
7
8
9
  //inside Step()
    b2Vec2 vel = body->GetLinearVelocity();
    switch ( moveState )
    {
      case MS_LEFT:  vel.x = -5; break;
      case MS_STOP:  vel.x =  0; break;
      case MS_RIGHT: vel.x =  5; break;
    }
    body->SetLinearVelocity( vel );
Here we are getting the current velocity and leaving the vertical component unchanged, and feeding it back because we only want to affect the horizontal velocity of this body.

Trying this code in the testbed you'll see that this setup gives us the instantaneous speed scenario. To implement a gradual acceleration up to a maximum speed, you could do something like this instead.
1
2
3
4
5
6
    switch ( moveState )
    {
      case MS_LEFT:  vel.x = b2Max( vel.x - 0.1f, -5.0f ); break;
      case MS_STOP:  vel.x *=  0.98; break;
      case MS_RIGHT: vel.x = b2Min( vel.x + 0.1f,  5.0f ); break;
    }
This will increase the velocity linearly by 0.1 per time step to a maximum of 5 in the direction of travel - with the default testbed framerate of 60fps the body will take 50 frames or just under a second to reach top speed. When coming to a stop the speed is reduced to 98% of the previous frame's speed, which comes to about 0.98^60 = a factor of about 0.3 per second. An advantage of this method is that these acceleration characteristics can be easily tuned.

Using forces


Forces are more suited to the gradual acceleration to top speed scenario, so let's try that first:
1
2
3
4
5
6
7
8
9
    b2Vec2 vel = body->GetLinearVelocity();
    float force = 0;
    switch ( moveState )
    {
      case MS_LEFT:  if ( vel.x > -5 ) force = -50;  break;
      case MS_STOP:  force = vel.x * -10; break;
      case MS_RIGHT: if ( vel.x <  5 ) force =  50; break;
    }
    body->ApplyForce( b2Vec2(force,0), body->GetWorldCenter() );
This is similar to the above in that the acceleration is linear and the braking is non-linear. For this example we have a pretty basic logic which simply applies the maximum force in every time step where the body is moving too slow. You will likely want to adjust this for the application you are making eg. a car might accelerate quickly at low speeds, but as it nears the maximum speed it's rate of acceleration decreases. For this you could just look at the difference between the current speed and the maximum speed and scale back the force as appropriate.

Remembering from the previous topic that forces act gradually, it might seem unlikely that we could use them to implement an instantaneous speed change. However, if we make the time span very short and the force very large, we can get the same effect as an impulse. First we need to do a little math...

The relationship between force and acceleration is f = ma where m is the mass of the body we're moving, a is acceleration which is measured in "units per second per second", and f is the force we want to calculate. The acceleration could also be called "velocity per second", since velocity and "units per second" are the same thing. So we could write this as f = mv/t where t is the length of time the force will be applied.

We can get m by using the body's GetMass() function. v will be the change in velocity we desire which is the difference between the maximum speed and the current speed. To get an instantaneous speed change effect, we would be applying the force for one time step or 1/60th of a second if using the default testbed framerate. Now we know everything except f, so we do something like this:
1
2
3
4
5
6
7
8
9
10
11
    b2Vec2 vel = body->GetLinearVelocity();
    float desiredVel = 0;
    switch ( moveState )
    {
      case MS_LEFT:  desiredVel = -5; break;
      case MS_STOP:  desiredVel =  0; break;
      case MS_RIGHT: desiredVel =  5; break;
    }
    float velChange = desiredVel - vel.x;
    float force = body->GetMass() * velChange / (1/60.0); //f = mv/t
    body->ApplyForce( b2Vec2(force,0), body->GetWorldCenter() );
This should give you the same behaviour as the SetLinearVelocity did, while still remaining a realistic physics scenario.

Using impulses


Astute readers will notice that the code immediately above is basically simulating an impulse. However since impulses already take into account the length of the simulation timestep, we can just take the time part out and get the same effect with ApplyLinearImpulse:
1
2
3
4
5
6
7
8
9
10
11
    b2Vec2 vel = body->GetLinearVelocity();
    float desiredVel = 0;
    switch ( moveState )
    {
      case MS_LEFT:  desiredVel = -5; break;
      case MS_STOP:  desiredVel =  0; break;
      case MS_RIGHT: desiredVel =  5; break;
    }
    float velChange = desiredVel - vel.x;
    float impulse = body->GetMass() * velChange; //disregard time factor
    body->ApplyLinearImpulse( b2Vec2(impulse,0), body->GetWorldCenter() );
For a gradual acceleration, just adjust the desired change in velocity as appropriate:
1
2
3
      case MS_LEFT:  desiredVel = b2Max( vel.x - 0.1f, -5.0f ); break;
      case MS_STOP:  desiredVel = vel.x * 0.98f; break;
      case MS_RIGHT: desiredVel = b2Min( vel.x + 0.1f,  5.0f ); break;