16. Scrolling Text

In these notes you will learn:

  • How to make upwards-scrolling movie credits.
  • How to make move credits that fade away.

16.1. Introduction

Now that we’ve seen how to use strings and fonts, lets look at an interesting application: scrolling text.

No doubt you’ve seen dozens of credit-lists at the end of movies and TV shows that slowly move up the screen. In this note we’ll write some programs that simulate movie credit scrolls.

To be concrete, suppose we want to scroll these cast credits from the movie Double Indemnity:

Fred MacMurray       ...   Walter Neff
Barbara Stanwyck     ...   Phyllis Dietrichson
Edward G. Robinson   ...   Barton Keyes

16.2. Program 1: Basic Upwards Scrolling

Since we only have three lines of text to scroll, we’ll store each line in a separate String variable:

String line1;
String line2;
String line3;

void setup() {
   // ...
   line1 = "Fred MacMurray       ...   Walter Neff";
   line2 = "Barbara Stanwyck     ...   Phyllis Dietrichson";
   line3 = "Edward G. Robinson   ...   Barton Keyes";
   // ...
}

Later in the course we’ll see that arrays are usually a better way of storing multiple strings.

Before we worry about the scrolling, lets first neatly display these three strings on the screen:

PFont font;

float x;   // (x, y) is the position of the first line
float y;

float lineSep;  // distance between each line

String line1;
String line2;
String line3;

void setup() {
  size(750, 500);
  font = loadFont("Purisa-48.vlw");
  textFont(font);

  x = 20;
  y = 500;
  lineSep = 50;

  line1 = "Fred MacMurray       ...   Walter Neff";
  line2 = "Barbara Stanwyck     ...   Phyllis Dietrichson";
  line3 = "Edward G. Robinson   ...   Barton Keyes";
}

void draw() {
  background(255);
  fill(0);
  text(line1, x, y);
  text(line2, x, y + lineSep);
  text(line3, x, y + 2 * lineSep);
}

The structure of this program is very similar to previous programs that display text on the screen. The big difference here is that we are displaying three different lines of text, and we use lineSep to space them out properly.

Now getting the scrolling to work is not too hard. We need to do a couple of things:

  • Add a dy variable to control the vertical movement of the scrolling text.
  • Set the initial value of y so that the scroll begins at the bottom of the screen.

Here is the modified code:

PFont font;

float x;   // (x, y) is the position of the first line
float y;

float dy;  // scroll velocity

float lineSep;  // distance between each line

String line1;
String line2;
String line3;

void setup() {
  size(750, 500);
  font = loadFont("Purisa-48.vlw");
  textFont(font, 32);

  // values for x and lineSep were chosen by experimentation
  x = 20;
  y = 550;
  dy = -1;
  lineSep = 50;

  line1 = "Fred MacMurray       ...   Walter Neff";
  line2 = "Barbara Stanwyck     ...   Phyllis Dietrichson";
  line3 = "Edward G. Robinson   ...   Barton Keyes";
}

void draw() {
  background(255);
  fill(0);
  text(line1, x, y);
  text(line2, x, y + lineSep);
  text(line3, x, y + 2 * lineSep);

  // move the text
  y += dy;
}

16.3. Program 2: Stopping and Fading Away

One of the many variations on credit-scrolling is to have the text scroll up to the middle of the screen, stop, and then fade away. To achieve this we will have to make two main modifications to our previous program:

  1. Add if-statements to check when the text has reached the middle of the screen. This is just a variation on checking for the edges of the screen, which we’ve seen a number of times now.
  2. Add code to cause the text to fade away. We’ve already seen this effect in Special Effect: A Fading Circle, and we’ll use the same technique here. We’ll add two new float variables:
    • transparency is a value between 0 and 1 that represents the current level of transparency for the on-screen text;
    • dt is the rate at which the transparency changes.

Here is the code:

PFont font;

float x;   // (x, y) is the position of the first line
float y;

float dy;  // scroll velocity

float lineSep;  // distance between each line

float transparency;  // how transparent is the text: between 0 and 1
float dt;  // the rate at which transparency changes

String line1;
String line2;
String line3;


void setup() {
  size(750, 500);
  font = loadFont("Purisa-48.vlw");
  textFont(font, 32);

  x = 20;
  y = 550;
  dy = -1;
  lineSep = 50;

  transparency = 1;
  dt = 0;

  line1 = "Fred MacMurray       ...   Walter Neff";
  line2 = "Barbara Stanwyck     ...   Phyllis Dietrichson";
  line3 = "Edward G. Robinson   ...   Barton Keyes";
}

void draw() {
  background(255);
  fill(0, 0, 0, map(transparency, 0, 1, 0, 255));
  text(line1, x, y);
  text(line2, x, y + lineSep);
  text(line3, x, y + 2 * lineSep);

  // stop moving when text has reached the middle
  if (y < 200) {
    dy = 0;      // stop the text from moving
    dt = -0.01;  // start decreasing the text's transparency
  }

  // move the text
  y += dy;

  // change the transparency
  transparency += dt;
}

16.4. Questions

  1. Describe the purpose of the lineSep variable.

16.5. Programming Questions

  1. Modify the first credit scroll program so that the credits scroll down instead of up. They should start entirely off the screen and then scroll down and off the bottom
  2. Modify the first credit scroll program so that the credits scroll from left to right. The credits should just scroll off the right edge of the screen.
  3. Modify the first credit scroll program so that the credits continuously “bounce” from left to right and right to left at a constant speed. No part of any of the credits should ever be off the screen.
  4. Write a program that displays the three strings in the sample programs as follows: the screen starts out empty, and the first name slowly fades in, stays on the screen for a while, and then slowly fades out. Then the next two names appear and disappear in the same way.

16.6. Appendix: Program 1 Using the Label Class

The Label class was mentioned in previous notes as simpler way to deal with fonts in Processing.

Here is an alternate solution to this problem using putLabel (you will need the Label class and putLabel functions in your program for this to work):

float y = 550;       // vertical position of the first line
float dy = -1;       // scroll velocity
float lineSep = 50;  // distance between each line

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

void draw() {
  background(255);

  putLabel("Fred MacMurray       ...   Walter Neff", 20, y);
  putLabel("Barbara Stanwyck     ...   Phyllis Dietrichson", 20, y + lineSep);
  putLabel("Edward G. Robinson   ...   Barton Keyes", 20, y + 2 * lineSep);

  // move the text
  y += dy;
}

And another solution that uses Label objects:

// we only need to set the position of line1 here because the other lines
// are positioned relative to it in draw()
Label line1 = new Label("Fred MacMurray       ...   Walter Neff", 20, 550);
Label line2 = new Label("Barbara Stanwyck     ...   Phyllis Dietrichson");
Label line3 = new Label("Edward G. Robinson   ...   Barton Keyes");

float dy = -1;       // scroll velocity
float lineSep = 50;  // distance between each line

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

void draw() {
  background(255);

  line1.render();
  line2.render(20, line1.y + lineSep);
  line3.render(20, line2.y + lineSep);

  // move the text
  line1.y += dy;
}

16.7. Appendix: Program 2 Using the Label Class

Here is program 2 using the Label class from the previous notes. You will need the Label class in your program for this to work:

float dy = -1;       // scroll velocity
float lineSep = 50;  // distance between each line

float transparency = 1;  // how transparent is the text: between 0 and 1
float dt = 0;            // the rate at which transparency changes

// only the first line is given a position since the later lines are
// positioned relative to it
Label line1 = new Label("Fred MacMurray       ...   Walter Neff", 20, 550);
Label line2 = new Label("Barbara Stanwyck     ...   Phyllis Dietrichson");
Label line3 = new Label("Edward G. Robinson   ...   Barton Keyes");

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

void draw() {
  background(255);

  color c = color(0, 0, 0, map(transparency, 0, 1, 0, 255));
  if (alpha(c) == 0) c = color(255);

  line1.msgColor = c;
  line1.render();

  line2.msgColor = c;
  line2.render(20, line1.y + lineSep);

  line3.msgColor = c;
  line3.render(20, line2.y + lineSep);

  // stop moving when text has reached the middle
  if (line1.y < 200) {
    dy = 0;      // stop the text from moving
    dt = -0.01;  // start decreasing the text's transparency
  }

  // move the text
  line1.y += dy;

  // change the transparency
  transparency += dt;
}