9. Special Effect: Simulating Gravity

In these notes you will learn:

  • How to simulate gravity.
  • How to simulate the elasticity of an object.

9.1. Introduction

So far our bouncing ball simulations have ignored gravity. In this note we will see how we can apply a couple of simple tricks to get effects that look as if gravity is in action.

We won’t worry about the exact physics of gravity here: all that concerns us here is that the ball looks like it is under the influence of gravity.

Note

Of course, sometimes it is important to simulate gravity accurately, or other physical processes, even in video games. This is tricky enough that many games use so-called physics engines that provide pre-made functions designed for efficiently simulating realistic physics. As you can imagine, creating a physics engine needs a lot more knowledge of physics than we will cover in this introductory programming course.

If you are curious about this topic, then you might want to look at a book such as Game Physics Engine Development by Ian Millington.

9.2. A Bouncing Ball in Gravity

We’re going to explore gravity with a simple bouncing ball demo. The trick we’ll use to simulate gravity is to add a small constant value to dy (the speed of the ball in the y-direction) on each call to draw(). In other words, we will continuously increase the speed in the y-direction.

Note

Changing the value of dy each time draw() is called is constant acceleration, and in the real world gravity works essentially the same way. Objects accelerate due to gravity, with their speed increasing 9.8 meters per second each second they fall.

This has the effect of making the ball fall downwards slowly at first, but then increasing in speed as it nears the bottom. When it hits the bottom edge, we reverse dy to get a simple bouncing effect.

We will also simulate the balls elasticity, which is one of the factors that determines how high the ball bounces after it hits the ground. The idea of elasticity is that every time the ball hits the ground it loses some energy, and so it bounces lower and lower. Exactly how much energy the ball loses depends on what it is made of, e.g. a rubber ball loses less energy than a glass marble. Instead of directly modelling the material of the ball, we’ll use elasticity to dampen the bounce every time it hits the ground.

We are still ignoring some details, such as the ball’s mass and air friction. But as you will see when you run the program, the results look good enough to be used in many games.

Here is the program:

float x, y;
float dx, dy;
float gravity_y;
float elasticity;

void setup() {
  size(500, 500);
  smooth();

  // set the initial position and speed of the ball
  x = 25;
  y = 100;
  dx = 1.8;
  dy = 0;

  // gravity and elasticity are constant values: try changing them
  gravity_y = 0.1;
  elasticity = 0.5;
}


void draw() {
  background(255);
  noStroke();

  fill(200, 0, 0);
  ellipse(x, y, 50, 50);

  x += dx;
  y += dy;

  dy += gravity_y;

  if (y + 25 >= 500) {
    y = 500 - 25;
    dy = -(dy * elasticity);
  }
}

Notice a couple of things about this program:

  • We’ve declared two variables on the same line, e.g.:

    float x, y;
    

    This is just to save a bit of typing. It is the same as if we had written it out like this:

    float x;
    float y;
    
  • The bigger the value of elasticity, the higher the ball bounces. So, for instance, the elasticity for a fully-inflated basketball might be 0.75, while a bowling ball (that would hardly bounce at all) might have an elasticity of 0.1.

9.3. Adding More Gravity

In real life there is only one major source of gravity on Earth that pulls things downwards. However, it is easy to simulate other kinds of gravity to our demo program.

For example, just for fun lets add a second force of gravity that causes things to move towards the right edge of the screen:

float x, y;
float dx, dy;
float gravity_x, gravity_y;
float elasticity;

void setup() {
  size(500, 500);
  smooth();

  // set the initial position and speed of the ball
  x = 25;
  y = 100;
  dx = 1.8;
  dy = 0;

  // gravity and elasticity are constant values: try changing them
  gravity_x = 0.025;
  gravity_y = 0.05;
  elasticity = 0.5;
}


void draw() {
  background(255);
  noStroke();

  fill(200, 0, 0);
  ellipse(x, y, 50, 50);

  x += dx;
  y += dy;

  dx += gravity_x;
  dy += gravity_y;

  if (y + 25 >= 500) {
    y = 500 - 25;
    dy = -(dy * elasticity);
  }

  if (x + 25 >= 500) {
    x = 500 - 25;
    dx = -(dx * elasticity);
  }
}

The movement of the ball is now much more complex. Try deleting the line background(255) to get the ball to leave a trail.

9.4. Questions

  1. Besides certain video games, what is another application that might require more accurate modelling of physics?
  2. What is the purpose of the variable elasticity?

9.5. Programming Questions

  1. Modify the gravity demo program so the ball’s bottom edge bounces on the bottom of the screen, and not its center.
  2. Modify the the gravity demo program so that the ball stops when it hits the right edge of the screen instead of rolling off.
  3. Modify the the gravity demo program to use an image (of your choice) instead of a circle. Make sure no part of the image goes off the screen when it bounces.
  4. Modify the the gravity demo program so that gravity pulls the ball up instead of down, causing the ball to bounce on the top edge.
  5. Modify the the gravity demo program so that gravity pulls the ball to the left instead of down, causing the ball to bounce on the left edge.