eX_04

intro to processing

processing-banner.jpg

If you do not already have this free software installed, head over to Processing.org

Prior to the exercise below, ensure you have:

  1. completed the browser-based One Hour of Code and have
  2. read the first 35 pages of the Processing Handbook.

This tutorial is in two parts:

  • Part I lays out the foundations, while
  • Part II aims to solidify these foundations while outlying ways to begin structuring your own Processing projects.

Overview

Generative (or Algorithmic) art is art or design produced by an artist or designer or anyone who chooses to create and explore imagery by writing computer programs by oneself or with the aid of a programmer.

“Processing integrates a programming language, development environment and a teaching methodology into a unified system. It was created to teach fundamentals of computer programming within a visual context. Students, artists, design professionals and researchers use it for learning, prototyping and production.” (Processing: A Programming Handbook for Visual Designers, Second Edition, Casey Reas and Ben Fry.) It is built on a simplified version of Java.

Objectives

  • Learn enough Processing coding to enable execution of the final project for the ART250 course.
  • Develop a basic understanding and facility for solving visual problems algorithmically.
  • Explore aesthetic ideas and visual structures through algorithmic processing of graphic data with computers.
  • Gain an understanding of basic computer programming through hands-on exploration and creation of images.
  • The focus of these exercises is not on training skilled programmers. Only minimal programming skills are expected. However anyone with previous programming experience is encouraged to explore each exercise as far as they are able.

Resources

Skills Covered 

  • what is a program?
  • statement
  • comments
  • Processing Libraries (extensions to any given program)
  • local vs global variables (variable scope)
  • declarations (as it applies to typing a variable before it can be used)
  • functions
  • x, y coordinates
  • loops
  • global variables

Intermediate Imaging & Sound

  • Translation, rotation and scaling of rectangles and ellipses
  • Animation: Moving graphic objects on the screen for still and moving imagery
  • Using frameCount for controlling scene sequencing
  • Playing and stopping sound at specific frames

Coding for Interactivity


 

Instructions – Part I  

Drawing, Translating Objects, and Audio Integration

 Tutorial designed by Domenic Licata

Tutorial designed by Domenic Licata

 

 

1. Download the ex04-audio files.

Note: the completed sketch can be downloaded here for reference.

2. You’ll need to install the minim library into your Processing environment. Create a File>New sketch. Then choose: Tools>Add Tool>Libraries>Minim>Install. (You only have to do this once per machine.)

Background: Minim is an audio library that allows for integration of sound files within a sketch: Mono and Stereo playback of WAV, AIFF, AU, SND, and MP3 files.

3. Save your sketch to your desktop, naming it "[your last name]-ex4". Be sure to use only lower case letters and no spaces.

Note: Processing places the .pde file into a new folder with the same name as your sketch. These can not be renamed, or complications will occur.

4. Drag the four sound files from the downloaded archive to your new sketch folder: GER_MUE_M.aif; GER_MUE_N.aif; GER_MUE_Y.aif; knock_walk_dooropen.aiff

5. Copy the below code into the new sketch:

// import of the minim library and declaring special AudioPlayer variables
import ddf.minim.*;
Minim minim;
AudioPlayer player1;
AudioPlayer player2;
AudioPlayer player3;
AudioInput input;

// Statements in in setup are only executed once
void setup() {
   size(640, 480);

   // the variable "minim" is called each time a new sound is imported     into the sketch
   minim = new Minim(this);
   player1 = minim.loadFile("knock_walk_dooropen.aiff");
   minim = new Minim(this);
   player2 = minim.loadFile("GER_MUE_Y.aif");
   minim = new Minim(this);
   player3 = minim.loadFile("GER_MUE_M.aif");
   // the sounds do not play until activated
   player1.loop();
} //ends void setup

// Statements in draw are executed repeatedly (looped)
void draw() {
   background(0,0,0);

} //ends void draw

6. Examine and identify the parts of the sketch. Run the sketch and note what happens. Change the color of the background. (Use colorpicker.com to help determine the RGB value of a color of your choosing. Or, if you are on a Mac, do a Finder search for the utility called “Digital Color Meter.”

7. Place the below code just above the setup block. This declares a variable, x, which will be used for timing and the position and size of items in the void draw loop.

int x;

8. Place the below code within the void draw block:

x = x + 1;
if (x > 640) {
   x = 0;
}

ellipse(x, 50, x+10, 60);
fill(150,150,50);

9. Examine and identify the new code. Try changing the arguments within the ellipse function. You may change the color of the ellipse if you wish. Try adding additional shapes (lines, rectangles), etc.

10. Declare two new variables, y and z which will also be used for timing and the position and size of items in the draw loop. Place these below the x variable declaration.

int y;
int z;

11. Paste the below code beneath the background function in the draw loop, before the closing brace }:

 

   // Sets the value of the variable x
   x = x + 1;

   // A conditional that if true resets the value of x to 0
   if (x > 640) {
      x = 0;
   }
   z = z + 1;
   if (z > 120) {
      z = 0;
   }

   fill(150,150,50);
   ellipse(x, 50, x+10, 60); 

   fill(z*2, z*2, z*2);
   ellipse(600-x, 150, x+10, 60); 

   println("z = ", z); 
/* The println function shows the results of an expression in the      console area. It is useful to keep track of numbers as events play out on screen, or to assist in debugging a sketch.*/ 

Run the sketch and notice your changes. Also notice what is being printed to the console.

Note: you are able to print any value, and as many values to the console, either with a print() or println().

12. Remove the background function from the draw loop and place it in void setup, before the closing brace }.

background(0,0,0);

Again, run your sketch and notice what the shapes appear to be doing, now that you are only drawing the background once in setup instead of each loop. This should instill the notion of layering within the image based on line of execution.

13. Place this code within the z conditional statement, before the closing brace }.

/* When the condition for z is true, player2 plays its sound, starting 100ms into the file */
player2.rewind();
player2.play(100);
// A trail is left for every 120 frames, and then the background is redrawn
background(0,0,0);

Note: At this point you may want to do an "auto format" so that the code is more easily readable. This can be found under Edit, or ⌘T. Use this often just like saving and you will save a lot of headaches.

14. Paste this code above the println function to introduce two additional ellipses. Note the timing of all events.

fill(150,150,50);
ellipse(x, 50, x+10, 60); 

fill(z*2, z*2, z*2);
ellipse(600-x, 150, x+10, 60);

note that after adding these two shapes it appears like nothing really happened. Why is this? Can you alter a bit of the step 14 code so that the shapes appear?

15. Save your pde project and save this for later reference.

 

 

Instructions - Part II

Conditional Statements & Advanced Movement

 Tutorial designed by Bernard Aaron Dolecki

Tutorial designed by Bernard Aaron Dolecki

 

1. Download the part 2 zip file and ensure you have the Minimum library installed.

Note: you can compare your sketch with the completed sketch file if you are having any problems.

2. Open the patch and run it. You are presented with a background and some music, but there are no available interactions yet. Close this and look back at the sketch to analyze the content. You will notice that Minim has been initiated and all of the audio files have been declared in void setup

3. Lets add some code. First, let us get a couple shapes moving around. The first thing you should do is declare two new global variables (before void setup). 

int resize;
int grow = 0;
int scene = 0;

4. You will notice that when declaring variables that you can actually assign them an original value. in this case, grow and scene will start off equal to zero.

5. Go ahead and delete the original background being drawn and audio file being played. We will be relocating it.

6. Copy and paste this within void draw() :

if (scene == 0) { //menu

   background(menu);
 
   ouch.pause();
   whatsThis.pause();
   ET.pause();
   nightBefore.pause();

   translate(500, 300); //moves the x, y origin point

   rotate(PI/mouseX+mouseY);
   fill(mouseX/3, mouseY/4, (mouseX+mouseY)/12);
   rect (0, 0, grow+20, grow+20);

   rotate(PI/mouseX - mouseY*2);
   fill(mouseY*3, mouseX/4, (mouseX-mouseY)/10);
   rect (-grow, grow, grow+20, grow+20);

} //ends scene 0

7. You can see that we are starting off with a conditional statement. If scene is zero then do everything between the curly brackets. Well if we look at the global variables we already know that we set scene to zero, and since we have not reassigned a value to it, by default we are then drawing the shapes. Since we are going to have more pages that we can navigate to, it makes sense to have things like the specific background and what audio will be played within this conditional statement.

8. We will cover what 'grow' is in a moment. The function called 'translate' actually moves our origin point from the top left to wherever we specify its new coordinates (in this case the middle of the sketch). We need this because the rotate function works based on the origin. You can comment out the 'translate' and see what happens.

note: note: Take a moment to look over everything that you just pasted. Ask any questions if you do not understand something.

9. Our shapes are a little small and not too exciting. Lets add some math by adding a value to grow. Right now it is originally set to zero but is not changing from that unless we tell it to. This is where processing can get really fun, because anywhere you can use a number you can put an integer. Copy and paste this code into your sketch; put it just after draw and just before the 'if' conditional:

if (resize == 0) { //this tells grow to add to itself
    grow = grow + 1; 
    if (grow == 100) { 
      resize = 1;
    }
  } 
  if (resize == 1) { //this tells grow to subtract from itself
    grow = grow-1; 
    if (grow == 0) { 
      resize = 0;
    }
  }

10. Your void draw should now look something like this:

ex4-2-code-preview.png

Remember you can use ⌘T at any time to organize your code.

11. With that bit of math that we just added you should now have squares that are pulsing. The one conditional statement is adding to grow each cycle, and then a second conditional inside the first sets 'resize' to 1 if grow reaches 100. Now that resize is no longer equal to one, the first conditional is skipped by processing and the second one is now activated where it subtracts one from grow until the cycle reverts again. If you don't understand this, please ask!

12. So let us activate these background arrows by integrating a second scene. While we are currently in scene zero, say we want to click on the ET arrow and go to 'scene 1.' Well once we are in scene 2, this same functionality of clicking on that same spot should be turned off. To do this we must add a new section underneath of draw called "void mousePressed." This will allow us to specify what Processing does when the mouse is pressed, essentially allowing for all of our navigation from scene to scene. For Simplicity sake, copy and paste all this code after void draw ends:

void mousePressed() { //navigation elements between scenes. 
  if (scene == 0) { 
    if (mouseX > 14 && mouseX < 95 && mouseY > 266 && mouseY < 348) {           
      ET.rewind();
      ET.loop();
      scene=1;
    } 
    if (mouseX > 906 && mouseX < 986 && mouseY > 266 && mouseY < 348) { 
      nightBefore.rewind();
      nightBefore.loop();
      scene = 2;
    }
  } //ends scene 0 

  if (scene == 1) { 
    if (mouseX < 150 && mouseY > 525) { 
      elevator.rewind();
      elevator.loop();
      scene = 0;
    } 
    if (mouseX > 850 && mouseY > 525) { 
      nightBefore.rewind();
      nightBefore.loop();
      scene = 2;
    }
  } //ends scene 1 

  if (scene == 2) { 
    if (mouseX < 150 && mouseY < 75) { 
      elevator.rewind();
      elevator.loop();
      scene = 0;
    } 
    if (mouseX > 850 && mouseY < 75) { 
      ET.rewind();
      ET.loop();
      scene=1;
    }
  } //ends scene 2
}//ends mousePressed

13. Run this and note what happens that when you click anywhere but the arrows, nothing happens. This is what we want. We are specifying for the scene to change only when clicked on a navigation element. You will see that in scene zero, the mouse location is specified for only the spots with the arrows. The only thing we are now lacking is the other scene content. Again for the sake of simplicity, copy and paste these other two scenes into the draw section, logically under the scene zero conditional:

if (scene==1) {//ET
    background(finger); 
    //whatsThis.pause(); 
    //elevator.pause(); 
    //nightBefore.pause();  

    if (mousePressed) { 
      if (mouseX > 390 && mouseX < 480 && mouseY > 340 && mouseY < 430) { 
        ouch.rewind(); 
        ouch.play();
      }
    }
  } //ends scene 1 

  if (scene == 2) {//Nightmare Before Christmas
    background(lights); 
    //ouch.pause(); 
    //elevator.pause(); 
    //ET.pause();  

    if (mousePressed) { 
      if (mouseX > 475 && mouseX < 660 && mouseY > 200 && mouseY < 425) { 
        whatsThis.rewind(); 
        whatsThis.play(1);
      }
    }
  } //ends scene 2

14. Before you run the code, look at what is going on. You will see that the scene 1 and 2 conditional sections are quite like scene zero, however they also have an additional conditional embedded in them in the form of a (different style) mouse click. This allows for additional clicking to happen within these scenes without the change of scene. Go ahead and play the sketch.

15. You will note that all of the audio plays but does not stop, and once it is played it will not play again no matter if you trigger it again or not. Just like telling a file to ".play", we can also tell it a few other things like ".rewind", ".pause" or ".loop". The rewind function allows us to set the file back to the start, even after it has been played. So what we must now do is any time we are switching from one scene to another we must start off by stopping previous audio from other scenes from playing. Later on you will also want to put a ".rewind" before most ".play"s so that it is always smooth from the start.

You have to think logically; how will things work when going back and forth between scenes? In the last code you pasted, I have commented out these other audio syntax elements-  you can now just delete the //'s and preview the changes.

16. The one big downfall of this example is that there is no hover options over the mouse buttons. Even though this is not needed for the background arrows, and people can probably figure things out, it is less apparent on ET's finger and Jacks head. By not knowing something is clickable, we are loosing smooth interactivity. What could solve this? Perhaps a different background version that changes bases on a mouse x/y location? Perhaps a mouse rollover effect? 

17. You will probably notice by now that there is a clicking happening when you change audio elements. There is one that does not doe this, which is the "ouch" audio of ET's finger. This is not 100% clear, but that file is 16-bit audio whereas all the rest is only 8-bit. It could be that 8-bits are not liked by processing, or that there is a hiccup by having both 8-bit and 16-bit in the same file. To avoid this happening, you may just want to ensure all your audio is 16-bit.

18. Also note that using photoshop can be helpful when specifying x/y coordinates. You can place your background there and use rulers like this:

photoshop-rulers.jpg

That is all for this tutorial! 

Ensure you are understanding all of the elements that you can. If you finish early, explore changing some of the math and shapes being drawn on scene 0.

When you are satisfied, see if any of your fellow classmates need help. I actually encourage you all to partner up so that you can troubleshoot with two heads rather than one.

If you are still having troubles, look over the final version and compare it with yours and see if you can solve the problem yourself.