Visual Programming For Absolute beginners


An ASIS&T Workshop
Presented by Clinton McKay

What Is Processing?

- from Wikipedia:

Processing is an open source programming language and integrated development environment (IDE) built for the electronic arts, new media art, and visual design communities with the purpose of teaching the fundamentals of computer programming in a visual context, and to serve as the foundation for electronic sketchbooks.

-Processing is based on Java but uses simplified syntax and assumes a graphical end product.

Why you're going to love Processing:

-Processing is really cool.

-You can build entire programs that run on Mac, PC, and Linux and work just like any other computer program (this is only possible with the IDE)

-You can drop a processing program (called a "sketch") into any webpage with a few lines of HTML.

-You can learn programming without wanting to bang your head against the wall!

What do You Need to Work with Processing?

-Processing IDE (Recommended)

-Openprocessing.org account

-Build and display directly in the browser (You'll just need a plain text editor)





Processing is simple, but it's still programming.
You'll need to know some basics of
programming to use it effectively.

Programming Tips

-Think like a machine. Be 100% explicit.

-Make your sketch as simple as possible.

-If something's not working, don't be discouraged--it could be something as simple as a missing ')' in your code. The Processing IDE will help you keep from making these kinds of mistakes but even pros make silly errors every once in a while.

-Be lazy. Try to find a way to do what you want with just a few lines of code--in most cases, there's a way.

The basics of Processing:


SETUP() // THE SETUP FUNCTION IS CALLED ONCE, IT WILL NEVER BE CALLED AGAIN. EVERYTHING YOU WANT TO DO BEFORE YOUR PROGRAM STARTS REALLY RUNNING NEEDS TO BE IN THE SETUP FUNCTION.

DRAW() // THE DRAW FUNCTION WILL BE CALLED OVER AND OVER AGAIN
UNTIL YOU TELL IT TO STOP. THIS IS HOW ELEMENTS ARE ANIMATED FROM ONE FRAME TO THE NEXT IN PROCESSING.



More Functions

Additional functions can be created very easily, you can package up some code to be used again and again just by referring the function name you give it.

For example:
void mousePressed()


void newCircle()


void rotateSquare()

The Setup() Function



void setup(){
    size(200,200);
    background(255,255,255,100);
    stroke(0,0,0,100);
    strokeWeight(3); 
    fill(150,150,150,50);
    frameRate(40);
} 

What the Setup() Function Means:



void setup(){ 
size(200,200); // width in pixels, height in pixels
background(255,255,255,100);  //  background red value, background green value, background blue value, alpha/opacity (0-100)
stroke(0,0,0,100);  //  stroke color (same values as background)
strokeWeight(3);  //  stroke width in pixels
fill(150,150,150,50);  //  fill color (same values as background)
frameRate(40) // number of times per second the draw function should be called (100 by default)
} 

Only the size element is absolutely required; other elements may be supplied in another function later on.

A Note on Color

-Colors in Processing can be represented a lot of different ways--usually R,G,B,A is a really useful way to do it.

-They can also be represented with hex codes, but using a hex code doesn't allow you to set the opacity. Hex codes are actually R,G,B codes in disguise anyway (for instance, #55FAD3)

-You can also use gray values (supply a number between 0 and 100, 0 being white and 100 being black) but why limit yourself to 100 shades of gray when you can use R,G,B to represent anything between white (255,255,255) and black (0,0,0)?

The Draw() Function



void draw(){
// do something
} 
Unlike the setup() function, the draw() function is called over and over again.

Whatever you type inside the draw() function will be performed repeatedly until Processing runs into a special function to stop it (that function is noLoop() )

Draw a Circle



ellipse(50,50,10,10);  //  X coordinate of the center, Y coordinate of the center, width in pixels, and height in pixels 

Whenever you want to draw a circle on the canvas, you need to call the ellipse() function. This function can make ellipses and circles, so it needs a center point, a width, and a height.


Draw a Line



line(50,50,150,150);  //  X coordinate of first endpoint, Y coordinate of first endpoint, X coordinate of second endpoint, Y coordinate of second endpoint 

line() takes four parameters--the first two are one endpoint, the second two are another endpoint.


Draw a Rectangle



rect(50,50,100,100);  // X coordinate of top left corner, Y coordinate of top left corner, width in pixels, height in pixels


rect() takes four parameters, the first two are the top left corner of the rectangle, the third is its width, and the fourth is its height.


OK. let's Make Something.



void setup(){
   size(500,500);
   background(255,0,0,100);
   fill(255,255,255,100);
   stroke(0,0,0,100);
}

void draw(){
   rect(100,100,50,200);
   ellipse(150,250,75,150);
   line(150,150,480,480);
} 
Wow, that's ugly. Don't worry, things will get better eventually!

Some more Programming Tips:

Variables - variables are really important. Here's how you declare a variable:

int x = 1;  // integers are whole numbers (they can be negative or positive)

float y = 4.0;  // floats are decimal numbers (also negative or positive) 

String chicken = "Roger is the chicken's name";  //  Processing doesn't use a lot of text, but you can display text in various fonts--store text as strings 

color c = color(255, 204, 0);  //  colors are not very useful as variables, but it's possible to store a color in a variable

More about Variables:


Variables don't need to be a single letter. Try to name your variables words/letters beginning with a lower case letter (generally, symbols other than "_" do not belong in variable names).


Examples of common variable naming conventions are:

w
inputText
numberOfChickens
charleysPhoneNumber

Width and height

width & height

These variables always return the canvas' width and height--use them any time you want to make your sketch scalable, because if you change the size of the canvas, width and height will respond to new canvas sizes and react appropriately.

For example:

rect((width/2) - 15,(height/2) - 15, 30, 30); 

Why is this better than just doing the math and entering integers for all four of rect()'s parameters?

Random



random(100);  

random() generates a semi-random float between 0 and whatever number you specify. This is great for generating a new random color or position.


Try adding the following into setup() and then draw():

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

MouseX and MouseY

mouseX & mouseY

These dynamic variables always store the location of the user's mouse, you can use them to produce shapes that change based on where the user's mouse is at any given point in time.


Try adding the following to the end of your draw() function:

stroke(0,0,0,100);
line(0, 0, mouseX, mouseY); 

Now let's practice:



Create a blank sketch (with a white background) that is 1000px wide and 1000px tall. Set your fill to (255,100,100,5).

Draw a rectangle from the top left corner to the user's mouse position.

The Code:

void setup(){
   size(1000, 1000);
   background(255, 255, 255, 100);
   fill(255, 100, 100, 5);
   stroke(0, 0, 0, 100);
}

void draw(){
  rect(0, 0, mouseX, mouseY);
} 
Great! But how can we make it so that a single rectangle is on the screen at any given time?

The Solution:



void setup(){
   size(1000, 1000);
   background(255, 255, 255, 100);
   fill(255, 100, 100);  // the opacity is set to 100% to show the rectangle
   stroke(0, 0, 0, 100);
}

void draw(){
  background(255, 255, 255, 100);
  rect(0, 0, mouseX, mouseY);
} 
Why does it work now?

More Practice (a little Harder):

(You can use the same sketch, just empty out your draw() function)

Draw a circle that's 30px wide and 30px high centered around the point where the user's mouse is.

Have each circle be a new random color with a random opacity between 0 and 50%. There should be no stroke around the circles.

Hint: to remove the stroke, simply add noStroke(); to your draw function before the shape is drawn or delete stroke(); and strokeWeight(); from your setup() function

The Code:


void setup(){
   size(1000, 1000);
   background(255, 255, 255, 100);
   fill(255, 100, 100);
   noStroke();
}

void draw(){
  fill(random(255), random(255), random(255), random(50));
  ellipse(mouseX, mouseY, 30, 30);
} 
Now, how can we set the opacity to a random number between 30 and 50?

Solution:


void setup(){
   size(1000, 1000);
   background(255, 255, 255, 100);
   fill(255, 100, 100);
   noStroke();
}

void draw(){
  fill(random(255), random(255), random(255), 30 + random(20));
  ellipse(mouseX, mouseY, 30, 30);
} 

More Practice:


Make a sketch that creates
a vertical line
-3px wide (use the strokeWeight() attribute)
-that is a random shade of green
-and 25% opaque
emanating from the user's mouse every frame.

The Code:


void setup(){
    size(1000, 1000);
    background(255, 255, 255, 100);
    strokeWeight(3);
}

void draw(){
    stroke(0, random(255), 0, 25);
    line(mouseX, 0, mouseX, height);
} 
Great! Now instead of green,
make it a random shade of gray.

Yes, We Have No Variables!



To make a random shade of gray, you can simply write
stroke(random(255), 25); 

but you know how I love RGBA, how would you do it with RGBA?

The Solution:



float g = random(255);
stroke(g, g, g, 25); 

What happens if you set g in the setup() function?
What about in the draw() function?

More Practice:



Now that you know how to make the horizontal line either a shade of green or a shade of gray, let's do both at once. Edit your code so that there's a horizontal green line and a vertical gray line emanating from the user's mouse position.

The Solution:


void setup(){
    size(1000, 1000);
    background(255, 255, 255, 100);
    strokeWeight(3);
}

void draw(){
   float g = random(255);
   stroke(g, g, g, 25);
   line(mouseX, 0, mouseX, height);
   stroke(0, random(255), 0, 25);
   line(0, mouseY, width, mouseY);
} 
So what's happening here?

Arrays


Arrays are really useful, but understanding them can take a little work. First, let's create a new global variable to store an array.

A global variable is one that is instantiated (or created) outside of any function, usually at the very top of your code.

float colorOptions[] = new float[]; 


Background Information for Arrays:


Positions in arrays are referred to with this syntax

String fruits[] = {"apples","oranges","grapefruits","peaches","bananas"};
fruits[0] fruits[1] fruits[2] fruits[3] fruits[4]

Notice that the number in brackets is not what you would expect. Positions in arrays (in Processing as well as almost all other programming languages) start with 0 instead of 1.

Dealing with Arrays


another way of referring to bananas (the last item in the fruits[] array) would be:

fruits[fruits.length - 1]

The length of fruits[] is 5 (there are 5 things in fruits[]), so whenever you subtract 1 from the length of fruits[], you get the position of the last item in the array. Guaranteed to work 100% of the time!

So how do I Store Items in an Array?



int[] colorOptions = {30, 100, 200, 230};

Now what does colorOptions look like?

colorOptions = [30,100,200,230]

Great! But what does it do? We'll need to learn about loops to see the power behind arrays.


Loops



What good is programming if you have to write a line of code each time you want to do something? Loops perform a task over and over. They come in two varieties (for loops and while loops), but for loops will teach you what you need to know.

To demonstrate loops, we'll just make one.

Loop (Step 1)



Write your setup() function (feel free to deviate from this however you like, or just copy it to make things simple)

void setup(){
    size(800,800);
    background(255,255,255,100);
    stroke(0,0,0,100);
    strokeWeight(1);
} 

Loop (Step 2)


Create a global variable called counter, set it to 0, and a global array just like the colorOptions example, only give it as many numbers as you'd like (make sure they're all between 0 and 255)

int counter = 0;
float[] colorOptions = {244, 35, 0, 130, 200};void setup(){
    size(800,800);
    background(255,255,255,100);
    stroke(0,0,0,100);
    strokeWeight(1);
}  


Loop (Step 3)

Add the draw() function, and draw a square like this:

int counter = 0;
float[] colorOptions = {244, 35, 0, 130, 200};void setup(){
    size(800,800);
    background(255,255,255,100);
    stroke(0,0,0,100);
    strokeWeight(1);
}  
void draw(){ rect(counter + 30, 30, 20, 20);}

Loop (Step 4)

Add the loop
int counter = 0;
float[] colorOptions = {244, 35, 0, 130, 200};void setup(){
    size(800,800);
    background(255,255,255,100);
    stroke(0,0,0,100);
    strokeWeight(1);
}  

void draw(){
     for (int i = 0; i < colorOptions.length; i++){
        rect(counter + 30, 30, 20, 20);
        counter += 30;
     }
}
Why do we have more than 5 squares?

For Loops Explained:


What's happening here?
for (int i = 0; i < colorOptions.length; i++){
        rect(counter + 30, 30, 20, 20);
        counter += 30;
     } 
1) int i = 0 -- Create an integer that begins as 0
2) i < colorOptions.length -- Keep going as long as i is less than the number of items in
colorOptions[]
3) i++ -- Add 1 to i each time the loop loops

That's it, now everything inside the loop will happen once for each item in colorOptions!

Loop (step 5 Part 1)



OK so we can make things happen multiple times, why are we using colorOptions.length to determine how many times the for loop happens instead of just "5"?

You can access the value of i while you're inside the loop, and it's changing all the time! Why is that useful?

Loop (step 5 Part 2)


int counter = 0;
float[] colorOptions = {244, 35, 0, 130, 200};void setup(){
    size(800,800);
    background(255,255,255,100);
    stroke(0,0,0,100);
    strokeWeight(1);
}  

void draw(){
     for (int i = 0; i < colorOptions.length; i++){        fill(colorOptions[i], colorOptions[i], colorOptions[i], 100);
        rect(counter + 30, 30, 20, 20);
        counter += 30;     }
     noLoop();
}

Loop (Step 6) logical operators:

int counterX = 0;
int counterY = 0;
float[] colorOptions = {244, 35, 0, 130, 200};
void setup(){
size(800,800);
background(255,255,255,100);
stroke(0,0,0,100);
strokeWeight(1);
}
void draw(){
int counterInt = (counterX / 30);
fill(colorOptions[counterInt % 5], colorOptions[counterInt % 5], colorOptions[counterInt % 5], 100);
rect(counterX + 30, counterY + 30, 20, 20);
counterX += 30;
if ((counterX + 60) > width){
counterY += 30;
counterX = 0;
}
if (counterX == 0 && counterY + 60 > height){
noLoop();
}
}

Logical Operators you should know:

if:
x > y (x is greater than y)
x < y (x is less than y)
x <= y (x is less than or equal to y)
x >= y (x is greater than or equal to y)
x == y (x is equal to y)
x != y (x is not equal to y)

x < y && y > 0 (x is less than y AND y is greater than 0)
x > y || y == 5 (x is greater than y OR y is equal to 5)

So now we have a Sketch. what next?

You have lots of options for how to distribute a sketch. One way is export the sketch:
1) Save the file in Processing IDE
2) Export a working version of the sketch.
You can export versions for Linux, Mac OSX, and Windows (both 32 and 64 bit).
3) Once you have the installer files, you can host them as zip files online and link to them from anywhere.
Exported sketches will run in full screen mode

Sharing with openprocessing.org

Openprocessing.org allows you to run sketches online using HTML5 and the processing.js JavaScript Library.

Once you've created an account on openprocessing.org, simply share links to your processing portfolio, individual sketches, or use this trick:
link to the sketch: http://www.openprocessing.org/sketch/102428
add /show: http://www.openprocessing.org/sketch/102428/show


Just add an iframe to your website with that url as its source and you'll get this:

iframe and openprocessing.org



The downside of the iframe solution:


iframes are kind of dumb. No one really likes them. Also, they don't always work with Processing the way you'd like.

Plus, HTML5 has a new element called the canvas that is way better and knowing about it and being able to work with it will be a lot more useful than knowing how to drop an iframe into html.

So where do we start?

Processing and the HTML5 Canvas


The first step is making sure you have a
canvas on your page:
<!DOCTYPE html>
<html>
<head>
<title>Processing and the HTML5 Canvas</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body> <canvas width="800px" height="800px"> </canvas>
</body>
</html>
Remember, the canvas is an HTML5 element,
don't use it with XHTML.

Processing and the HTML5 Canvas (part 2)

Now, link to processing.js. Either save the library
or link to an external copy.
(I have hosted processing.js, so you can just link to my copy)

<!DOCTYPE html>
<html>
<head>
<script src="http://clintonmckayart.com/Randomer/processing.js"></script>
<title>Processing and the HTML5 Canvas</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body> <canvas width="800px" height="800px"> </canvas>
</body>
</html>


Processing and the HTML5 Canvas (Part 3)


Now, save your processing code in a plain text file. Name the file processingCode.js (or anything else.js)

add the following attribute to your canvas element:

data-processing-sources="processingCode.js"

Processing and the HTML5 Canvas (Part 4)

Your finished html file should look like this:
(make sure you're pointing to TWO .js files that really exist)

<!DOCTYPE html>
<html>
<head>
<script src="http://clintonmckayart.com/Randomer/processing.js"></script>
<title>Processing and the HTML5 Canvas</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body> <canvas width="800px" height="800px" data-processing-sources="processingCode.js"></canvas>
</body>
</html>


Additional Processing Resources:


Processing.org
Open Processing
W3Schools HTML Tutorials
W3Schools JavaScript Tutorials
Slid.es (reveal.js builder)

You can contact me with any questions!
www.clintonmckay.com
clintonmckay@gmail.com