Royal Institute Masterclass

Creative Coding

Charlie Pinder

School of Computer Science, University of Birmingham

Objective

In this session, we will explore some ways to use coding to be creative. We’ll draw some shapes, flap some cakes and fiddle with webcam images. I will introduce the Processing environment and cover some basic coding skills.

As with last week, the key to learning coding is experimentation, so please play with all the examples, try to break things in interesting ways and ask questions.

Processing basics

To open Processing, go to “Start” and then look under

All programs → School of Computer Science → Processing 2.2.1 → Processing.exe

And click to open. This will open the Processing environment. Note that it creates a new “sketch” for you – a sketch is basically a program.


Our first Processing sketch

void setup()
{
size(200,200);
frameRate(10);
}
void draw()
{
background(255,255,255);
ellipse(width/2, height/2, 50, 50);
}

Don’t worry too much yet what this all does. We’re going to type it all in first, run it and see what happens.

You can also copy and paste a heavily-commented version of the code from here:

Note that when you press “run”, a new separate window will open with the results of your code. (*note* there might be a slight delay after pressing run before the new running code appears!)

Good to know: There might be a slight delay after pressing run before the new running code appears!

Differences between python and Java

Processing is based on Java, so there are a few differences to the Python code you saw last week. Java doesn’t care about line breaks or tabs. We only use line breaks and tabs in Java to improve readability, but it doesn’t mean anything to the Java compiler.

Java uses:

  • Semicolons (;) to indicate the end of a line of code
  • Curly brackets ({}) to divide up functions (i.e. prespecified chunks of code that we can call by name)
  • Round brackets (()) to surround function/method calls and conditional tests

Exploring the code in depth

Let’s step through the code line by line.

The first thing to notice is that we have two functions defined – the setup() function and the draw() function. These are the basics of any Processing sketch.

void setup()
{
// this code gets run once
}
void draw()
{
// this code is run repeatedly
}

As you might expect, the setup function is only called once. The main thing we always need to do is to specify the size of our canvas for our sketch, which is done using the size method:

size(200,200);

TASK 1: Have a play with the numbers. Then, what if you set it to (0,0)? What if you set it to (some massive number, some massive number)?

Good to know: Most keyboard shortcuts work in the editor (e.g. Control & S to save, Control & Z to undo. Also helpful is Control & R to run your sketch.

The draw() function is called a framerate number of times per session. You can change how many times it’s called in setup() using the frameRate() method:

frameRate(10);

You can play with changing the number of frames per second later – but at the moment you won’t see any difference because our draw() loop always does the same thing!The default rate is 60 frames per second, so that’s how fast your sketch will run if you leave out this line of code.

Now let’s take a look at what’s happening in the draw() function.

background(255,255,255);

First, we draw a background. The numbers here stand for (red, green, blue) values respectively, and they can be anything from 0 to 255. The processing_cheat_sheet_english.pdf has some examples.

TASK2: Have a play with the numbers, and run the result. Can you make the background red? How about blue? What about purple? What happens if you put in a number that isn’t between 0 and 255?

Then try making the background slightly different each time it runs.

background(random(255), random(255), random(255));

Next in the draw() loop, we draw a circle using the ellipse(x,y,ellipse_width,ellipse_height) method. Calling this means an ellipse is drawn at point (x,y) with the specified width and height – to draw a circle, make the width and height values the same.

ellipse(width/2, height/2, 50, 50);

Here we draw an ellipse at point (width/2, height/2). Why? Well, Processing co-ordinates start at the top left of the sketch at (0,0), with the bottom right being the (sketchwidth, sketchheight) values. Sketch width values are stored in a handy global variable (i.e. a number that's accessible everywhere) called "width" and the sketch height is stored in a handy global variable called "height". Since ellipses are drawn from their centres, drawing one at point (width/2, height/2) draws it in the centre.

TASK 3: Experiment with different positions - alter the first two numbers in the ellipse() call to change the position (maybe using random() again). Experiment with the width and height of the ellipse by changing the "50"s for something else.

Task 4: Now the sketch is slightly different each time draw() is called, try changing the frameRate in the setup() function!

TASK 5: Experiment with different colours for the ellipse - add this line *above* the ellipse call

fill(255,0,0);

Can you guess what colour it will make the ellipse before you run it?

We really encourage you to experiment . The worst thing that will happen is that Processing won’t understand what you mean, and it will try to give you a helpful error in the message area, highlighting the line with the problem.

Final task – adding some interaction plus some variables!

We often want to respond to what the user is doing (that is, after all, rather the point of Human-Computer Interaction ).

Processing gives us a few handy functions to flag up to our code that the user has done something:

Mouse

void mousePressed()
{
// react to mouse pressed here
}

Keyboard

void keyPressed()
{
// react to key pressed here
}

Task 6: reacting to the user

Add one of the methods above. Look at your sketch and decide what number you want to change based on user interaction.

Now, in order to be able to access that number outside your draw() loop, we need to make it a global variable, which means declaring it right at the top of your sketch.

Say you decided to change the ellipse width based on mouse presses. First, declare an int variable (a whole number variable) at the top of your sketch (above the setup() function):

int ellipseWidth = 50;

Now, because you’ve declared the variable outside the other functions, you can access it throughout your code to both read and change it.

Next, replace the current ellipse width with the new variable:

ellipse(width/2, height/2, ellipseWidth, 50);

The final step is to change the ellipseWidth in the mousePressed() function:

void mousePressed()
{
// react to mouse pressed here
ellipseWidth += 25;
}

The += just means, take the existing value of ellipseWidth, add 25 to it, then save the result back into the ellipseWidth. Now run the code and try clicking the mouse.

Good to know: you can use a println() statement to print variable values out to the console so you can see what’s going on with the variables in your sketch.

println(ellipseWidth);

Try replacing more numbers. Could you have mouse presses to increase the width, and key presses to decrease it? What happens when the width goes below zero?

Handy links:

  • - a list of all the available functions, methods, keywords and symbols that Processing understands, with explanations