Learning goals

What to do

Your task is to animate one or more elements of your image.

This task will depend on having a method with x and/or y parameters that draws an element at a specified position: see Lab 2.

The following example illustrates how to do this.

The building has landed

The example image from Lab 2 seems like a peaceful city scene (click for full size):

You may not have realized that there is a backstory: one of the buildings is not a building at all. It’s actually an alien spaceship! Click the link below to see the animation:

Building animation

Animation basics

The basic principle of animation is very straightforward: the program should draw a series of slightly different images, with small delay between each image. If the delay between images is small, our eyes will perceive the changes between images as motion.

Processing is designed for animation: by default, your program’s draw method is called 10 times per second. So, if each time draw executes it draws a slightly different scene, we have animation! We will refer to the slightly different images drawn by the draw method as the program executes as frames.

To animate a single element of the image, as we did in the building animation, all we need to do is draw the element in a different position in each frame. The perceived motion of the element will depend on how the element’s position is changing. In the building example, we wanted the building to move from the top of the scene towards the bottom. So, we need to make the moving building’s y coordinate increase.

Doing this is simple: we can add a global variable to the program to keep track of where the moving building should be displayed. Our global variable will look like this:

int buildingY = -140;

It is a global variable as long as we define it outside any of the program’s methods. Global variables are “visible” to all of the methods in the program, so they can be referred to in any method. Note that for this global variable, we have defined it as an int (integer), and given it an initial value (-140).

To implement the animation, we just need to make two small changes to the program. First, in the drawBuildings method, we will change the line of code that calls the drawBuildingOne method to draw the animated building. This is the original line of code:

drawBuildingOne(120,400);  // use x=120,y=400 for this copy

We will change it as follows:

drawBuildingOne(120,buildingY);  // this is the moving building!

Note that rather than drawing the building at a fixed y coordinate, we specify its y coordinate as whatever the current value of the buildingY variable is.

The last change we need to make is that the value of buildingY needs to be updated for each frame of the animation. This is easily accomplished by adding some code to the beginning of the drawBuildings method, which is executed once per frame (because it is called by the draw method). We will add the following code to the top of the method:

if (buildingY < 400) {
  buildingY++;
}

This code uses an if construct to check whether buildingY is less than 400. If it is, then it increases the value of buildingY by 1. (That is what the ++ does.) The purpose of the if construct is to make the building stop moving when buildingY reaches 400. If we didn’t do this, the building would keep moving down indefinitely, and eventually move past the bottom of the scene.

Here is the complete code: CityLightsAnimation.pde

Other possibilities

The example above is a simple one. There are many more possible ways to add animated elements to your program:

Using arrays to control many elements at once

If you are animating multiple elements, you will need at least one global variable per element. Using and updating multiple variables can become tedious and error-prone.

An array is a sequence of variables. The variables in an array are called the elements of the array, and each array element is referred to using an integer index. The first element in an array has index 0, the second has index 1, etc.

Here is how we might use arrays to animate all of the buildings (except for the original second building, which we’ll leave where it is.)

First, we’ll declare two global arrays to keep track of

Here are the global arrays:

int[] buildingY = { -200, -320, -175, -240, -190, -210 };
int[] stopY = { 410, 400, 420, 415, 420, 380 };

Note how there are 6 elements in each array, one for each building. The buildingY array serves the same purpose that the buildingY variable did in the previous animation, except that now it can keep track of the positions of 6 buildings rather than just one building. The stopY array keeps track of where each building should stop: this allows each building to stop moving at a different position.

Now we just need code to

We can add code to the drawBuildings method to accomplish both of these:

for (int i = 0; i < buildingY.length; i++) {
  if (buildingY[i] < stopY[i]) {
    buildingY[i]++;
  }
}
  
drawBuildingOne(-10,buildingY[0]);
drawBuildingOne(120,buildingY[1]);
drawBuildingOne(60,buildingY[2]);
drawBuildingOne(195,buildingY[3]);
drawBuildingOne(260,buildingY[4]);
drawBuildingOne(340,buildingY[5]);

The for loop checks each building’s y coordinate (i is an index to select an element, first 0, then 1, etc.) and increases the building’s y coordinate if the y coordinate has not yet reached the stop value.

The calls to drawBuildingOne are the same as before, except that instead of hard-coded y coordinate values, the y coordinate values are taken from the values of the elements of the buildingY array.

Click the following link to see the updated animation:

Multiple building animation

Here is the complete code: CityLightsAnimation2.pde