Processing array tutorial

How to use this tutorial

This tutorial consists of sections which address a variety of issues in using arrays. Each section includes explanation and example code; because you learn programming by doing, not by reading, each section also includes exercises. You can work your way through by reading the material for a particular section and then immediately doing the exercises. If you already know some things about arrays, you can check the list below to jump directly to the material that is new to you.

Jump to: Introduction - Declaring an array - Using for loops with arrays - Using array length in for loops - Setting the values of an array - Coordinating multiple arrays - Dynamic code with arrays - Arrays that change length - Using arrays to support interaction

Introduction

So far, the variables we have used have generally stored a single value: an integer, a float, a boolean, etc. Arrays are a special kind of variable, that store a numbered list of values instead of one value. By using arrays, we can store and operate on much larger collections of values than would be possible to do by defining individual variables for each item. It is easy, for example, to create and operate on lists of 500 points or more.

Declaring an array

How do you make an array? We can tell Processing that we want to create a variable that stores a list of integers like this:

int[] xValues = { 30, 12, 3, 89};

This told Processing to make a new variable called xValues. The int[] xValues part told Processing that xValues is going to be an array of integers, i.e. it will hold a numbered list of integer values. The = { 30, 12, 3, 89} part told Processing what the initial value of xValues will be. Specifically, it says that the xValues variable will hold the 4 integers listed, stored in sequence. In other words, stored in xValues is a list that looks like this:

  1. 30
  2. 12
  3. 3
  4. 89

Note that this is a numbered list, i.e. each value that we gave Processing to put in the array is associated with a number which represents its order in the array; number 0 on the list is 30, number 1 on the list is 12, and so on. This number is called the "index." We can access each element of the array using its index in the following way. xValues[0] tells Processing to work with item number 0 on the list, i.e. 30. xValues[1] accesses item number 1 on the list, i.e. 12. In general, xValues[i] will access the element which has the index i in the list.

So, we can write code like the following to use the whole list:

int[] xValues = { 30, 12, 3, 89};

// draw circles with x values from the
// xValues array
ellipse(xValues[0],height/2,5,5);
ellipse(xValues[1],height/2,5,5);
ellipse(xValues[2],height/2,5,5);
ellipse(xValues[3],height/2,5,5);

Exercise

  1. Write a program that uses an array to store 4 integers and uses those integers to set the stroke width for 4 shapes of your choice.

Using for loops with arrays

Note that the code we just wrote is pretty repetitive. Generally speaking, in Processing, when code is repetitive we can use a for loop to make it simpler. In this case, that "ellipse" code is pretty much the same from line to line. So, we can replace it with a simpler version:

int[] xValues = { 30, 12, 3, 89};

// draw circles with x values from the
// xValues array
for(int i = 0; i < 4; i++) {
  ellipse(xValues[i],height/2,5,5);
}

What is this code doing? The for loop uses an integer variable i whose value increases 1 every time through the loop, until it reaches 4. In other words, i's value is 0, 1, 2, and then 3. Each time, we draw a circle using the ith value from xValues.

We can think of this another way. Remember that xValues is a numbered list:

  1. 30
  2. 12
  3. 3
  4. 89
Essentially, what the for loop is doing is sequentially going through the list, and doing the same thing to each item on the list; in this case, drawing the circle.

Exercise

  1. Copy and alter the code in this section so that instead of drawing an ellipse at each x-coordinate on the list, it draws a line from the top to the bottom of the screen at each x-coordinate point.

Using array length in for loops

What happens if we change the number of items in the list? How does the code change?

int[] xValues = { 30, 12, 3, 89, 17, 36};

// draw circles with x values from the
// xValues array
for(int i = 0; i < 6; i++) {
  ellipse(xValues[i],height/2,5,5);
}
If you look at this code and compare it to the last version, you'll see that two things changed. The first is that I added two extra numbers to the xValues initialization. This makes the list stored in xValues look like this:
  1. 30
  2. 12
  3. 3
  4. 89
  5. 17
  6. 36

The second change is the for loop now checks for "i < 6" instead of "i < 4." In other words, the for loop is now running for all 6 items on the list instead of the 4 items it was previously checking.

It's a hassle, though, to change all the for loops in a program every time you change the amount of data in the array. For this reason, Processing makes this a little bit easier for us by providing some extra information about the array. Specifically, for each array, Processing keeps track of the length of the list it holds for us, which we can access by typing arrayName.length (substitute in the name of the variable you are using).

Now, we can write our code this way:

int[] xValues = { 30, 12, 3, 89, 17, 36};

// draw 6 circles with x values from the
// xValues array
for(int i = 0; i < xValues.length; i++) {
  ellipse(xValues[i],height/2,5,5);
}
With this phrasing, we can add or delete numbers from the xValues array as much as we want to, without having to change the for loop at all.

In general, it is very common to use for loops in conjunction with the array. The general structure of such a loop is like this:

for(int i = 0; i < arrayName.length; i++) {
	statement(s) that use arrayName[i]
}
Say, for example, you have written code using simple variables to make a point:
point(xpos,ypos);
If you now convert xpos to a variable that stores an array of ints, and want to do the same operation on everything in the array, you would do that like this:
for(int i = 0; i < xpos.length; i++) {
	point(xpos[i],ypos);
}
When using arrays, you will use this structure very, very frequently. It is a good idea to memorize it.

Exercises

  1. Adjust the for loop you used for the previous exercise to use the length of the xValues array instead of a hard-coded numer.
  2. Consider the following program that draws a single transparent circle at a random point to the screen.
    int myHue = 314;
    
    // set up graphics
    background(255);
    fill(0,0);
    colorMode(HSB);
    
    // draw ellipse to screen
    stroke(myHue,255,255);
    ellipse(random(width),random(height),5,5);
    
    Alter this program to draw multiple circles in different hues that you choose. Make myHue into an array that stores multiple hues, and use a for loop to draw all the circles, correctly colored, to the screen.

Setting the values of an array on the fly

So far, we have set the values of the array right where the array is declared, e.g. float speeds[] = { 0.2, 0.3, 05};. But, sometimes you want to set or alter the values in the code itself. Imagine, for example, that you want to make the value of the xValues array used in the prior section be randomly generated every time the program is run. How would you do this? We can do this like this:

int[] xValues;

xValues = new int[6];
xValues[0] = round(random(width));
xValues[1] = round(random(width));
xValues[2] = round(random(width));
xValues[3] = round(random(width));
xValues[4] = round(random(width));
xValues[5] = round(random(width));

// draw circles with x values from the
// xValues array
for(int i = 0; i < xValues.length; i++) {
  ellipse(xValues[i],height/2,5,5);
}

What's going on in this code? A few things.

First, we no longer assign any values to the xValues variable in the initialization. This means our new initialization - int[] xValues; - tells Processing that xValues is going to be an array of integers, but it does not tell Processing how long the list will be, nor what values are in it. In other words, xValues exists as a variable, but like any other variable which has been declared but not initialized, it doesn't have any information in it yet. In other words, the value that xValues holds is something like ?????? - gobbledygook that Processing can't do anything with yet.

The next line, xValues = new int[6] tells Processing to make a new list of 6 int's, and store it in the xValues variable. xValues now contains a list, but the list doesn't have any data in it yet. In other words, we can think of xValues as now holding the following:

  1. ??????
  2. ??????
  3. ??????
  4. ??????
  5. ??????
  6. ??????
I.e. it has 6 slots to store data, but those slots still don't have anything in them. (update: in practice this morning we discovered that if you don't assign a value, but then try to use it, processing will assign the value to be 0. You can try this by adding "println(xValues[1]);" immediately after "xValues = new int[6];" in the code above.)

After this come the lines that actually assign values to the different slots in the array. The line xValues[0] = round(random(width)); uses the random function to generate a number between 0 and the width of the screen, i.e. an arbitrary x coordinate somewhere in the display. By rounding it we are turning it from a float to an int so that we can store it on our list of ints. xValues[0] refers to item number 0 on the xValues list. In other words, xValues[0] = round(random(width)); generates an arbitrary number, then looks in xValues list at slot number 0, and puts that number at that location. Assuming that the program came up with the random number 15, after this assignment statement xValues looks like this:

  1. 15
  2. ??????
  3. ??????
  4. ??????
  5. ??????
  6. ??????
This process then continues in the next lines with the remaining slots on the list until they have all been initialized.

You might note that the code we just wrote is pretty repetitive. This means it is, once again, a candidate for simplifying using a for loop. Indeed, we can use the magic incantation described in the previous section:

for(int i = 0; i < arrayName.length; i++) {
	statement(s) that use arrayName[i]
}
in order to do this assignment. Specifically, we can rewrite the code like this:

int[] xValues;

xValues = new int[6];
for(int i = 0; i < xValues.length; i++){
  xValues[i] = round(random(width));
}

// draw circles with x values from the
// xValues array
for(int i = 0; i < xValues.length; i++) {
  ellipse(xValues[i],height/2,5,5);
}
In other words, we can use a for loop both to initialize and to access elements in an array.

There's one more shortcut we can take here if we want to. We can create the xValues variable and put the list of 6 in it at the same time if we want to:

int[] xValues = new int[6];
for(int i = 0; i < xValues.length; i++){
  xValues[i] = round(random(width));
}

// draw circles with x values from the
// xValues array
for(int i = 0; i < xValues.length; i++) {
  ellipse(xValues[i],height/2,5,5);
}
The line int[] xValues = new int[6]; creates the xValues variable and tells Processing to make it hold a list of 6 integers, but it does not yet specify what each of the 6 integers will be. That comes later, with the for loop.

Exercise

  1. Adapt your code for exercise 2 in the last section to make the hues be randomly generated. Use a for loop to generate the random values

Coordinating multiple arrays

So far, we have used a single array at a time. But there are frequently multiple pieces of data about the shapes you are drawing that you want to store at the same time. A simple example is x and y coordinates. What if instead of having our circles all on the same line, we wanted to have them spread around the screen? We can do this by defining an extra array:

int[] xValues = new int[6];
int[] yValues = new int[6];

for(int i = 0; i < xValues.length; i++){
  xValues[i] = round(random(width));
  yValues[i] = round(random(width));
}

// draw circles with x values from the
// xValues array
for(int i = 0; i < xValues.length; i++) {
  ellipse(xValues[i],yValues[i],5,5);
}

Note that there are now two arrays: one for the x value of the 6 circles, and one for the y value of the 6 circles. The y values are initialized the same way as the x values; in fact, we can use the same for loop, since the arrays are the same length - they'd better be, since they are supposed to be storing information about the same entities (the 6 circles on the screen). In the for loop, we are using both xValues[i] and yValues[i] to get the x and y coordinates, respectively, of the circles.

This can continue indefinitely. Imagine, for example, that you also want to give each circle a unique color. How would you do this? In the same way: (1) Add a new variable called colors which will store 6 colors, (2) add an assignment statement for it in the first for loop which will initialize each colors[i], (3) add a statement to the second for loop which will use each colors[i] to alter the color of the ith circle. In other words:

int[] xValues = new int[6];
int[] yValues = new int[6];
color[] colors = new color[6];

for(int i = 0; i < xValues.length; i++){
  xValues[i] = round(random(width));
  yValues[i] = round(random(width));
  colors[i] = color(random(256),random(256),random(256));
}

// draw circles with x values from the
// xValues array
for(int i = 0; i < xValues.length; i++) {
  fill(colors[i]);
  ellipse(xValues[i],yValues[i],5,5);
}

Exercise

  1. Alter the code developed in this section so that each circle drawn will have a different stroke width, randomly chosen between 1 and 4. Use an array to store the stroke widths.

Dynamic code with arrays

So far, the examples we have used with arrays are all static. But what happens if we want to use arrays in dynamic code? Where do you do what?

For example, consider this code which draws multi-colored lines on the screen:

float[] pos;

// initialize the positions of the lines
pos = new float[10];
for(int i = 0; i < pos.length; i++){
  pos[i] = random(width);
}

// set up the graphics
size(150,150);
strokeWeight(4);
colorMode(HSB);
background(0);

// color and draw each line in the array
for(int i = 0; i < pos.length; i++) {
  stroke(i*10,180,255);
  line(pos[i],0,pos[i],height);
}

What if we want the lines to move across the screen instead, i.e. the positions to change over time?

We'll start by simply converting the existing code to a dynamic version. We'll follow the usual rules for dynamic code:

  1. Put data that needs to be remembered between frames into global variables.
  2. Put statements that only need to happen once at the beginning in setup().
  3. Put statements that need to happen on every frame in draw().

If we look at our horizontal lines code written above, there's an array defined at the top which is used in the drawing, so this will need to be a global variable. The graphics initialization and initialization of the array only needs to happen once and would go in setup(). Since we're going to do animation, the actual drawing would go in draw(). That gives us this:

float[] pos;

void setup() {
  // initialize the positions of the lines
  pos = new float[10];
  for (int i = 0; i < pos.length; i++) {
    pos[i] = random(width);
  }

  // set up the graphics
  size(150, 150);
  strokeWeight(4);
  colorMode(HSB);
  background(0);
}

void draw() {
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
  }
}

So far, the code just does exactly the same thing as the static version. Now, we need to think about the animation. We want the lines to move; this means changing the x position of the lines every frame. We can do that by incrementing the value of each element in the array. In other words, after I have drawn the line associated with each point, I want to increase the x value of that line. We can do that by rewriting draw as follows:

void draw() {
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i]++;
  }
}

If you run this code you'll immediately notice a bug. Now the lines do go off to the right, but they leave a trail behind. Now that we're animating the lines, we need to also clear out the screen on every frame. This means a revision to our draw() function.

void draw() {
  background(0);
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i]++;
  }
}

Finally, you might like the lines to wrap around again after they go off the right hand side of the screen. How can we make them appear again at the left side? We need to test when they go off the right hand side and set them back to the left hand side again. You know how to do this with simple variables, and with array variables the code is basically the same; it's just doing it in the for loop so that it happens to all the values in the array. Once again, we'll rewrite draw as follows:

void draw() {
  background(0);
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i]++;
    if(pos[i] > width) {
      pos[i] = 0;
    }
  }
}

Coordinating multiple arrays in dynamic code

What if we want the lines to go at different speeds? This will require us to keep track of two aspects of each line: its current x position, and its speed. Just as with static code, that requires us to make and coordinate two different arrays.

In our case, this means adding a new array called speed[]. Just as with the pos array in the previous section, this means deciding where to declare, initialize, and use it. We'll add speed as a global variable, then we'll initialize it in setup() and use it in draw().

float[] pos;
float[] speed;

void setup() {
  // initialize the positions of the lines
  pos = new float[10];
  speed = new float[10];
  for (int i = 0; i < pos.length; i++) {
    pos[i] = random(width);
    speed[i] = random(2);
  }

  // set up the graphics
  size(150, 150);
  strokeWeight(4);
  colorMode(HSB);
}

void draw() {
  background(0);
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i] += speed[i];
    if(pos[i] > width) {
      pos[i] = 0;
    }
  }
}

Exercise

  1. Adapt the code for drawing colored circles developed in the previous section so that the circles move down each frame.
  2. Adapt this code so that the circles wrap back around to the top of the screen after they drop off the bottom.

Arrays that change length

Making arrays longer

There are many situations in which an array might need to change length over the course of a program. This frequently happens when you want to support interactions in which the user adds more data to the program. In this case, the array will need to get longer and longer as the user enters more data.

Let's start with a simple example. Imagine that you want to take the moving lines code (for simplicity's sake, we'll leave out the variable speeds for now), and, once every 1/2 second (or every 30 frames), you want to add another line to the mix. This means you need to add a new random x position to the pos array every 30 seconds. How can you add something new to an array?

If we were writing a list on a piece of paper, it's easy to imagine how we would add something to the "pos" list. If we had points 0-5 already and wanted to add a new point 6, we would just write 6 at the bottom of the list, and then write the new point next to it. In Processing, you might therefore guess that you can do something like this:

pos[6] = random(width);

But in Processing things work differently. To put it simply, when you initially make an array Processing always only gives you a piece of paper that is exactly as long as the list you said you wanted. If you said you wanted an array with 6 integers, then exactly 6 integers will fit on the list. If you try to put a 7th one on it, Processing will give you an error.

So how can we make lists longer? We will do this by creating a new list which contains all 7 elements. One way to do this would be like this:

// make a new array which is one longer than pos
float[] posnew = new float[pos.length+1];

// copy pos's data into posnew
for(int i = 0; i < pos.length; i++) {
   posnew[i] = pos[i];
}

// add a new data point to the end of posnew
posnew[posnew.length-1] = random(width);

// make pos store posnew's data
pos = posnew;

If that code gives you a little bit of a headache to understand, you'll be happy to hear that Processing gives us a shortcut that lets us avoid that whole thing: the function append. Append takes two arguments: an array, and something to add to it. Just as with the code above, it creates a new array that has the same data as the original array, plus the thing you wanted to add in.

We can now rewrite the lines code as follows:

float[] pos;

void setup() {
  // initialize the positions of the lines
  pos = new float[10];
  for (int i = 0; i < pos.length; i++) {
    pos[i] = random(width);
  }

  // set up the graphics
  size(150, 150);
  strokeWeight(4);
  colorMode(HSB);
}

void draw() {
  // once every 30 frames, add a new line
  if(frameCount%30 == 0) {
    pos = append(pos, random(width));
  }
  background(0);
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i]++;
    if(pos[i] > width) {
      pos[i] = 0;
    }
  }
}

Note that we did not just say append(pos, random(width)); we also assigned the value returned by append to pos. This is because append does not alter pos, instead, it creates a new array which is one longer, copies pos's values into it, and adds the new element specified in the function call, in this case random(width). If we want append to affect pos, we need to do that explicitly: pos = append(pos, random(width));.

Exercise

  1. Adapt the code developed in this section so that the speeds at which the lines move is variable. Each line should have both a position and a speed associated with it, so you will need to make the speed[] array longer every time the pos[] array gets longer .

Making arrays shorter

Just as you sometimes want to make arrays longer, it's also possible you'd like to make arrays shorter. Processing also provides you a shorthand for this case. The function shorten(arrayname) returns a new array which is the same as arrayname but with the last entry lopped off.

Say, for example, we have the moving lines code, but we'd like to delete one line every 30 frames instead of adding one. How would we do this? To start out, we'll simply do the same thing as in the previous code, just using shorten() instead of append(). That gives us this:

float[] pos;

void setup() {
  // initialize the positions of the lines
  pos = new float[10];
  for (int i = 0; i < pos.length; i++) {
    pos[i] = random(width);
  }

  // set up the graphics
  size(150, 150);
  strokeWeight(4);
  colorMode(HSB);
}

void draw() {
  // once every 30 frames, add a new line
  if(frameCount%30 == 0) {
    pos = shorten(pos);
  }
  background(0);
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i]++;
    if(pos[i] > width) {
      pos[i] = 0;
    }
  }
}

Note that, as is the case with append(), it is not enough to say shorten(pos). You also need to set pos to the result, i.e. pos = shorten(pos). This is because shorten(pos) makes a new array which is one smaller than pos, then copies everything from pos into that array. It does not, however, affect anything about pos, which still holds its prior list of numbers. If you want to change pos, you need to do that explicitly.

Now if you run the code above in Processing, you'll see that the lines disappear one by one until you don't see anything. But what happens then? The program crashes and Processing says "NegativeArraySizeException." What happened? The problem occurs on the line pos = shorten(pos);. Every time we call this code, pos is one shorter. But at a certain point, pos is an array of length 0, i.e. an empty list. When Processing tries to shorten the empty list, there's no way to do so. This is when the program crashes.

How do we avoid this? We need to check whether pos is empty before we try to shorten it. This means wrapping an if statement around our shorten() command:

if(pos.length > 0) {
  pos = shorten(pos);
}
This makes our final working code look like this:
float[] pos;

void setup() {
  // initialize the positions of the lines
  pos = new float[10];
  for (int i = 0; i < pos.length; i++) {
    pos[i] = random(width);
  }

  // set up the graphics
  size(150, 150);
  strokeWeight(4);
  colorMode(HSB);
}

void draw() {
  // once every 30 frames, add a new line
  if(frameCount%30 == 0) {
    if(pos.length > 0) {
      pos = shorten(pos);
    }
  }
  background(0);
  // color and draw each line in the array
  for (int i = 0; i < pos.length; i++) {
    stroke(i*10, 180, 255);
    line(pos[i], 0, pos[i], height);
    pos[i]++;
    if(pos[i] > width) {
      pos[i] = 0;
    }
  }
}

Exercise

  1. Create a program which creates a starry night at dawn. Initially, the program will draw 100 randomly located stars on a dark blue background. Every frame, the background brightness will become one lighter. Every 10 frames, one of the stars will disappear, until there are no stars left.

Using arrays to support interaction

One of the things that's wonderful about arrays is that they make it possible to make more complex interactions. Rather than simply responding to what is happening now, we can keep track of a history of interaction and build up a complex interaction over time.

For example, we can make a program that keeps track of what a user has typed. We'll define an array called characters that stores the character that the user typed in, then use the text() function in a for loop to draw the characters to the screen. That program would look like this:

// characters is used to store what the user typed in
char[] characters = { 'a', 'b', 'c'};
// remember whether the key was pressed on the last frame
boolean wasPressed = false;

void setup(){
  fill(0);
}

void draw(){
  background(255);
  // if a new key is pressed, add it to the characters array
  if(keyPressed && !wasPressed){
    characters = append(characters, key);
  }
  // draw all the characters that have been pressed to the screen
  for(int i = 0; i < characters.length; i++) {
    text(characters[i], i*width/characters.length, 20);
  }
  wasPressed = keyPressed;
}

Here, the interaction is stored because every time a new key is pressed, we use append to add a new character to the end of the array.

There's one thing that's a little funny about this code. You'll note that by saying char[] characters = { 'a', 'b', 'c'}; we initialize this array with 3 characters that weren't typed in by anybody. That's not so elegant; it would be nicer if the program only used characters that were actually typed in. That means that characters, to start out with, wouldn't be a list of 3 characters; it would be an empty list, i.e. one with 0 characters on it. How can we do this?

Our first attempt might look like this: char[] characters;; i.e. initialize it, but don't put anything in it. This won't work, though. The problem is that when you made the variable characters you told Processing it would be a list of characters, but you didn't yet tell Processing how long the list would be. Processing will therefore get confused when you try to access characters.length or when it tries to append to a list that doesn't have a defined length yet.

To avoid this problem, you can initialize characters[] to an empty list, i.e. a list of length 0. You can do this either by saying characters[] = new int[0]; (i.e., make characters be a new list of 0 ints), or you can use a special shorthand: characters[] = {};. Just as { 'a', 'b', 'c'} means "a list with 3 elements in it, i.e. the characters 'a', 'b', and 'c'", {} means "a list with no elements in it," i.e. the empty list.

So far we've saved one piece of information, character strokes. But just as is the case with any other array, we can store multiple pieces of data about interaction in multiple arrays. Let's imagine we want to draw flickering rectangles everywhere where the user has clicked. We'll need two arrays: one to track mouseX and one to track mouseY. Then, we can use append to add data to these arrays. The code might look like this:

// pointsX and pointsY store everywhere the user has clicked
int[] pointsX = {};
int[] pointsY = {};
boolean wasPressed = false;

void setup(){
  noStroke();
}

void draw(){
  background(0);

  // if the mouse was pressed, remember the point
  if(mousePressed && !wasPressed) {
    pointsX = append(pointsX,mouseX);
    pointsY = append(pointsY,mouseY);
  }

  // draw a randomly colored rectangle everywhere the
  // user has pressed
  for(int i = 0; i < pointsX.length; i++){
    fill(color(random(256),random(256),random(256)));
    rect(pointsX[i],pointsY[i],20,20);
  }
  wasPressed = mousePressed;
}

Exercise

  1. The following code will create a random character between a and z:
    char randChar = char(int('a') + round(random(26)));
    
    Using this code, write a program that draws a random character on the screen wherever the user clicks the mouse.
  2. After the character has been generated, have the characters fall down the screen, 1 pixel on every frame, until they land on the bottom.