In these notes you will learn about:
Processing is a freely available piece of software. It comes with a handy programming environment that runs more or less identically on Mac, Linux, and Windows systems.
Note
You really can expect Processing to work essentially identically on different systems. Past students have used Processing on all these systems with almost no noticeable differences. This is a pretty impressive technical achievement that is due to Java: from its birth, Java has always tried to make the same Java program run the same on any computer.
So the first thing you ought to do is download and install the appropriate version of Processing for your computer. We’ll be using the editor that comes with Processing. When you first run it, it should look something like this:
Processing is a minor dialect of the popular Java programming language. One of the major differences between Processing and Java is that Processing comes with this ready-to-use graphical editor that makes it easy to start writing programs. If we were programming in Java, we would need to take some time to set up a more complicated editor, such as Eclipse.
Note
It is possible to use Processing in regular Java programs without using its graphical editor. This is especially useful when you start writing big programs, as the Processing editor is designed mainly for writing very small programs. In this course we will only be writing small programs and so we’ll stick with the Processing editor.
Lets write our first Processing program. Launch Processing and type the following into the editor window that appears:
void setup() {
size(500, 500);
}
void draw() {
ellipse(mouseX, mouseY, 40, 40);
}
Warning
You must type this program exactly as it appears: a single wrong character could cause it not to work!
Now run the program by clicking the “play” button at the top of the window, i.e. the little triangle in the circle at the top-left of the screen (under the File menu). Move the mouse around, and you should see lots of circles, e.g.:
After you press the play button we say that a program is running, or executing. This particular program runs until you either click the “stop” button (the little square in the circle), or quit Processing (e.g. closing the Processing window, or choosing “quit” in the File menu).
Note
To save a program to your computers disk, click the square with the downward-pointing arrow, or press ctrl-S (i.e. hold down the ctrl key and then press S). Give your program a descriptive name to help you remember what it is about, e.g. firstProgram would be good.
The Processing IDE combines three basic programming tools into one convenient package. First, it contains a text editor that you use to edit your programs. This is a good programming text editor that provides a number of special features like color-code text and automatic formatting. Second, the IDE handles compiling for you. Compiling is the name of the process of converting source code to executable code. Third, it makes it easy to run your programs after they’ve been compiled.
Note
Processing files end with the extension .pde. This is important because many programs decide how to handle a file based on its extension.
Now lets look in detail at our program. The text of a program is called its source code, or code for short:
void setup() {
size(500, 500);
}
void draw() {
ellipse(mouseX, mouseY, 40, 40);
}
The first thing to note is that the source code is divided into two functions, one named setup() and the other named draw(). Almost every Processing program we write will have these two functions.
The setup() function is called precisely once at the start of your program. When a function is called the code inside of it, i.e. the code between the open brace { and the close brace }, is executed. In this program, setup() contains a single function call to size that sets the width and height of the output window to be 500 by 500 pixels.
After the setup() function finishes, the draw() function is called repeatedly. That is, Processing calls draw() again and again forever. Each time draw() is called, an ellipse 40 pixels wide and 40 pixels high is drawn at the position of the mouse pointer, i.e. at location (mouseX, mouseY) on the screen. The flow chart on the right shows how setup() and draw() are called.
Both setup() and draw() are void functions, and so they provide no return value. All that means is that these particular functions don’t calculate any results. Later we will see that functions that do calculate values for us.
mouseX and mouseY are examples of variables. These particular variables are pre-defined by Processing and are automatically set to be the current coordinates of the mouse pointer on the screen.
Another important detail to notice about this program is how it is indented. In programming, indentation is used to help visually identify related statements in a block of code. For example, the statement inside the setup() function is indented a couple of spaces:
void setup() {
size(500, 500);
}
The close brace } lines up with the v in void. If we add any more statements to setup(), they should start in the same column as the s in size.
Consistent and correct indentation is an important part of writing source code, and we will be checking for it in all your assignments. If you are not sure how to indent something, then indent it like the source code in these notes, or ask a TA or instructor for advice.
Note
Processing editor will automatically indent your code for you if you press ctrl-T (hold down the Ctrl key, and then press T). This is quite handy, although be aware that it doesn’t always work perfectly.
In one second, Processing can call draw() approximately 60 times. In other words, it can draw about 60 different pictures a second. We call this the program’s frame rate, and the Processing variable frameRate is an estimate of the current frame rate. The number of frames per second that a program runs at is often abbreviated fps.
Of course, if it takes a long time for draw() to finish, then the frame rate might be less than 60. For complex animations that do a lot of work to generate each frame, it is important to keep an eye on the frame rate to make sure it never dips too low. However, in this course we will probably not write many — if any — programs that cause serious frame rate problems.
If you like, you can change the frame rate by calling the frameRate function. For example, to set the frame rate to be 30 frames per second, put this in setup():
frameRate(30);
Now lets play with our program a little bit to see what else we can do. Re-write it as follows (again, be very careful to type the code exactly as given!):
void setup() {
size(500, 500);
}
void draw() {
ellipse(250, 250, mouseX, mouseY);
}
Here we’ve changed the parameters to the ellipse function: now the ellipse being drawn is always at (250, 250) (the middle of the screen), and its width is the value of mouseX and its height is the value of mouseY. Move the mouse pointer around while the program is running to see the effect.
Here we swap mouseX and mouseY:
void setup() {
size(500, 500);
}
void draw() {
ellipse(mouseY, mouseX, 40, 40);
}
This is an unusual effect: it feels as if the mouse is not working properly!
In this program we add another ellipse:
void setup() {
size(500, 500);
}
void draw() {
ellipse(mouseX, mouseY, 40, 40);
ellipse(mouseX + 80, mouseY, 40, 40);
}
The second ellipse is drawn 80 pixels to the right of the first one. If you replace the 80 with, say, 20, then the ellipses will overlap.
Lets stop for a moment and look in more detail at the ellipse function. You call the ellipse function by writing a statement that looks like this:
ellipse(x, y, width, height);
We say that ellipse has four parameters: x, y, width, and height. Each of these parameters must be a number; width and height should both be greater than 0.
Notice a few important details:
It’s important that you follow exactly this format for any call to ellipse. Almost any other way of calling ellipse results in an error. For example:
ellipse(0, 0, 0, 250, 250); // too many parameters
ellipse(0, 0, 250); // too few parameters
ellipse(0, 0, 250, 250,); // extra comma
ellipse(0, 0. 250, 250); // . instead of ,
Ellipse(0, 0, 250, 250); // wrong case
elipse(0, 0, 250, 250); // wrong spelling
ellipse(0, 0, 250, 250) // missing ;
ellipse(0, 0, 250, 250; // missing )
The // symbol indicates a source code comment, i.e. a message to a person reading the program. We will often add comments to our programs to make them easier for humans to read.
ellipse is a pre-defined function that comes with Processing, and you can read about it here. The Processing reference page lists all the Processing functions, and we will often be referring to it. Bookmark it!
Note
Check out Khan Academy for an easy way to test out shapes quickly.
Now lets make a small but important modification to our original program:
void setup() {
size(500, 500);
}
void draw() {
background(200);
ellipse(mouseX, mouseY, 80, 80);
}
Every time draw() is called the background function sets the color of the drawing window to be (in this case) a light shade of gray (a value closer to 0 would make it darker). This has the effect of erasing the screen: anything on the screen gets over-written. The result is that the ellipse appears to move around without leaving a trail.
This simple trick of re-drawing the screen background at the start of every call to draw is a key idea in computer animation. We’ll use it throughout this course as the basic technique for getting things to move on the screen.
You can set the background of the drawing window to be an image:
PImage bg;
void setup() {
size(500, 300);
bg = loadImage("http://bglabs.evade.netdna-cdn.com/45875kli90/360.jpg");
}
void draw() {
background(bg);
ellipse(mouseX, mouseY, 80, 80);
}
The idea here is that we have loaded an image from the web into a Processing variable named bg. Whenever draw is called that image is first drawn on the background.
Note the following:
bg is a variable of type PImage that is defined in the very first line of the program, i.e. this line defines bg:
PImage bg;
As we will see later, it is important that bg be defined outside of any function. If bg had been defined inside, say, the setup() function, then bg would not be usable in draw().
The loadImage function reads an image file (JPEG, GIF, PNG, etc.) into your program. In this particular case we are reading the image from a website, but, more typically, you give it the name of an image file on your computer.
Loading an image from disk is relatively slow, and so you probably only ever call loadImage inside of setup(). You might have noticed video games often take a long time to “load” when they start: typically this is because they are loading images and sounds from disk into memory, and accessing a disk takes much more time than accessing RAM.
Loading images directly from the web is usually worse than getting them from a disk. For instance, if your web connection is slow, or if the server that stores the image is slow, then your program will be slow because it doesn’t continue until it gets the entire image. Plus the bigger an image is, the longer it takes to be sent across the web. Another problem is that you don’t have control over the image: the owner of the website could change or remove the image at any time.
Generally, it is better to store all the images you load into your programs directly on your computer. This is what we will be doing in this course.
Once an image is loaded it stays in memory and thus can be quickly accessed (e.g. via a PImage variable like bg) whenever we need it.
To set the background of the window, we write the statement background(bg).
Important
The width and height of the window need to be the same as the width and height of the background image. Check the dimensions of your image before running your program and then call size with the same width and height.
Instead of moving an ellipse, lets see how we can move an image. Look at this program:
PImage bg;
PImage ball;
void setup() {
size(500, 300);
bg = loadImage("http://bglabs.evade.netdna-cdn.com/45875kli90/360.jpg");
ball = loadImage("soccerball.png");
}
void draw() {
background(bg);
image(ball, mouseX, mouseY);
}
Here we’ve added a new PImage variable called ball. Inside setup() we load the contents of the disk file soccerball.png into it using loadImage.
Note
We actually have to have the file soccerball.png in the same location as our program! More on this later.
To display the ball, we call the image function:
image(ball, mouseX, mouseY);
This puts the image in ball at location (mouseX, mouseY) on the screen.
Keep in mind that for every different image you want displayed in a program will need its own PImage variable.
One of the messiest details of using files is naming them. Modern computers organize data stored on disk into files and folders (or directories), known as a file system. A file is a named collection of on-disk data, while a folder is a named collection of other file and folders. The folders in a file system form a hierarchy that looks like an upside-down tree.
For example, here is a simple example file system with four folders and three files:
One way to name files is to use their absolute path name. This is the name of the file preceded by the names of the folders it is contained within. For example, on Windows you write absolute path names like this:
C:\Desktop\cmpt166\a1.txt
C:\Desktop\cmpt166\ball.gif
C:\Desktop\cmpt166\data\ball.gif
C:\Desktop\macm101\a1.txt
In Windows, the \ character, called backward slash (or backslash), is used to separate the names. The C: at the start is the name of the disk drive the file is on.
On Mac and Linux computers, absolute path names are written a little differently:
/Desktop/cmpt166/a1.txt
/Desktop/cmpt166/ball.gif
/Desktop/macm101/a1.txt
There’s no C: at the start, and the forward slash character, /, is used to separate the names.
Notice that two files both have the same name, a1.txt. That’s okay because they are in different folders, and so have different absolute names. What would not be okay is if the two files were in the same folder: then there would be no way to tell them apart.
While absolute path names work well, they can often be very long. Plus, there are often cases where we don’t know all the names of the containing folders. For example, if you use absolute path names in an assignment and then send that assignment to a TA for marking, your program will most likely not work correctly because the TA probably won’t have the same folder structure as you.
So to deal with these problems, we often use relative path names. For relative path names to work, we need a current working folder that specifies the name of the folder that we (or a program) are currently using. For instance, suppose we agree that the folder cmpt166 is the current working folder. Then we can specify the files in it like this:
a1.txt
ball.gif
We don’t need any folder names at all since all the files we are interested in are inside the current working folder. Not only does this result in shorter names, but it will work in the case where you send your program to a TA since the names of all the containing folders are not specified.
Lets take a moment to see how Processing arranges the files and folders for the programs you write in it. Suppose you write a program in the Processing editor, and save it with the name soccerBall. Then, inside the current sketchbook, Processing creates a folder called soccerBall, and inside that folder is a file called soccerBall.pde that contains the source code of your program.
The folder that contains the .pde source file, in this case soccerBall, is the current working folder for the program.
Processing programs often have media files (e.g. image and sound files) associated with them. To keep things tidy, you can (and should!) put all your media files in a folder called data that is in the same folder as the .pde source file. When you call a function such as loadImage("ball.gif"), Processing automatically searches the data folder for the file ball.gif.
Draw a flow chart showing when the setup() and draw() functions are called.
What is source code?
Describe, in English, what the following Processing statement does:
size(500, 250);
Write a Processing statement that draws an ellipse of width 50 and height 75 at the current mouse location.
Name two variables that Processing provides.
What is the purpose of a ; (semi-colon) in a Processing program?
What does // indicate in a Processing program?
What happens if you call loadImage on a file:
loadImage can load images directly from websites. Why is this usually a bad idea?
What does this statement do?
image(ball, mouseX, mouseY);
What is an absolute path name? What is a relative path name? How do they differ?
What are two major problems with absolute path names?
Draw a picture of a file system that has files and folders with the following names:
/Desktop/courses/macm101/notes.txt
/Desktop/courses/166/sketchbook/bounce/bounce.pde
/Desktop/courses/166/sketchbook/jump/jump.pde
/Desktop/courses/166/sketchbook/jump/data/jumper.pde
Write a program that draws a square wherever the mouse pointer is on the screen. The square should leave a trail, i.e. do not re-draw the background on each call to draw(). Hint: Use the rect function.
Re-do the previous question, but this time do not have the square leave a trail, i.e. re-draw the screen background at the start of each call to draw().
Write a program that draws this shape centered at the mouse pointer:
It should not leave a trail when it moves.
Draw the following figure, consisting of 9 small squares, using exactly 3 calls to rect:
There’s no animation in this question: just write the code that draws this diagram.
Important: you must make only 3 calls to rect!
You might want to use the noFill function in this program.
Write a program that draws a circle inside of a square wherever the mouse points. It should not leave a trail.
Write a program that animates (without a trail) two squares. The first square moves horizontally across the screen following the x-coordinate of the mouse. The second square moves vertically across the screen following the y-coordinate of the mouse.
Give the squares different colors using the fill function.
Write a program that draws a vertical line and horizontal line that intersect at the mouse pointer. The lines should go all the way across the screen, and move (without leaving a trail) as the mouse moves. Turn off the mouse pointer using the noCursor() function.
Write a program that draws two ellipses both with their centers in the middle of the screen (i.e. at (250, 250) on a 500 x 500 screen). Make the width and height of the two ellipses change in different ways as you move the mouse pointer around the screen. How exactly the ellipses change is up to you.
Read about the triangle function and write a program that makes a triangle follow the mouse pointer around the screen without leaving a trail.
Important: The triangle must keep the same size and orientation as it moves.
Draw the following figure using only four calls to the triangle function:
There’s no animation in this question, just a single static image.
Important: you must make only 4 calls to triangle!
You might want to use the noFill function in this program.
Find (or create) a nice background image, and use it in one of the sample programs from the notes above that does not already use a background image. Remember to set the size of the window to be the width and height of the image!
Write a program that draws a single line on the screen using the line function. One end of the line should always be at (0, 0), and the other end of the line should be at the mouse pointer. The line should not leave a trail: re-draw the background on each call to draw().
Extend the program in the previous question to use four lines, each with one end attached to one of the four corners of the screen. The other end of each line should be at the mouse pointer.
Write a program that draws an interesting, unique, and non-trivial picture that moves (without leaving a trail) wherever the mouse pointer goes. Use at least one image that you create, and at least 5 shapes drawn with Processing functions.
You can use any drawing/paint tool you like for creating your image (e.g. the paint program that comes with Windows is fine). It doesn’t need to be a work of art, but make sure it looks like you put some effort into it.
Also create your own unique background image that goes with your moving picture: the background and the moving thing should make sense together.
Here are a few ideas:
Try to make your program fun, e.g. something that might impress a little kid for a minute or two.