PFA:002 – Drawing With Code

Inspiration

Today’s Artists

Stop Drawing Dead Fish

Variables?

Before we go any further. Let’s dig a little deeper into one very important concept about programming. Variables.

As you can see, writing code involves a lot of numbers and very often you will use the same value in many places. Let’s create a new Sketch and draw a bunch of ellipses that are all the same size.

size(400,400);
background(0);

fill(255);
noStroke();

ellipse(100,200,20,20);
ellipse(200,200,20,20);
ellipse(300,200,20,20);

If we would like to change the size of these ellipses we would need to go and change the parameters on each of them. Not a huge deal when you only have three ellipses, but once you get to some more complicated programs and start dynamically changing some of the parameters, it’s going to be really important to know how to use variables. (Sidenote: There are also much better ways to draw multiple ellipses than writing them line by line. We will learn that later in the form of the for loop)

Variables can be thought of as boxes that can contain certain amount of certain type of data. You put the data inside the box and you can then access that data in that box at a later stage in your code. So let’s see how we could use them here.

First of all, you need to declare the variable. Declaring means that you give your variable a name. You can decide this name yourself, but there are some rules:

  • You shouldn’t use any names that are already reserved for other use in the programming language.
  • Variable names need to begin with a letter, underscore (_) or the dollar sign ($). Using a letter is preferred.
  • Variable names cannot start with a number, but after the first letter, you can add numbers also
  • Although it is not a strict rule, it is a convention to use camelCasing

You can also assign some value to the variable. Basically you create a box, write a name on the side of it and put some stuff inside the box. Here we declare a variable called eSize and assign it a value of 30.

Assigning a value is done using the equal sign (=). Here we declare a variable called eSize and assign it a value of 30.

int eSize = 30;

Ok, that makes sense, but what is that ‘int’ doing there?

Int means integer (a whole number, a number without decimals). Variables in Processing (and in many other programming languages) have specific data types and int is one of them. This variable, or box, can only store certain type of data. Because it has been declared as an int, it cannot store other types of data. The basic datatypes in Processing are:

  • boolean – true or false
  • byte – numerical value between -127 to 127
  • int – number without decimal points. 32-bit value.
  • long – like int, but long is able to store a larger value. 64-bit value.
  • float – numbers that have decimal values (floating-point numbers). 32-bit value.
  • double – like float, but can store a much larger value. 64-bit value.
  • color – color values
  • char – characters (letters and other unicode characters)
  • String – text (strictly speaking this is not a data type, but in the beginning we can think of it in the same way)

I included all the data types above, but you will be able to go pretty far with just using int, float, boolean and String. If you try to assign a value to a variable that does not match the datatype, you will most likely get an error.

Variables also have a scope, the area of the code where the variable is visible/usable. The eSize has been declared as a global variable. It can be accessed and modified in any other part of the code. We will talk about the scope of variables in more detail later.

Let’s use the variable in our code.

int eSize = 30;

size(400,400);
background(0);

fill(255);
noStroke();

ellipse(100,200,eSize,eSize);
ellipse(200,200,eSize,eSize);
ellipse(300,200,eSize,eSize);

Now that the size is a variable, we can easily change the size of all ellipses just by changing the value on one line of code. But laziness is not the only reason variables are used, they are also essential when we need to store and modify values.

Making Things Move – setup() and draw()

So far we have been creating programs that run only once. In order to create animations or interactive software, we need to somehow make the program run continuously. Fortunately, Processing makes this pretty easy. It has built in functions called setup() and draw(). The setup() function runs once, when the program starts, and the draw() function keeps running on a loop until you quit the program. This is how you use them:

void setup() {
}

void draw() {
}

Now we have the functions in place, but they don’t actually do anything yet, since there is no code inside the functions. Anything that is between the curly braces { } after setup, is part of the setup function. Same thing applies for the draw function.

Also remember to write the word void in front of the setup and draw. We will come back to why that needs to be there later, but for now, you just need to remember that it should always be there. If you really want to know, void just means that this function does not return anything,

From now on, we should always start any program we write by first adding these two functions. The next step is to add some code inside the functions.

int eSize = 30;

void setup() {
 // Set the size of the window
 // This needs to be only done once
 size(400, 400);
}

void draw() {
 // draw an ellipse
 ellipse(200, 200, eSize, eSize);
}

It looks like nothing special is going on. There’s just an ellipse in the middle of the window. It looks like a still image, but actually the program is drawing the ellipse over and over 60 times a second. It’s just always in the same place. Let’s edit the code and make the ellipse move.

Simple Interaction – mouseX, mouseY

We can replace the numbers with special variables called mouseX and mouseY, they are built-in variables in Processing that allow you to use the mouse coordinates. With the code below, you should be able to move the ellipse around using your mouse cursor.

int eSize = 30;

void setup() {
  // Set the size of the window
  // This needs to be only done once
  size(400, 400);
  background(134, 82, 132);
}

void draw() {
  // draw an ellipse where the mouse cursor is
  ellipse(mouseX, mouseY, eSize, eSize);
}

This is what you should see as a result:

You might be wondering, why do you get that trail of ellipses drawing on top of each other instead of just one of them? That is because Processing does not automatically clear the window on each frame, and we are only drawing the background only once in the setup. Watch what happens if we move the background() command inside the draw function.

int eSize = 30;

void setup() {
 // Set the size of the window
 // This needs to be only done once
 size(400, 400);
}

void draw() {
// clear the background on each frame
 background(134,82,132); 
 // draw an ellipse where the mouse cursor is
 ellipse(mouseX, mouseY, eSize, eSize);
}

Simple Conditions – if and mousePressed

We will discuss if statements in more detail in the next class, but let’s add some more interaction to our sketch using mousePressed and if. Just like mouseX and mouseY, mousePressed is a system variable. It stores the information if the mouse button is pressed or not. So the value is either true or false.

In order to make your program ask if the mouse button is pressed or not, you need to use a conditional statement called if. We could for example make the program only draw the ellipse if the mouse button is pressed.

int eSize = 30;
void setup() {
  // Set the size of the window
  // This needs to be only done once
  size(600, 600);
  background(134, 82, 132);
}

void draw() {
  // draw an ellipse where the mouse cursor is only when the mouse is pressed
  if (mousePressed == true) { 
    ellipse(mouseX, mouseY, eSize, eSize);
  }
}

Note that inside the if statement we use two equal signs == to compare if two values are equivalent.

Modifying the Values of Variables

In order to move and animate the graphical objects with code, we need to modify the values of our variables while the code is running. We already kind of did it by using the mouse coordinates, but let’s see how we can directly modify the values ourselves.

int eSize = 30;

void setup() {
  // Set the size of the window
  // This needs to be only done once
  size(600, 600);
  frameRate(60);
  background(134, 82, 132);
}

void draw() {
  // increase the size of the brush on each frame
  eSize = eSize + 1;
  println(eSize); 
  ellipse(mouseX, mouseY, eSize, eSize);

  // reset the eSize value back to 30 when the mouse is pressed
  if (mousePressed == true) { 
    eSize = 30;
  }
}


The ellipse keeps on growing, because each frame we add one to the previous value of the eSize variable. Try changing the frameRate to slow down or speed up the program to see this more clearly.

We are also using the command println() to print out the value stored in the eSize variable. Printing values is a very important debugging tool. It helps you to understand how your variables are changing while the code runs. It is also very useful for printing information about various stages of the program. Here we print out the text “Setup done!” when the code finishes the Setup part of the code.

We will look at more advanced examples related to modifying variables during the next lesson. Let’s finish today off with something a bit more fun.

Random

A very simple trick that creates very interesting effects is to use random(). Anywhere that you have a static number in your code, you could try replacing it with a random number. You need to define one or two parameters inside the random:

  • One value: random(100) – This will generate random numbers between 0 and 100. You are only defining the max value.
  • Two values: random(50,100) – This example will generate random values between 50 and 100. You are defining the min and max values.

Let’s try to implement the random to our current sketch. The eSize gets randomized when the mouse is pressed. Note that the data type of the variable was changed to float, since random() always returns a number with a decimal point.

Try doing something else with the random function. You should look into two additional system variables:

  • width – gives you the width of the output window in pixels
  • height – gives you the height of the output window in pixels

You could easily create something like this:

…or this:

… or this:

 

2nd Assignment

This is one of the mandatory assignments that you need to complete to pass this class.

  • Use the random() funtion and the 2D shapes to draw some interesting patterns.
  • Try using the random on different things: size, position, color etc.
  • Try your code with and without the background() in your draw() function
  • Save your sketch to your OpenProcessing page and post the link to MyCourses