Day 02 Wrap-Up

Today we formally introduced Processing as a development tool and discussed some basic ways to create simple interactive sketches. Here’s a recap of what we covered:

  1. We started off by discussing Processing as a graphical development tool. You can get started yourself by downloading Processing from http://www.processing.org – run the installer and you’re ready to begin!
  2. Next we talked about how to write programs using Processing. Processing programs are sometimes referred to as “sketches” — as soon as you launch the application you will be greeted with a new sketch window. You can save this file and give it a name – Processing requires your sketch names to contain only alphanumeric characters (it will yell at you if you use an invalid character).

    Processing IDE

    The Processing IDE

  3. The file format that Processing uses for source code files is “.pde”.  “.pde” files are really just plain text files, and you can open them inside any text editor.  You can view your source code on your file system by clicking on Sketch -> Show Sketch Folder. Note that Processing will organize your sketches into folders for you – each sketch will be filed inside its own folder of the same name. These are quickly accessible inside the IDE by clicking on File -> Sketchbook
  4. By default, your sketches will be saved in a Processing folder inside your Documents folder on a Mac.  On a PC they will be stored inside the “My Documents” folder.  You can change the default location for your “sketchbook” by clicking on File -> Preferences.
  5. Processing s ource code is written in the large text box in the middle of the IDE.  Code is executed sequentially  as in other programming languages. You will be following Java syntax rules when writing your code. For a basic function call this looks like the following:
    functionName(argument1, argument2, … , argumentN);
    Note the semicolon at the end of the line – this denotes the end of a statement.  Most lines of code you write in Processing require a semicolon at the end of the line, but there are a few exceptions that we will go over in our next class.  Also, keep in mind that Processing (Java) is case sensitive, and most functions are written using “camelCase” style.
  6. The first thing you will want to do in your program is to request a size for your graphical canvas.   You can do this by calling the “size” function. Size takes at least two arguments – a width and a height, in pixels. For example, calling:
    size(800, 600);
    will create a graphical canvas with a width of 800 pixels and a height of 600 pixels. Don’t forget the semicolon at the end of your statement!
  7. The origin of your processing sketch is at the top left side of the screen. This means that all visible X & Y values will be positive. Note that Processing also supports a 3D coordinate system as well – the z axis is positive as it moves “towards” you and goes negative as it recedes away from you.

    Processing coordinate space

    Processing coordinate space

  8. Next we moved on to discuss how to draw shapes. We began by drawing a simple point which is nothing more than a single pixel on your screen. You can ask Processing to draw a single point at any location by using the point function, like this:
    Not incredibly useful, but it’s a start! :)
  9. You’ve probably noticed at this point that the Processing IDE will color code your function calls as you type them.  You can right-click (command click on a Mac) and select “Find in Reference” to open up the Processing document page for that function. You should bookmark this reference page – it contains a ton of useful information that you will constantly be referring when developing an application. You can access the Processing reference page directly by going here: http://processing.org/reference/
  10. Next we began to talk about how to draw lines. Lines take four arguments representing the starting point and the ending point of the line, like this:
    line(x1, y1, x2, y2); 
  11. We then attempted a very simple programming challenge to draw a house. Here’s the code and the resulting masterpiece!
  12. Next we discussed commenting your code, which allows you to leave yourself text-based “notes” so that you can figure out what you were thinking when you open up your source code 6 months from now :). Processing (Java) supports two types of comments:
    // single line comment  
    /* multi line comment */
  13. You can draw an ellipse using the ellipse function, like this:
    ellipse(x, y, width, height);
    
    When the width and height arguments are equal you will draw a circle. Ellipses are drawn from their center point, but you can change this behavior by calling the function ellipseMode() function – it will cause all ellipses from this point forward in your program to be drawn from their top left corner:
    ellipseMode(CORNER);
    
  14. We then added a super-cheesy sun to our little demo scene (but it really looks like a cheesy moon …)
  15. Rectangles can be drawn with the “rect” function, like this:
    rect(x, y, width, height);
    
    Rectangles are drawn from their top left corner You can change this behavior by calling the rectMode() function, like this:
    rectMode(CENTER);
    
    Here’s a our little scene with some rectangles added in for good measure:
  16. The “smooth()” method is used to tell Processing to “smooth” out your shapes and reduce the amount of pixelation you might see around their edges.  You can call it once at the beginning of your program and then forget about it:
    smooth();
    
  17. As you may have seen, drawing in Procesisng is “additive” – shapes drawn to the screen are rendered based on the order they appear in your code. This means that shapes drawn first will appear “behind” shapes drawn on top of them For example, the following code produces the output below – note how the ellipse obscures part of the rectangle:
  18. Primitive shapes in Processing have two visual components – “stroke” and “fill”.  “stroke” refers to the outline of the shape, and “fill” is the color that floods the interior of the shape.
  19. You can change the thickness of your stroke by calling the strokeWeight() function, like this – note that this affects all drawing from this point forward:
    // set outline to 10 pixels 
    // ALL shapes drawn after this will have
    // this stroke weight until you call
    // the strokeWeight function again with
    // a different value
    strokeWeight(10);
    
  20. You can turn off “stroke” by using the noStroke() function – note that calling this function affects ALL drawing operations from that point forward:
    noStroke();
    
  21. Likewise, you can turn off the fill on a shape by calling the noFill() function:
    noFill();
    
  22. Next we discussed the basics of color in Processing. Color is handled using 1 byte per “channel”. Recall that, to a computer, a bit is just a single zero or one, and a byte is 8 bits (eight 0’s and 1’s)  combined into a single value. With one byte we can express 256 possibilities .
    00000000
    00000001
    00000010
    ……………………
    11111101
    11111110
    11111111
    
    (don’t worry, you don’t have to do any binary counting in Processing just yet!)
  23. So a byte gives us 256 possibilities … recall from your study of “lists” in Python that computers generally like to start counting from #0.  Therefore, in Processing we can express colors using the range 0 – 255, where 0 is “no color” in this channel and 255 is “all color” in this channel. 128 would be “half color” in this channel.
  24. For greyscale (i.e. “black and white” color) we can express our choice of color by using the following:
    0   = black 
    128 = 50% black, 50% white 
    255 = white
    We demonstrated this by drawing some ellipses with different greyscale color values:
  25. We then moved on to discuss RGB color.  Recall from Web Design that a pixel can be instructed to glow in 3 different ways: Red, Green and Blue – RGB!  We can address each of these channels separately in Processing by using an “overloaded” version of the fill() function, like this:
    // RGB fill! 
    // Red = 100% 
    // Green = 0% 
    // Blue = 0%; 
    fill(255, 0, 0); 
    ellipse(100,100, 50, 50);
    
    Each channel can be controlled using a separate byte. For example, the following will display a red fill:
    fill(255, 0, 0)
    
    And this will set a blue fill:
    fill(0, 0, 255)
    You can use the digital color meter program (Mac) or color picker application (other platforms) to extract colors as their RGB value. In addition, here’s an RGB color picker that can help you do this via any web browser: http://www.rapidtables.com/web/color/RGB_Color.htm
  26. In graphical applications, “alpha” refers to the level of transparency of a color. Processing supports “alpha” in the same way it supports the other color channels – you can use a single byte (0-255) to determine how much transparency should be included in a color.
    0   = totally transparent (invisible) 
    128 = 50% transparent 
    255 = totally opaque
    
    You can use another overloaded version of the “fill” function to do this:
  27. You can also adjust the color of a shape’s stroke value using the same technique, like this:
  28. If you hate the 0-255 range for colors you can “re-map” it to something more convenient using the colorMode() function, like this:
    colorMode(RGB, 100);
    
    This will allow you to address each channel using a range of 0-100 instead of 0-255
  29. You can change the background color of your sketch by using the background() method, like this:
      background(0,255,0);
    
    Note that calling background will wipe out anything already on your canvas. Essentially it just draws a rectangle across the entire screen with the desired color.
  30. You can write text to the screen using the “text” function, like this:
    This will display the word “hello” at position 150, 150. Note that text is affected by the “fill” color that you specify. You can adjust the font size by calling the textSize() function before calling the text function, like this: // size our canvas size(400,400); // set a larger text size textSize(30); // write some text text(“bigger!” 140, 150); [/ckprocessingeditor]
  31. Sometimes we need to print out a value to the black area below your sketch, known as the “console”. In Processing we often want to do this for “debugging” purposes – it lets us display something to us (the programmer) without affecting the visuals being painted to the screen. You can use the “println()” function to do this:
      println(“something!”); 
    
  32. Next we turned our attention to interactivity. Interactive media experiences play out over multiple “dimensions”, such as:

    • Width
    • Height
    • Depth (sometimes)
    • Time!

    “Time” is the component that is the most overlooked – it’s the invisible “flow” behind the scenes that gives “life” to your programs
  33. Games and interactive multimedia projects require us to write code that will execute over a period of time. We sometimes call this our “game loop” – it’s a region of code that continually executes over and over again. It gives us the ability to modify our media experiences over time.
  34. Processing is built with this idea of “flow” in mind. The framework comes pre-packaged with two special functions that you can use to (1) setup your experience and (2) repeatedly execute code over time to update the experience. These functions are called “setup()” and “draw()” and we will be using them in all of our programs from this point forward. Here’s an example of a bare bones sketch (that does absolutely nothing!):
  35. Both the setup() and draw() function are preceded by the keyword “void”. You can blissfully ignore this if you’d like, but this keyword specifies that these functions don’t have any return values. We’ll talk more about that when we get to functions next week.
  36. You’ll also notice a set of “curly braces” after each function – this is called a “block” – it denotes the beginning and end of the function. Processing isn’t like Python insofar as using “tabs” to denote blocks – you have to use curly braces to mark the boundaries of a function. Note that you don’t place semicolons after a function definition or after curly braces.
  37. In general, things that you want to happen ONE TIME go inside setup. As of now the only things you’d probably put up there is a call to the size() and smooth() methods to set up your canvas. In general, things that you want to happen REPEATEDLY go inside draw. Right now most of your calls to the basic drawing functions (ellipse, rect, etc.) will go inside draw if you want them to be animated.
  38. The draw function executes about 30-60 times a second. When Processing reaches the end of the block attached to the draw() function it will paint the screen without whatever you had chosen to draw during that iteration.
  39. You can request that Processing execute your “draw” function at a different rate by using the frameRate() function:
  40. frameRate(30);
    
    The value passed to frameRate is your desired frame rate in # of frames per second (FPS). The higher this number, the more times your draw loop will execute and the “smoother” your animation will look. With that said, this is just a “request” to Processing – it sometimes can’t give you your desired frame rate due to limitations of your computer’s hardware and software.
  41. Drawing the same thing over and over again inside of the draw() loop results in more or less nothing, like in the following program: 
    In order to take advantage of the draw() loop we need to vary our program over time. One simple way to do this is to use the position of the mouse. Since the mouse has the ability to move in “real-time” we can track its position inside of Processing and use that position to draw something to the screen.
  42. The mouse’s position is exposed to Processing via two variables called “mouseX” and “mouseY”. You can refer to these variables at any point in your program – they are considered global and are accessible inside any function.
  43. Programming Challenge: Write a program that continually draws a line from the center of the screen to the position of the mouse.
  44. Programming Challenge: Write a simple “painting” program that draws an ellipse wherever the mouse is currently positioned on the screen.
  45. Programming Challenge: Write a program that lays down a series of “semi transparent” ellipses as the user moves their mouse.
  46. Programming Challenge: Write a program that moves three ellipses around the screen. The ellipses are “locked” in three horizontal lines, but they will follow the X position of the mouse.
  47. Programming Challenge: Write a program so that instead of painting an ellipse you are simply moving an ellipse around the screen with the mouse (like a cursor).
  48. Programming Challenge: Change your previous sketch so that you print out the mouse’s X and Y position on top of your ellipse as well.
  49. Programming Challenge (advanced!): Change your program so that you are still painting an ellipse to the screen, but your painting should “fade out” over time (i.e. ellipses should slowly disappear)
  50. Processing also exposes the previous position of the mouse via the pmouseX and pmouseY variables. For example, here’s a “scribbler” application that lets the user scribble an un-interrupted line on the screen.
  51. You can add this function to your program if you want to “listen” for when the user presses the mouse:
    void mousePressed()
    {
    
    }
    
    Anything you place inside the block attached to that function will run every time the left mouse button is pressed. Here’s a demo program that lets the user draw on the screen using ellipses – every time you press the mouse it will erase the screen and let you draw a new picture.