1. Installing Processing
1.1. Learning Outcomes
Students will be able to:
-
Download and install Processing
-
Open a processing project folder
-
Execute a provided Processing project
1.3. Tutorial Video for Downloading and Installing Processing
How to download and install Processing on Windows 10 (recorded by a previous GGC student):
Note that sometimes the operating system’s search will not find the Processing app, since Processing’s "installation" does not register the app with the system. You will need to remember where the Processing app is to find and execute the app. Another way to start Processing is to open a Processing code file (see below).
1.4. Test Run the Example Project
After you’ve successfully downloaded and installed Processing following the video above, you can test whether the Processing has been installed properly by executing an example project.
Download the Square.zip and extract it into a folder called Square. Go into the folder and double-click on the file Square.pde. If Processing is installed properly, you should be able to open the file in Processing’s IDE (see the image below).

Click on the Run button to see the animation. You should see a green rectangle in the center of the display window, The rectangle will disappear with a mouse click and reappear with a click to any key on keyboard. Study the code and see whether you could understand it.
For Processing, the file name and the folder name must match. For this example, since the file name is Square.pde, the folder must be named Square. |
How to download and install Processing on Windows and create a very simple Processing program (recorded more recently by a professor):
2. Basics - Variables, Assignments, Expressions
2.1. Learning Outcomes
Students will be able to:
-
Students will be able to explain what variables are, why they are used, and how they are used in programming.
-
Students will be able to declare variables and initialize them with values.
-
Students will learn how to manipulate variables to calculate position and size circles/ellipses in processing.
2.2. Definition
A variable is a named storage location in computer memory that holds a value. In programming, it is important to create variable name meaningfully because that help us understand what each variable is used for and we can make our code easier to maintain. For example, if we are storing a person’s age, we might name the variable "personAge."
The folliwng is an example of how we could declare and use a variable.
A fast way to test the code: Download a blank project Blank.zip and extract it into a folder called Blank. Copy the code in the editor and run the the code. |
// Declare a variable named "personAge" for a person's age
int personAge;
// Assign a value 25 to the variable
personAge = 25;
// Print the value of the variable using "println()" function/method
println("The person's age is " + personAge);
2.3. Tutorial
We will use a fun example to introduce how to use variables in Processing to change the visual effect. It uses the sine math function to scale the size of circles smoothly. Enter the following code block by block into your code editor. Please read the comments embedded in the code, which are intended for teaching the concepts.
The following video will guide you through the tutorial:
//a comment about this program.
/**
* ThreeCirclesSine.
*
* Smoothly scaling size with the sin() function for three circles
*/
//these two lines declare two float variables: "diameter" and "angle"
float diameter; //diameter will store the size of the circle
float angle = 0; //angle will control the size of circles.
//setup() function is called at the beginning of the program
void setup() {
size(640, 360); //size() function creates a window of size 640 by 360 pixels.
//diameter variable is defined to be the height of the window minus 10 pixels. This represents the size of the circle to the drawn.
diameter = height - 10;
noStroke(); //noStroke() function does not create the outline of the circle
fill(255, 204, 0); //the circle sets the color to yellow.
}
/**
* draw() function gets executed called repeatedly to
* create the animation effect. Each time it get executed
* is like the Processing "paints a frame in a movie".
* The follwing draw() function draws three circles and
* updates their size based on the current value of the
* "angle" variable.
*/
void draw() {
background(0); //paint the black background
/**
* d1 is used to store the diameter of the first circle. It is
* calculated using the "sin()" function and the "angle" variable.
* The sin() funtion takes angle as a parameter and it returns/generates
* a value between -1 and 1. Then this value will be scaled by "diameter/2"
* to generate a value between "- diameter/2" and "diameter/2". Then, add
* "diameter/2" to generate a value between "0" and "diameter". Last, add
* "10" to generate a value between 10 and diamter + 10.
*/
float d1 = 10 + ((sin(angle) * diameter/2) + diameter/2 );
//d2 is calculated in a similar way to d1 but with a different angle value
float d2 = 10 + (sin(angle + PI/2) * diameter/2) + diameter/2;
//d3 is calculated in a similar way to d1 and d2 but with a different angle.
float d3 = 10 + (sin(angle + PI) * diameter/2) + diameter/2;
//ellipse() function draws each circle
ellipse(0, height/2, d1, d1); //circle 1
ellipse(width/2, height/2, d2, d2); //circle 2
ellipse(width, height/2, d3, d3); //circle 3
//angle variable is incremented by 0.02 to create a smooth animation effect.
angle += 0.02;
}
When you run the program, you will see three circles, one with center in the middle of the left edge, one with the center in the middle, and one with the center in the middle of the right edge of the window.

2.3.1. A complete program
/**
* ThreeCirclesSine.
*
* Smoothly scaling size with the sin() function for three circles
*/
float diameter;
float angle = 0;
void setup() {
size(640, 360);
diameter = height - 10;
noStroke();
fill(255, 204, 0);
}
void draw() {
background(0);
float d1 = 10 + (sin(angle) * diameter/2) + diameter/2;
float d2 = 10 + (sin(angle + PI/2) * diameter/2) + diameter/2;
float d3 = 10 + (sin(angle + PI) * diameter/2) + diameter/2;
ellipse(0, height/2, d1, d1);
ellipse(width/2, height/2, d2, d2);
ellipse(width, height/2, d3, d3);
angle += 0.02;
}
2.4. Exercise 1: Spiral Movement
-
Declare variables
-
Declare "diameter" with an initial value of 10 (type: float)
-
Declare "angle" with an initial value of 0 (type: float)
-
Declare "radius" with an initial value of 0 (type: float)
-
Declare "angleStep" with an initial value of 0.1 (type:float)
-
-
Set up the canvas - copy following code
void setup() {
size(640, 340);
diameter = 10;
noStroke();
fill(255, 204, 0);
}
-
Draw the circle in a spiral form (Please use the starter code below based on the following description inside of draw() function)
void draw() {
1. call background() function to set the background color to black. background() function takes 0 for black.
2. compute x and y coordinates of the point on the ellipse/circle using the width, height, radius, and angle variables.
by using the cos() and sin() functions. Copy two lines.
float x = width/2 + radius * cos(angle);
float y = height/2 + radius * sin(angle);
3. use the ellipse() function to draw a circle on the canvas.
ellipse() function takes four arguments: the x-coordinate of the center of the ellipse,
the y-coordinate of the center of the ellipse, the width of the ellipse, and the height of the ellipse.
4. angle variable is incremented by angleStep.
5. radius variable is incremented by 0.2. This will create the spiral movement.
}

2.4.1. Solution Code
float diameter;
float angle = 0;
float radius = 0;
float angleStep = 0.1;
void setup() {
size(640, 340);
diameter = 10;
noStroke();
fill(255, 204, 0);
}
void draw() {
background(0);
float x = width/2 + radius * cos(angle);
float y = height/2 + radius * sin(angle);
ellipse(x, y, diameter, diameter);
angle += angleStep;
radius += 0.2;
}
2.5. Exercise 2: Sprial Movement and Gradual Larger
Building on Exercise 1, declare a new float variable named gradualIncrement and initialize it with a value of 0.1. Inside the draw() function, add the line diameter += gradualIncrement to gradually increase the diameter of the circle by gradualIncrement on each iteration of the loop. Test your program to ensure that the circle grows gradually and moves in a spiral pattern.
float diameter;
float angle = 0;
float radius = 0;
float angleStep = 0.1;
void setup() {
size(640, 340);
diameter = 10;
noStroke();
fill(255, 204, 0);
}
void draw() {
background(0);
float x = width/2 + radius * cos(angle);
float y = height/2 + radius * sin(angle);
ellipse(x, y, diameter, diameter);
angle += angleStep;
radius += 0.2;
}

2.5.1. Solution Code
float diameter;
float angle = 0;
float radius = 0;
float angleStep = 0.1;
void setup() {
size(640, 340);
diameter = 10;
noStroke();
fill(255, 204, 0);
}
void draw() {
background(0);
float x = width/2 + radius * cos(angle);
float y = height/2 + radius * sin(angle);
ellipse(x, y, diameter, diameter);
angle += angleStep;
radius += 0.2;
diameter += 0.1; // Increase diameter gradually
}
3. Conditionals
3.1. Learning Outcomes
Students will be able to:
-
Understand basics about boolean expression
-
Apply boolean expression in if statement to make choices and solve simple problems
3.2. Basics About Boolean Expression
Boolean expressions use relational operators such as < (less than), < = (less than or equal), > (greater than), >= (greater than or equal), != (not equal) to compare variables against certain values.
For example, for a student to pass a class, the grade must be greater than or equal to 70; that is, we need to compare a student’s grade with 70. The boolean expression that represents this comparison is grade >= 70. A boolean expression will evaluate as either true or false and used in if statement so the code block belongs to that if statement will only be executed when the condition (boolean expression) is true.
For more detailed information about boolean expression and relational operators, please click here.
3.3. Tutorial 1
The code below uses an if statment to detect which key has been pressed and change the color of a rectangle accordingly, with R for red, G for green and B for blue. At the start, the rectangle is grey rectangle. Please read the comments embedded in the code, which are intended for teaching the concepts.
If you need help understand RGB color values, please visit https://processing.org/tutorials/color .
A fast way to test the code: Download a blank project Blank.zip and extract it into a folder called Blank. Copy the code in the editor and run the the code. |
//Use variables to store color code.
color defaultColor = color(125,125,125); // default color: grey
color RED = color(255, 0, 0);
color GREEN = color(0, 255, 0);
color YELLOW = color(255, 255, 0);
color BLUE = color(0, 0, 255);
color myColor;
void setup() {
// Initilize the window size.
size(900, 900);
}
void draw() {
//Use an if statement to determine the fill color
if (keyPressed) {
if (key == 'r' || key == 'R') {
myColor=RED;
}
else if(key == 'g' || key == 'G') {
myColor=GREEN;
}
else if(key == 'b' || key == 'B') {
myColor=BLUE;
}
else
myColor=defaultColor;
}
fill(myColor);
// draw a rectangle with size 200 by 200.
rect(350, 250, 200, 200); //rect(xLocation, yLocation, length, width)
}
3.4. Tutorial 2
In this tutorial, you will learn how to use an if statement to change the moving direction of an object with left and rigth arrow keys.
int recWidth = 50, recHeight=50; //rectangle size
int directionX = -1, directionY = 0; //moving direction: 0 - not moving, 1 - coordinate increases, -1 - corredinate decreases
float x=400, y=400; //position of upper left corner of rectangle
float speed=0.5; //change value each iteration for location
color myColor=color(255,0,0);
// ==============================================
void setup()
{
size(900, 900);
}
void draw()
{
background(0); //0 represent the black color
// Update position variables
x = x + speed*directionX;
y = y + speed*directionY;
fill(myColor);
rect(x, y, recWidth, recHeight);
}
// ==============================================
void keyPressed()
{
//Currently the rectangle can only move left or right
if (key == CODED)
{
if (keyCode == LEFT)
{
directionX=-1;
directionY=0;
}
else if (keyCode == RIGHT)
{
directionX=1;
directionY=0;
}
}
}
3.5. Tutorial 3
Now, run Tutorial 2 code again and do not change the moving direction of the square and observer what will happen when the rectange approaches the border. You will notice that the square will move outside of the window. Let’s add an if statment so it moves to the opposite direction when hitting the left or right border.
Since the size of the window is 900 by 900, the square will touch the right border when its x coordinate is 900 - recWidth. It will touch the left border when its x coordinate is 0. Let’s check the location using the following if statement. If the boolean expression is true, indicating the square is hitting the border, change the moving direction to the opposite.
if ( x >= 900-recWidth || x <= 0)
{
// code to change moving direction
}
Here’s the complete code for Tutorial 3.
int recWidth = 50, recHeight=50; //rectangle size
int directionX = -1, directionY = 0; //moving direction: 0 - not moving, 1 - coordinate increases, -1 - corredinate decreases
float x=400, y=400; //position of upper left corner of rectangle
float speed=0.5; //change value each iteration for location
color myColor=color(255,0,0);
// ==============================================
void setup()
{
size(900, 900);
}
void draw()
{
background(0); //0 represent the black color
// Update position variables
x = x + speed*directionX;
y = y + speed*directionY;
// check if square reaches left or right border
if ( x >= 900 - recWidth || x <= 0)
{
directionX = -directionX; // change direction
}
fill(myColor);
rect(x, y, recWidth, recHeight);
}
// ==============================================
void keyPressed()
{
//Currently the rectangle can only move left or right
if (key == CODED)
{
if (keyCode == LEFT)
{
directionX=-1;
directionY=0;
}
else if (keyCode == RIGHT)
{
directionX=1;
directionY=0;
}
}
}
3.6. Exercise 1
Add additional if statements so the square also moves up and down with border control.
3.6.2. Solution code
Here’s the solution code for Exercise 1
int recWidth = 50, recHeight=50; //rectangle size
int directionX = -1, directionY = 0; //moving direction: 0 - not moving, 1 - coordinate increases, -1 - corredinate decreases
float x=400, y=400; //position of upper left corner of rectangle
float speed=0.5; //change value each iteration for location
color myColor=color(255,0,0);
// ==============================================
void setup()
{
size(900, 900);
}
void draw()
{
background(0); //0 represent the black color
// Update position variables
x = x + speed*directionX;
y = y + speed*directionY;
// check if square reaches left or right border
if ( x >= 900 - recWidth || x <= 0)
{
directionX = -directionX; // change direction
}
if (y >= 900-recHeight || y <= 0)
{
directionY=-directionY;
}
fill(myColor);
rect(x, y, recWidth, recHeight);
}
// ==============================================
void keyPressed()
{
//Currently the rectangle can only move left or right
if (key == CODED)
{
if (keyCode == LEFT)
{
directionX=-1;
directionY=0;
}
else if (keyCode == RIGHT)
{
directionX=1;
directionY=0;
}
else if (keyCode == UP)
{
directionX=0;
directionY=-1;
}
else if (keyCode == DOWN)
{
directionX=0;
directionY=1;
}
}
}
3.7. Exercise 2
Allow a user to choose the shape they want by using the keyboard: 1 for circle, 2 for triangle and 3 for rectangle. Here’s the code to draw the three shapes. You can use them directly in the if statement. Feel free to change the numbers to understand how the shapes were created in Processing.
circle(400, 400, 200); // (centerX, centerY, radius)
triangle(300, 300, 600, 300, 450, 500);//(x1, y1, x2, y2, x3, y3)
rect(350, 350, 200, 300); // (x1, y1, width, height)
3.7.1. Starter code
color myColor=color(0, 0, 255);
void setup() {
// Initilize the window size.
size(900, 900);
//display text instructions
textSize(24); // set text size
fill(myColor); //set text color
text("Choose your shape using1, 2, or 3.", 40, 100);
text("1: Circle", 40, 130);
text("2: Triangle", 40, 160);
text("3: Rectangle", 40, 190);
}
void draw() {
fill(myColor);
//Use if statement to determine the shape (hint: check Tutorial 1)
}
3.7.2. Solution code
Here’s the solution code for Exercise 2.
color myColor=color(0, 0, 255);
void setup() {
// Initilize the window size.
size(900, 900);
//display text instructions
textSize(24); // set text size
fill(myColor); //set text color
text("Choose your shape using1, 2, or 3.", 40, 100);
text("1: Circle", 40, 130);
text("2: Triangle", 40, 160);
text("3: Rectangle", 40, 190);
}
void draw() {
fill(myColor);
//Use an if statement to determine the shape
if (keyPressed) {
if (key == '1' ) {
circle(400, 400, 200); // (centerX, centerY, radius)
} else if (key == '2') {
triangle(300, 300, 600, 300, 450, 500);//(x1, y1, x2, y2, x3, y3)
} else if (key == '3') {
rect(350, 350, 200, 300); // x1, y1, width, height
}
}
}
4. Loops
4.1. Learning Outcomes
Students will be able to:
-
predict the outcome of a loop
-
write a loop to solve a similar problem as shown in the tutorial
4.2. Tutorial 1
We are going to use the following example to understand what a loop is and how it works. The starter code can also be downloaded from Squares.zip. Open Squares.pde and you will see a code as follows:
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
rect(0, 0, 100, 100);
rect(100, 0, 100, 100);
rect(200, 0, 100, 100);
rect(300, 0, 100, 100);
rect(400, 0, 100, 100);
}
If you run the code, you will see a window as follows.

The code draws five squares using five lines of code. If we need to fill up the window with the same-sized squares, we will need five total rows. That is, we will need to draw 5 squares per row for five rows, that is, a total of 25 squares, which will require 25 lines of code.
If we change the square size from 100 x 100 to 10 x 10, to fill up a row, we will need to draw 500 / 10 = 50 squares. We will need to draw 50 rows to fill up the window. That is, we need to draw a total of 50 x 50 = 2500 squares. Using the same approach as in the starter code, we would need 2500 lines of code.
If the window size becomes 2000 x 2000 and the square size is 10 x 10, we will need to draw 40,000 squares. Using the same approach as in the starter code, we will need to use 40,000 lines of code. We can see that it would be a very tedious, boring and error-prone task.
The good news is that we have a new tool - loop - that will allow us to do things repetatively. Let’s get started. Let’s transform the starter code to one as shown below:
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
int x = 0;
rect(x, 0, 100, 100); //x is 0 here
x += 100;
rect(x, 0, 100, 100); //x is 100 here
x += 100;
rect(x, 0, 100, 100); //x is 200 here
x += 100;
rect(x, 0, 100, 100); //x is 300 here
x += 100;
rect(x, 0, 100, 100); //x is 400 here
x += 100;
}
If you run the code, you will see that it draws the same five squares. Let’s examine the above code. We introduced a variable x. It starts with 0. After the each square is drawn, its value is increased by 100. We can see x takes on the values from 0, 100, 200, 300, to 400, the same as the x-coornates of the squares in the starter code, thus drawing the same squares.
You might ask why we bother to use a variable. That’s a good question! With a variable introduced, we can see that something interesting has happened. We can see that the following code is repeated five times in the program.
rect(x, 0, 100, 100);
x += 100;
Now it is a good time to introduce loop. We will introduce a while loop (also called a while statement) as shown below. A while loop is very similar to an if statement. Just like an if statement, the boolean expression is first evaluated, if it is true, the statements below will be executed. In the example code below, a 100 x 100 square is draw and x is incremented by 100. An if statement will be done, but a while statement will go back to check the boolean expression again. If it is still true, it will execute the statements below again. This process will repeat until the boolean expression becomes false.
while (__a boolean expression___) {
rect(x, 0, 100, 100);
x += 100;
}
Now what the boolean expression should be in order to draw the five squares?
Let’s first go to Java Visualizer and copy the following following code into the main method and visualize the execution and observe how x's value changes.
int x = 0;
while (x < 1000) {
System.out.println(x);
x += 100;
}
Ok. I think by now you have figured out that the boolean expression for drawing five squares should be x ⇐ 400 or x < 500. They will have the same effect for this program, since x is incremented by 100 each iteration of the loop.
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
int x = 0;
while (x < 500) {
rect(x, 0, 100, 100);
x += 100;
}
}
Java and most programming languages offer another type of loop, called for loop. It does the same thing as a while loop but has a different format. The following is an equivalent for loop as the while loop in step 2. Pay attention to where x is intialized to 0 and where x is incremented by 100 are in the for loop.
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
for (int x = 0; x < 500; x += 100) {
rect(x, 0, 100, 100);
}
}
We can see the for loop is more compact.
You can stop here, but if you are curious about how to fill out the whole window using the squares, you can read on.
For the remainder of Tutorial 1, we will use for loop. Let’s add another variable y and initialize y to 0. After drawing a row of squares, we will increase y by 100.
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
int y = 0;
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100); // y is 0 here
}
y += 100;
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100); // y is 100 here
}
y += 100;
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100); // y is 200 here
}
y += 100;
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100); // y is 300 here
}
y += 100;
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100); // y is 400 here
}
y += 100;
}
If you run the code above, you will see that the window is covered with square as follows:

Again we can see that the following code is executed repetatively:
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100);
}
y += 100;
Treating the above block code as a unit and using the same approach as how we have converted the step-1 code to the step-2 code, we can use another loop to make this code execute five times and draw the five rows:
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
int y = 0;
while (y < 500) {
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100);
}
y += 100;
}
}
Converting the while loop in step-5 code to a for loop, we have the following code that is more compact:
public void setup() {
size(500, 500); //window size 500 x 500
background(100); //a gray color
fill(100, 130, 200); //a blue color
for (int y = 0; y < 500; y += 100) {
for (int x = 0; x < 500; x += 100) {
rect(x, y, 100, 100);
}
}
}
4.3. Exercise 1
Change the code further so that it uses 10x10 squares to cover the first row or the whole window.
4.4. Tutorial 2
The following code plots two sine waves.

You may notice a similar phenomenon inside the drawOneWave method to that in Tutorial 1 - Step 1, where a segment of code is repeated over and over again, in this case, 20 times. This indicates that you can use a loop to remove the duplicated code.
4.4.1. Starter Code
/*Initialize variables that will be used later*/
int xspacing = 32; // How far apart should each horizontal location be spaced
float amplitude = 75.0; // Height of wave
float period = 500.0; // How many pixels before the wave repeats
int w; // Width of entire wave
float dx; // Value for incrementing X, a function of period and xspacing
int numPoints; // # of points to draw for a wave
void setup() {
size(640, 360);
w = width+16;
dx = (TWO_PI / period) * xspacing; // TWO_PI is 2 * PI
numPoints = w/xspacing;
}
void draw() {
background(0);
noStroke();
fill(255);
drawOneWave(0); // draw one sine wave
drawOneWave(2); // draw another sine wave
}
/*
* This method draws a sine wave.
*/
void drawOneWave(float angle) {
float x, y;
float plot_x, plot_y;
int i = 0;
x = angle + i * dx; //repeat 20 times
y = sin(x)*amplitude;
plot_x = i * xspacing;
plot_y = height/2+y;
ellipse(plot_x, plot_y, 16, 16);
i++;
x = angle + i * dx;
y = sin(x)*amplitude;
plot_x = i * xspacing;
plot_y = height/2+y;
ellipse(plot_x, plot_y, 16, 16);
i++;
...
}
The code that repeats in the code above is the following:
x = angle + i * dx;
y = sin(x)*amplitude;
plot_x = i * xspacing;
plot_y = height/2+y;
ellipse(plot_x, plot_y, 16, 16);
i++;
Using the same approach as in the tutorial one, the drawOneWave method can be transformed to a compact while loop.
void drawOneWave(float angle) {
float x, y;
float plot_x, plot_y;
int i = 0;
while (__boolean expression__) { //What the expression should it be for numPoints iterations?
x = angle + i * dx;
y = sin(x)*amplitude;
plot_x = i * xspacing;
plot_y = height/2+y;
ellipse(plot_x, plot_y, 16, 16);
i++;
}
}
The boolean expression should be: i < numPoints.
We can convert the whole loop to a more compact for loop: .An Equivalent For Loop
for (int i = 0; i < numPoints; i++) {
x = angle + i * dx;
y = sin(x)*amplitude;
plot_x = i * xspacing;
plot_y = height/2+y;
ellipse(plot_x, plot_y, 16, 16);
}
4.4.2. Solution Code
You can see that in the solution below, an eight-line for loop is used to replace the 20 repetitions of a code segment.
/*Initialize variables that will be used later*/
int xspacing = 32; // How far apart should each horizontal location be spaced
float amplitude = 75.0; // Height of wave
float period = 500.0; // How many pixels before the wave repeats
int w; // Width of entire wave
float dx; // Value for incrementing X, a function of period and xspacing
int numPoints; // # of points to draw for a wave
void setup() {
size(640, 360);
w = width+16;
dx = (TWO_PI / period) * xspacing; // TWO_PI is 2 * PI
numPoints = w/xspacing;
}
void draw() {
background(0);
noStroke();
fill(255);
drawOneWave(0); // draw one sine wave
drawOneWave(2); // draw another sine wave
}
/*
* This method draws a sine wave.
*/
void drawOneWave(float angle) {
float x, y;
float plot_x, plot_y;
for (int i = 0; i < numPoints; i++) {
// For every x value, calculate a y value with sine function
x = angle + i * dx;
y = sin(x) * amplitude;
plot_x = i * xspacing;
plot_y = height/2 + y;
ellipse(plot_x, plot_y, 16, 16);
}
}
4.4.3. Animate the Wave
In an further update to the solution code, we will draw one wave but it is animated.
Add a variable angle at the top of the program:
float angle = 0; // Angle of the first point of a wave
void draw() {
background(0);
noStroke();
fill(255);
angle += 0.02;
drawOneWave(angle); // draw one sine wave
}
/*Initialize variables that will be used later*/
int xspacing = 32; // How far apart should each horizontal location be spaced
float amplitude = 75.0; // Height of wave
float period = 500.0; // How many pixels before the wave repeats
int w; // Width of entire wave
float dx; // Value for incrementing X, a function of period and xspacing
int numPoints; // # of points to draw for a wave
float angle = 0; // Angle of the first point of a wave
void setup() {
size(640, 360);
w = width+16;
dx = (TWO_PI / period) * xspacing; // TWO_PI is 2 * PI
numPoints = w/xspacing;
}
void draw() {
background(0);
noStroke();
fill(255);
//drawOneWave(0); // draw one sine wave
//drawOneWave(2); // draw another sine wave
angle += 0.02;
drawOneWave(angle); // draw one sine wave
}
/*
* This method draws a sine wave.
*/
void drawOneWave(float angle) {
float x, y;
float plot_x, plot_y;
for (int i = 0; i < numPoints; i++) {
// For every x value, calculate a y value with sine function
x = angle + i * dx;
y = sin(x) * amplitude;
plot_x = i * xspacing;
plot_y = height/2 + y;
ellipse(plot_x, plot_y, 16, 16);
}
}
The following shows how the animation should look like:

4.5. Exercise 2: Draw Lots of Rectangles
In this exercise, you will first study the starter code that draws the rectangles as follows.

You will figure out the pattern of the locations of the rectangles and convert it into a loop based solution.
4.5.1. Starter code
//starter
// Runs when the program is first launched
public void setup() {
// Initilize the window size in setup().
size(1000, 1000);
// Disable the layer.
noStroke();
// Set background color
background(118, 128, 228);
// Draw pipes at the upper left corner
fill(58, 58, 58);
rect(150, 150, 25, 200); //x, y, width, height
rect(200, 150, 25, 200); //x, y, width, height
rect(250, 150, 25, 200); //x, y, width, height
rect(300, 150, 25, 200); //x, y, width, height
rect(350, 150, 25, 200); //x, y, width, height
// Draw pipes at the upper right corner
rect(1000-150-25, 150, 25, 200); //x, y, width, height
rect(1000-200-25, 150, 25, 200); //x, y, width, height
rect(1000-250-25, 150, 25, 200); //x, y, width, height
rect(1000-300-25, 150, 25, 200); //x, y, width, height
rect(1000-350-25, 150, 25, 200); //x, y, width, height
// Draw pipes at the lower left corner
rect(150, 1000-150-200, 25, 200); //x, y, width, height
rect(200, 1000-150-200, 25, 200); //x, y, width, height
rect(250, 1000-150-200, 25, 200); //x, y, width, height
rect(300, 1000-150-200, 25, 200); //x, y, width, height
rect(350, 1000-150-200, 25, 200); //x, y, width, height
// Draw pipes at the lower right corner
rect(1000-150-25, 1000-150-200, 25, 200); //x, y, width, height
rect(1000-200-25, 1000-150-200, 25, 200); //x, y, width, height
rect(1000-250-25, 1000-150-200, 25, 200); //x, y, width, height
rect(1000-300-25, 1000-150-200, 25, 200); //x, y, width, height
rect(1000-350-25, 1000-150-200, 25, 200); //x, y, width, height
}
4.5.2. Solution Code
//solution
// Runs when the program is first launched
public void setup() {
// Initilize the window size in setup().
size(1000, 1000);
// Disable the layer.
noStroke();
// Set background color
background(118, 128, 228);
// Draw rectangles
fill(58, 58, 58);
int margin = 150;
int w = 25;
int h = 200;
// Draw pipes at the upper left corner
int x = margin;
int y = margin;
for (int i = 0; i < 5; i++) {
rect(x, y, w, h); //x, y, width, height
System.out.printf("%d %d %d %d\n", x, y, w, h);
x += 50;
}
System.out.println();
// Draw pipes at the upper right corner
x = 1000 - margin - w;
y = margin;
for (int i = 0; i < 5; i++) {
rect(x, y, w, h); //x, y, width, height
System.out.printf("%d %d %d %d\n", x, y, w, h);
x -= 50;
}
System.out.println();
// Draw pipes at the lower left corner
x = margin;
y = 1000 - margin - h;
for (int i = 0; i < 5; i++) {
rect(x, y, w, h); //x, y, width, height
System.out.printf("%d %d %d %d\n", x, y, w, h);
x += 50;
}
System.out.println();
// Draw pipes at the lower right corner
x = 1000 - margin - w;
y = 1000 - margin - h;
for (int i = 0; i < 5; i++) {
rect(x, y, w, h); //x, y, width, height
System.out.printf("%d %d %d %d\n", x, y, w, h);
x -= 50;
}
System.out.println();
}
4.6. Exercise 3: Show Gray Scale Value
In this exercise, you will write a program that draws a gradual change of color from black to white and shows the gray scale value of the color where the mouse points to. See the following image for a reference. Note that the text color should be white when the mouse points to anywhere on the left half of the window and black when the mouse points to anywhere on the right half of the window.

4.6.1. Solution Code
int red = color(255, 0, 0);
void setup() {
size(640, 360);
noStroke();
textSize(30);
}
public void draw() {
background(255);
int numberOfColors = 64;
int w = width / numberOfColors;
int h = height;
System.out.println(w + " " + h);
for (int x = 0; x < width; x += w) {
int gray = (int) ((float) x/width * 256);
fill(gray);
//System.out.println(gray);
rect(x, 0, w, h);
}
fill(red);
text("Gray scale value", 400, 30);
int currentGray = (int) ((float) mouseX/width * 256);
System.out.println(currentGray);
int textColor;
if (currentGray <= 255/2) {
textColor = 255;
} else {
textColor = 0;
}
fill(textColor);
if (mouseX <= width - 40) {
text(currentGray, mouseX, mouseY);
} else {
text(currentGray, mouseX-40, mouseY);
}
}
5. Methods
5.1. Learning Outcomes
Students will be able to:
-
Understand the basics of Method
-
Apply method defined by others
-
Create a method
5.2. Basic Concept
Simply speaking, we create a method by putting codes that focus on acehieving one specific task into one block and give this block a name, referred to as method name. Later on, the same code in places we need it without having to re-write it. (Over-simplified)
A method always has a method header and a method body. Once a method has been created, it needs to be invoked when you need to use it. Tutorial 1 will show you examples of defining a method and invoking methods.
5.3. Tutorial 1
Run Tutorial 1 code below in Processing, and draw an image by moving your mouse. The size of the circle is determined by the speed of your mouse movements.
In this program, a method variableEllipse() was created. The method header is:
void variableEllipse(int x, int y, int px, int py)
void means this method will not return any data. variableEllipse is the method name. x, y, px, py are the parameters with integer data type.
This method is invoked in draw() method.
Take a look at the method body of variableEllipse: It invokes abs() method, stroke() method and ellipse() method. All these three methods are already defined in the Processing library and we just need to invoke them when needed.
A fast way to test the code: Download a blank project Blank.zip and extract it into a folder called Blank. Copy the code in the editor and run the the code. |
/**
* Move the cursor to create image
*that responds to the speed of the mouse.
*/
void setup() {
size(880, 600);
background(102);
}
void draw() {
// Call the variableEllipse() method and send the
// parameters for the current mouse position mouseX and mouseY
// and the previous mouse position pmouseX and pmouseY
variableEllipse(mouseX, mouseY, pmouseX, pmouseY);
}
// The method variableEllipse() calculates the speed of the mouse
// and draws a small ellipse if the mouse is moving slowly
// and draws a large ellipse if the mouse is moving quickly
void variableEllipse(int x, int y, int px, int py) {
// calculate the speed based on current mousePosition and previous mouse position
float speed = abs(x-px) + abs(y-py);
stroke(speed);
ellipse(x, y, speed, speed);
}
The code was provided by Processing
5.4. Exercise 1
Look at the starter code provide below. Pay attention to the parameters of polygon() method. Invoke the method three times to create the three shapes similar to the ones shown in the picture.

5.4.1. Starter code
color myColor=color(255, 255,0);
void setup() {
size(800, 600);
}
void draw() {
background(200, 200, 200);
fill(myColor);
// invoke polygon() three times to create three shapes in a row, the y location is 150, the x location is up to you but please spread out the three shapes evenly.
}
void polygon(float x, float y, float radius, int npoints) {
float angle = TWO_PI / npoints;
beginShape();
for (float a = 0; a < TWO_PI; a += angle) {
float sx = x + cos(a) * radius;
float sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
5.4.2. Solution code
color myColor=color(255, 255,0);
void setup() {
size(800, 600);
}
void draw() {
background(200, 200, 200);
fill(myColor);
// invoke polygon() three times to create three shapes
polygon(100, 150, 82, 5);
polygon(350, 150, 80, 6);
polygon(600, 150, 70, 8);
}
void polygon(float x, float y, float radius, int npoints) {
float angle = TWO_PI / npoints;
beginShape();
for (float a = 0; a < TWO_PI; a += angle) {
float sx = x + cos(a) * radius;
float sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
6. Arrays
6.1. Learning Outcomes
Students will be able to:
-
declare and initialize arrays
-
manipulate array elements using Processing in Java.
6.2. What is Arrays in Java?
An array in Java is a way to store a collection of elements of the same type. It is like a container that can hold multiple items of the same kind, such as a collection of numbers, letters, or even objects.
For example, imaging you are collecting the scores of games. Instead of creating separate variables for each score, you can use an array to store all the scores in one place. Then, you can access and manipulate the scores as needed.
Here’s a example of how to declare an array of integers in Java:
//this creates an array called scores that can hold 5 integers.
int[] scores = new int[5];
//Initialize the array with specific values
int[] scores = {10,9,8,7,6,5,4,3,2,1,0};
To access an element in the array, you use the index of the element, which starts from 0. The following code access the first element in the array and then assign it to a new value.
int firstScore = scores[0];
scores[0] = 100; //to change an element in the array.
6.3. Tutorial 1
6.3.1. Starter Code - step 1
This program creates an array of circles and randomly sets their colors using an array of colors.
int numCircles = 10; //variable determins the number of circles in the array
//circleX, circleY, circleSize, and circleColor arrays store the x-position, y-position, size, and color of each circle.
int[] circleX = new int[numCircles];
int[] circleY = new int[numCircles];
int[] circleSize = new int[numCircles];
color[] circleColor = new color[numCircles];
//colors array stores three different colors that will be randomly assigned to each circle.
color[] colors = {color(255, 0, 0), color(0, 255, 0), color(0, 0, 255)};
6.3.2. Starter Code - step 2
// setup() function has a for loop iterates through each circle and sets its x-position, y-position, size and color using random values from the arrays
void setup() {
size(400, 400);
for (int i = 0; i < numCircles; i++) {
circleX[i] = int(random(width));
circleY[i] = int(random(height));
circleSize[i] = int(random(20, 50));
circleColor[i] = colors[int(random(3))];
}
}
6.3.3. Starter Code - step 3
//draw() function has a for loop iterates through each circle and draws it with the assigned color and size.
void draw() {
background(255);
for (int i = 0; i < numCircles; i++) {
fill(circleColor[i]);
ellipse(circleX[i], circleY[i], circleSize[i], circleSize[i]);
}
}

6.4. Tutorial 2 Preparation
We will visualize a set of data values over a map using the following code in Tutorial 2. To prepare for that, we first need to display the map. The following code display the map image. You can also download the code MapRender.zip, which contains map.png.
PImage mapImage;
/*
* The setup() method executes once after click Run button
*/
void setup( ) {
size(640, 400);
mapImage = loadImage("map.png"); //load an image from the data folder
}
void draw( ) {
background(255);
image(mapImage, 0, 0);
}
The program should display the following:
6.5. Tutorial 2
We will visualize a set of data values over a map using the following code. We will load in the position data of the map so that we can use them to determine where to render our visualizeion against the map.
You can also download the code MapVisualization.zip, which contains the image and data files map.png, locations.tsv, and random.tsv.
PImage mapImage;Table locationTable;
Table locationTable;
int rowCount;
void setup( ) {
size(640, 400);
mapImage = loadImage("map.png");
// Create a Table object with the provided coordinates data file.
locationTable = loadTable("locations.tsv");
// The row count will be used a lot, so store it globally.
rowCount = locationTable.getRowCount();
}
void draw( ) {
background(255);
image(mapImage, 0, 0);
// Drawing attributes for the ellipses.
smooth( );
fill(192, 0, 0);
noStroke( );
// Loop through the rows of the locations file and draw the points.
for (int row = 0; row < rowCount; row++) {
float x = locationTable.getFloat(row, 1); // column 1
float y = locationTable.getFloat(row, 2); // column 2
ellipse(x, y, 9, 9);
}
}
The program should display the following:
6.6. Exercise 1
How can we use arrays in Processing to create a Dippin' Dots style rainbow ice cream that fills a cup?
-
Open the Processing software and create a new sketch by selecting "File" > "New" from the menu bar.
-
In the new sketch window, copy and paste the following code to create a program that generates a Dippin' Dots style rainbow ice cream:
6.6.1. Starter code
int numCircles = 50;
int[] circleX = new int[numCircles];
int[] circleY = new int[numCircles];
int[] circleSize = new int[numCircles];
color[] circleColor = new color[numCircles];
void setup() {
size(400, 400);
smooth();
noStroke();
for (int i = 0; i < numCircles; i++) {
float t = random(0, TWO_PI);
float r = random(0, 100);
float x = r * cos(t) + width / 2;
float y = r * sin(t) + height / 2 + 50;
circleX[i] = int(x);
circleY[i] = int(y);
circleSize[i] = int(random(5, 15));
circleColor[i] = color(random(255), random(255), random(255), 200);
}
}
void draw() {
background(255);
for (int i = 0; i < numCircles; i++) {
fill(circleColor[i]);
ellipse(circleX[i], circleY[i], circleSize[i], circleSize[i]);
}
noLoop();
}
-
Save the sketch by selecting "File" > "Save" from the menu bar, and give it a name such as "DippinDotsIceCream".
-
Run the program by clicking on the "Play" button in the upper-left corner of the Processing window. You should see a window with circles of different colors arranged in a circular pattern (see the image below).
-
To modify the program to create a Dippin' Dots style rainbow ice cream that fills a cup, do the following:
- First increase the numCircles variable to 200 to create more circles and make the ice cream more dense.
- Modify the circleSize array to create smaller circles with sizes between 3 and 7.
Modify the r variable to create a smaller radius, making the circles more tightly packed together. For example, you can change 100 to 50. When you run the code, you should see an image as follows:
-
Add vertex commands to create a cup shape using the beginShape() and endShape() functions. Add the following vertex commands to create a simple cup shape in the draw function right after the for loop:
beginShape(); vertex(80, height - 20); vertex(320, height - 20); vertex(310, height - 10); vertex(90, height - 10); endShape(CLOSE);
When you play the program, you may not see anything. It is due to no stroke color for the shape. Add the following before the proceeding code for drawing the shape (but after the for loop):
fill(255, 170, 0); stroke(255, 170, 0); strokeWeight(2);
When you run the code, you should see the following:
-
Modify the draw() function as follows:
- Animate the ice cream by moving each circle down by a random amount int(random(1, 3)) each frame until they reach the bottom of the cup.
- Add an if statement to check if each circle has reached the bottom of the cup, and if so, reset its position to a random y-coordinate at the top of the cup.
Your for loop should look like the following:
for (int i = 0; i < numCircles; i++) { //add a small random number to y (i.e. going down a little) circleY[i] += int(random(1, 3)); //if reach bottom, reset the y to a negative value (i.e. above the top of the window) if (circleY[i] > height - 20) { circleY[i] = int(random(-50, -10)); } fill(circleColor[i]); ellipse(circleX[i], circleY[i], circleSize[i], circleSize[i]); }
-
Finally, remove the noLoop() function from the draw() function to allow the animation to run indefinitely. However, when you run the code, you will see that small circles of different colors falling down like raindrops. However, all the small circles will have a orange border. Add noStroke(); right above the for loop that draws the circles to remove the orange stroke.
-
Save and run the program to see a colorful icecream ball falling into the cup. After it is almost gone, another one will appear.
6.6.2. Solution Code
int numCircles = 200;
int[] circleX = new int[numCircles];
int[] circleY = new int[numCircles];
int[] circleSize = new int[numCircles];
color[] circleColor = new color[numCircles];
void setup() {
size(400, 400);
smooth();
noStroke();
for (int i = 0; i < numCircles; i++) {
float t = random(0, TWO_PI);
float r = random(0, 100);
float x = r * cos(t) + width / 2;
float y = r * sin(t) + height / 2 + 50;
circleX[i] = int(x);
circleY[i] = int(y);
circleSize[i] = int(random(3, 7));
circleColor[i] = color(random(255), random(255), random(255), 200);
}
}
void draw() {
background(255);
fill(255, 170, 0);
stroke(255, 170, 0);
strokeWeight(2);
beginShape();
vertex(80, height - 20);
vertex(320, height - 20);
vertex(310, height - 10);
vertex(90, height - 10);
endShape(CLOSE);
noStroke();
for (int i = 0; i < numCircles; i++) {
circleY[i] += int(random(1, 3));
if (circleY[i] > height - 20) {
circleY[i] = int(random(-50, -10));
}
fill(circleColor[i]);
ellipse(circleX[i], circleY[i], circleSize[i], circleSize[i]);
}
}
6.7. Exercise 2
Create an array called xPositions that stores 10 integer values between 0 and the width of the screen. Use a for loop to draw 10 circles with random y positions and a fixed size at each x position in the array.
6.8. Exercise 3
Create an array called colors that stores 5 color values of your choice. Use a for loop to draw 5 rectangles of equal size 40 x 40 on the diagonal of a window 200 x 200 with each being filled with a different color from the colors array.
6.8.1. Solution Code
color[] colors = {color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(255, 255, 0), color(255, 0, 255)};
void setup()
{
size(200, 200);
int rectSize = 40;
for (int i = 0; i < colors.length; i++) {
fill(colors[i]);
rect(i * rectSize, i * rectSize, rectSize, rectSize);
}
}
6.9. Exercise 4
Create an array called yPositions that stores 50 integer values between 0 and the height of the screen, evenly distributed. Use a for loop to draw 50 lines of varying lengths with a fixed x position (the middle of the window) and a y position determined by each value in the yPositions array. The length of the line should be a random value between 10 and 50.
6.9.1. Solution Code
int[] yPositions = new int[50];
void setup() {
size(300, 300);
for (int i = 0; i < yPositions.length; i++) {
yPositions[i] = i * height / yPositions.length;
}
int x = width / 2;
for (int i = 0; i < yPositions.length; i++) {
line(x, yPositions[i], x + random(10, 50), yPositions[i]);
}
}
6.10. Exercise 5
Create an array called textStrings that stores 4 string values of your choice. Use a for loop to draw 4 text strings, each string being centered horizontally and spaced vertically with the height of the screen divided by the number of elements in the textStrings array.
6.10.1. Solution Code
String[] textStrings = {"Hello", "World", "Processing", "Java"};
void setup() {
size(300, 300);
textSize(32);
textAlign(CENTER, CENTER);
for (int i = 0; i < textStrings.length; i++) {
text(textStrings[i], width / 2, i * height / textStrings.length + height / (textStrings.length * 2));
}
}
7. Class and Object
7.1. Learning Outcomes
Students will be able to:
-
Understand the class definition structure
-
Understand how to creaete objects
7.2. Tutorial 1
We are going to use the following example to understand what class is, how to create objects from a class, and the advantages of using object-oriented programming. Download the oo_ex1_starter.zip and extract it into a folder called oo_ex1_starter. Read and understand this starter code.
7.2.1. Starter Code
// Arrays to store attributes of multiple balls
int num = 5; //# of balls
float[] x = new float[num]; //x coordinates
float[] y = new float[num]; //y coordinates
float[] speedX = new float[num]; //speeds along x axis
float[] speedY = new float[num]; //speeds along y axis
float[] diameter = new float[num]; //diameters
/**
* setup method - called once at the start of the program
*
* Initialize the attributes of balls
*/
void setup() {
size(800, 600); //window size
for (int i = 0; i < num; i++) {
x[i] = random(width); //set to a random value in [0, width)
y[i] = random(height); //set to a random value in [0, height)
diameter[i] = random(20, 50); //set to a random value in [20, 50)
speedX[i] = random(1, 3); //set to a random value in [1, 3)
speedY[i] = random(1, 3); //set to a random value in [1, 3)
}
}
/**
* draw method - by default, called 60 times per second.
*
* Move and display each ball
*/
void draw() {
background(255);
for (int i = 0; i < num; i++) {
move(i);
display(i);
}
}
/**
* Move the ball with index i
*/
void move(int i) {
x[i] += speedX[i]; //x coordinated modified by speed along x axis
y[i] += speedY[i]; //y coordinated modified by speed along y axis
// Check for collision with the screen boundaries
if (x[i] <= 0 || x[i] >= width) { //if goes to out of the window along x axis
speedX[i] *= -1; //reverse speed direction along x axis
}
if (y[i] <= 0 || y[i] >= height) { //if goes to out of the window along y axis
speedY[i] *= -1; //reverse speed direction along y axis
}
}
/**
* Display the ball with index i
*/
void display(int i) {
ellipse(x[i], y[i], diameter[i], diameter[i]); //draw a circle
}
If you run the code, you will see a window with five balls moving around. When each ball hits a boundary, it reverses course.
You should be able to see that each ball has five attributes, x coordinate, y coordinate, diameter, speed along the x axis, and speed along the y axis. The starter code uses five arrays to store the five attributes for all the balls. If you need to extend the program so that each ball has more attributes, such as color, texture, weight, acceleration, etc., you will need to create more arranges to store these attributes and it could become cumbersome.
7.2.2. Transformation to Object-Oriented Programming
We will learn a new program structure that allows a program to store all the attributes for a ball in "one place" or an object. A Java class is the definition of what attributes will be stored in the object and what "actions" the object can take.
Create another folder called oo_ex1_solution and a subfolder called Balls under it. In the subfolder, create the following two files: Ball.pde and Balls.pde.
Ball.pde is the class definition, a template for Ball objects. It contains the specification of the five attributes, a constructor method (the same name as the class name), two instance methods, move and display, that a Ball object can call.
// Ball class to represent a moving ball
class Ball {
float x, y; // Position of the ball
float speedX, speedY; // Speed of the ball
float diameter; // Diameter of the ball
//Constructor method that create a ball with the
//specified position and diameter
Ball(float x, float y, float diameter) {
this.x = x;
this.y = y;
this.diameter = diameter;
this.speedX = random(1, 3); // initial X speed set to a random value in [1, 3)
this.speedY = random(1, 3); // initial Y speed set to a random value in [1, 3)
}
// Move the ball
void move() {
x += speedX;
y += speedY;
// Check for collision with the screen boundaries
if (x <= 0 || x >= width) {
speedX *= -1;
}
if (y <= 0 || y >= height) {
speedY *= -1;
}
}
// Display the ball
void display() {
ellipse(x, y, diameter, diameter);
}
}
You can see that the logic for moving a ball and display a ball is the same as the starter code. How the attributes are initialized are also similarly done as the starter code. However, with a class definition, the main program Balls.pde becomes very streamlined. We only need one array to store the information for all the Ball objects, instead one array for each attribute.
// Array to store multiple balls
int num = 5;
Ball[] balls = new Ball[num];
void setup() {
size(800, 600);
for (int i = 0; i < balls.length; i++) {
float x = random(width);
float y = random(height);
float diameter = random(20, 50);
balls[i] = new Ball(x, y, diameter); //Create a Ball object and save it in the array
}
}
void draw() {
background(255);
for (int i = 0; i < balls.length; i++) {
balls[i].move();
balls[i].display();
}
}
7.3. Exercise 1
Convert the following code into an object-oriented solution. Define a class for Bird that has six attributes, a constructor method, update method, and display method. Update the main program Birds.pde so that it uses one array to store all the bird information.
int num = 10; //# of birds
float[] x = new float[num]; //x coordinates
float[] y = new float[num]; //y coordinates
float[] speedX = new float[num]; //speeds along x axis
float[] speedY = new float[num]; //speeds along y axis
float[] wingSpan = new float[num]; //Widths of the bird's wings
float[] wingPosition = new float[num]; //Position of the wings (to simulate flapping)
void setup() {
size(800, 600);
for (int i = 0; i < num; i++) {
x[i] = random(width/2);
y[i] = random(height);
wingSpan[i] = 30; // Initial wing position
speedX[i] = 2; // Constant horizontal speed
speedY[i] = 0; // No vertical speed
wingPosition[i] = 0; // Initial wing position
}
}
void draw() {
background(135, 206, 250); // Sky blue background
for (int i=0; i < num; i++) {
update(i);
display(i);
}
}
void update(int i) {
x[i] += speedX[i];
y[i] += speedY[i];
// Check for collision with the screen boundaries
if (x[i] <= 0 || x[i] >= width) {
speedX[i] *= -1;
}
if (y[i] <= 0 || y[i] >= height) {
speedY[i] *= -1;
}
// Simulate wing flapping
wingPosition[i] = sin(radians(frameCount * 5)) * 20; // Flap the wings up and down
}
void display(int i) {
fill(255, 200, 0); // Yellow color
ellipse(x[i], y[i], 30, 20);
// Draw wings
fill(255); // White color
pushMatrix();
translate(x[i], y[i]);
rotate(radians(wingPosition[i]));
triangle(0, 0, -wingSpan[i] / 2, 15, -wingSpan[i] / 2, -15);
triangle(0, 0, wingSpan[i] / 2, 15, wingSpan[i] / 2, -15);
popMatrix();
}
7.3.1. Solution code
// Bird class to represent a flying bird
class Bird {
float x, y; // Position of the bird
float speedX, speedY; // Speed of the bird
float wingSpan; // Width of the bird's wings
float wingPosition; // Position of the wings (to simulate flapping)
Bird(float x, float y, float wingSpan) {
this.x = x;
this.y = y;
this.wingSpan = wingSpan;
this.speedX = 2; // Constant horizontal speed
this.speedY = 0; // The bird starts without vertical speed
this.wingPosition = 0; // Initial wing position
}
// Update the bird's position and wing flapping
void update() {
x += speedX;
y += speedY;
// Check for collision with the screen boundaries
if (x <= 0 || x >= width) {
speedX *= -1;
}
if (y <= 0 || y >= height) {
speedY *= -1;
}
// Simulate wing flapping
wingPosition = sin(radians(frameCount * 5)) * 20; // Flap the wings up and down
}
// Display the bird
void display() {
// Draw body
fill(255, 200, 0); // Yellow color
ellipse(x, y, 30, 20);
// Draw wings
fill(255); // White color
pushMatrix();
translate(x, y);
rotate(radians(wingPosition));
triangle(0, 0, -wingSpan / 2, 15, -wingSpan / 2, -15);
triangle(0, 0, wingSpan / 2, 15, wingSpan / 2, -15);
popMatrix();
}
}
int num = 10;
Bird[] birds = new Bird[num];
void setup() {
size(800, 600);
for (int i = 0; i < birds.length; i++) {
float x = random(width/2);
float y = random(height);
birds[i] = new Bird(x, y, 30); //Create a Ball object and save it in the array
}
}
void draw() {
background(135, 206, 250); // Sky blue background
for (int i=0; i < birds.length; i++) {
birds[i].update();
birds[i].display();
}
}