5. Making Things Move

In these notes you will learn:

  • How to make an object move down the screen at different speeds.
  • How to animate two objects on the screen at once.

5.1. Introduction

We’ve seen how to make things follow the mouse using the mouseX and mouseY variables, and so now lets turn to the topic of making things move on their own.

The basic trick for making an object move is to change it’s (x, y) location on each call to draw(). For instance, to make an object move at a constant speed in a straight line, we add some constant value to x, and a (possibly different) constant value to y on each call to draw().

Note

In this course we are not worrying much about the precise physical equations that govern the movement of objects in the real world. As long as the movement looks good enough, then we will leave it at that. This is a pretty common approach when you are making animations for, say, video games, where how things look is more important than precisely simulating the real world.

5.2. A Ball that Falls Down

Now lets write a program that makes a ball fall from the top of the screen to the bottom. We’ll use a variable, y, to store the vertical position of the ball, i.e. it’s position along the y-axis.

Enter this program into Processing:

color orange = color(255, 165, 0);
color white = color(255, 255, 255);

// y is the vertical position of the ball
float y;

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

  // the ball starts near the top of the screen
  y = 50;
}

void draw() {
  // re-draw the background
  background(white);

  // draw the ball
  noStroke();
  fill(orange);
  ellipse(250, y, 50, 50);

  // add 1 to y to make the ball move downwards
  y += 1;
}

When you run it, you should see an orange ball slowly moving down the screen.

To understand this program, look at the variable y, the y-coordinate of the ball’s center. Every time we add 1 to it (using the statement y += 1) in draw() the ball gets drawn one pixel lower down. Thus the ball appears to move slowly down the screen.

What happens when the ball hits the bottom of the screen? For this program, “nothing”: it keeps going, never to be seen again. We’ll learn a little later how to make things “bounce” when they hit an edge.

An important detail of this program is the line that defines y:

float y;

This statement defines y to be a variable of type float and assigns it an initial value of 0.0. Every variable in Processing has a type, and the type float is what Processing uses for numbers that have a decimal point in them (e.g. 78.939, -34.2, etc.).

Once y is defined, you can change it value using an assignment statement, e.g.:

y = 5;    // assigns the value 5 to y

This line causes the value 5 to be stored in the memory location y refers to it. Or, more briefly, we say that it assigns 5 to y.

Note also that we define y outside of both the setup() and draw() functions. This ensures y is usable — visible — anywhere in our program. If we had defined y inside a function, then it would only be usable within that function.

It’s sometimes useful to imagine variables as boxes with labels, e.g.:

Variable y with type float and value 0.0.

This diagram shows that y is of type float and currently has the value 0.0.

5.3. A Small Change

Lets modify the program so that the ball moves in the opposite direction, i.e. rising from the bottom to the top of the screen. Only two changes are needed: we make the initial value of y something close to the bottom of the screen (e.g. 450), and then we subtract 1 from y every time draw() is called:

color orange = color(255, 165, 0);
color white = color(255, 255, 255);

// y is the vertical position of the ball
float y;

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

  // the ball starts near the bottom of the screen
  y = 450;
}

void draw() {
  // re-draw the background
  background(white);

  // draw the ball
  noStroke();
  fill(orange);
  ellipse(250, y, 50, 50);

  // subtract 1 from y to make it move upwards
  y -= 1;
}

Notice that we wrote y -= 1 at the end of draw(). This is one way to subtract 1 from a variable in Processing. Similarly, y += 1 adds 1 to y.

If you want to change the speed of the ball, then subtract a different amount, e.g. to cut the ball’s speed in half try subtracting 0.5 from y using the statement y -= 0.5 in the previous program. If you want the ball to move at twice the speed, then subtract 2 using y -= 2: now on each call to draw() the ball moves 2 pixels up the screen instead of 1.

5.4. Moving Images

Now lets re-write our first program (where the ball moves down the screen) using an image in place of the ball. The code has the same structure, except now we use the commands for loading and placing images:

// convenient colors
color white = color(255, 255, 255);

// images
PImage foot;

// y is the vertical position of the foot
float y;

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

  foot = loadImage("foot.png");

  // the foot starts off the top of the screen
  y = -250;
}

void draw() {
  // re-draw the background
  background(white);

  // draw the foot
  image(foot, 0, y);

  // add 1 to y to make it move downwards
  y += 1;
}
A foot.

This code draws a foot (that you may recognize) moving slowly down the screen. The file foot.png stores the picture of a foot, and in setup we use loadImage to store it in the computer’s memory as a PImage variable named foot.

Warning

For this program to work as-is, it’s important that the file foot.png be in the right folder. Recall that loadImage looks for the image files in the folder that contains the Processing .pde source file, or in a folder called data stored in the same folder as the .pde file.

In draw() we clear the screen, display the foot at location (0, y), and then increase y.

Notice that y is set to -250 in setup. Since -250 is not on the screen the foot is revealed as it moves. Placing objects at points off the visible part of the screen is a useful trick that we will occasionally use.

5.5. Adding a Fish

Now lets modify the program so that there’s a fish at the bottom of the screen:

// convenient colors
color white = color(255, 255, 255);

// images
PImage foot;
PImage fish;

// y is the vertical position of the foot
float y;

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

  foot = loadImage("foot.png");
  fish = loadImage("fish.png");

  // the foot starts off the top of the screen
  y = -250;
}

void draw() {
  // re-draw the background
  background(white);

  // draw the fish near the bottom of the screen
  image(fish, 200, 295);

  // draw the foot
  image(foot, 0, y);

  // add 1 to y to make it move downwards
  y += 1;
}
A foot and a fish.

Essentially all we’ve done here is to add the PImage variable fish. We load a picture of a fish into it in setup(), and then display it near the bottom of the screen.

The fish doesn’t move, i.e. it is always displayed at the same coordinates. Eventually the foot covers the fish, and, then, because nothing stops the foot, it keeps going and slides off the screen revealing the fish.

An important detail in this program is that the fish is drawn before the foot. Thus the foot covers the fish. To see this, change the order of the image commands, i.e. draw the foot before the fish. In programs with many graphical objects the order in which they get drawn is quite important, and we will eventually need a better way of dealing with it. For now, we will just be careful to draw things in the right order.

5.6. Questions

  1. Define frame rate.
  2. About how many frames per second can Processing display?
  3. Why might the frame rate in a Processing program decrease?
  4. In the first program, why do we add 1 to y instead of subtracting 1?
  5. What kinds of values can a float variable, such as y in the sample programs, contain?
  6. Why is y defined outside of the setup() and draw() functions?
  7. Write a statement that adds 5 to y.
  8. Suppose you swap the order in which the foot and fish are drawn on the screen in the draw() function of the foot/fish program. Describe what you see when the program runs.

5.7. Programming Questions

  1. Modify the first program so that the ball moves left-to-right across the screen.

  2. Modify the first program so that the ball moves right-to-left across the screen.

  3. Modify the first program so that the ball moves diagonally across the screen, e.g. top-to-bottom and right-to-left across the screen. You’ll need to add an x variable to keep track of the x-coordinate of the ball.

  4. Modify the rising ball program to make it look like a balloon floating up and off the screen. Do this by drawing a line from the bottom of the balloon to look like a string:

    A balloon with a string.
  5. Write a program that makes two balls move at the same time on the screen: a red ball going down, and a green ball going up. Each ball will need its own y-coordinate.

  6. Re-do the previous question, but this time have the two balls move in different diagonal directions. You’ll need one x and one y variable for each ball.

  7. Modify the foot/fish program so that the fish follows the x-coordinate of the mouse pointer. Don’t change it’s y-coordinate, i.e. keep it where it is on the bottom of the screen and just let it move left/right with the mouse pointer. The foot animation should not change.

    When this program is done, the foot should slowly descend onto a fish that can move left/right.

  8. Modify the foot/fish program as in the previous question, but also allow the fish to move vertically (i.e. up and down) up to, at most, the bottom of the foot.