We're going to learn to add some basic interactivity to our face, first by making it respond to mouse movement, then by tweaking that code so it responds to sounds picked up by the microphone.
This project requires your computer to have a microphone attached. If not, that's okay. You can either do the mouse-movement part of this unit, or move onto the next unit, making a "mischievous" painting program using mouse and keybord input.
1. We're going to start with a basic Processing sketch that draws a face. Feel free to copy and paste this code into Processing to follow along, or use your own face project as the basis.
2. To make our project interactive, we need to divide the code into two 'functions.' A function is a named chunk of code that does a specific job. Every interactive P5 project has at least these two functions:
function setup() - Runs once at the beginning. This is where we set the size, and generally "set things up." function draw() - Runs over and over again, constantly. This is generally where we "draw" shapes and things. Since its constantly drawing over and over, we can change the drawing to make things animate and move!
Look at the lines added to the code below. The only command in our setup() function is the createCanvas() command, and we put everything else in the draw() function. Notice how every function name ends with "()" parentheses, and the contents of every function is contained within "{}" curly braces.
function setup(){
createCanvas(400, 300); //sets the size for the window
}
function draw(){
background(0, 200, 100);
strokeWeight(4);
fill(255, 0, 100);
stroke(100, 0, 50);
rect(100, 250, 200, 100, 35); //shoulders
ellipse(200, 150, 150, 200); //face
strokeWeight(1);
stroke(0,0,0);
fill(255,255,255);
ellipse(250, 150, 20, 20); //eye
ellipse(150, 150, 20, 20); //eye
fill(255,255,0);
stroke(150,100,0);
ellipse(200, 180, 20, 40); //nose
strokeWeight(2);
stroke(100, 0, 50);
line(150, 210, 200, 205);//mouth part 1
line(200, 205, 250, 210);//mouth part 2}
3. Now we're going to create our first variable in Processing. A variable is a value that can change, which we give a name to. The name can be as simple as 'x' or as complex as 'iceCreamSandwichesEatenOnWednesday' though we try to keep them short.
Our variable will be called 'eyemove,' since we're going to store a number in it that will change, and will cause our face's eyes to change. The code "var eyemove;" tells Processing to make a new variable named "eyemove".
We'll add the code at the very beginning of our program, outside of any function, so both functions can use it.
Inside the draw() function, we'll add a line of code to give eyemove a value:
eyemove = mouseX;
This code sets eyemove equal to the horizontal position ('x') of the mouse in the screen. Lower down, we'll change the code where we drew the eyes, and replace the '20' we put for width and height with 'eyemove.' Now the eye size will change based on mouse position!
Try adding the following code to your sketch and trying it out:
var eyemove;
function setup(){
createCanvas(400, 300); //sets the size for the window
}
function draw(){
eyemove = mouseX;
background(0, 200, 100);
strokeWeight(4);
fill(255, 0, 100);
stroke(100, 0, 50);
rect(100, 250, 200, 100, 35); //shoulders
ellipse(200, 150, 150, 200); //face
strokeWeight(1);
stroke(0,0,0);
fill(255,255,255);
ellipse(250, 150, eyemove, eyemove); //eye
ellipse(150, 150, eyemove, eyemove); //eye
fill(255,255,0);
stroke(150,100,0);
ellipse(200, 180, 20, 40); //nose
strokeWeight(2);
stroke(100, 0, 50);
line(150, 210, 200, 205);//mouth part 1
line(200, 205, 250, 210);//mouth part 2
}
4. It moves! But maybe a bit too much. Since our window is 400 pixels wide, mouseX ranges from 0 to 400. So when we wiggle our mouse, the eyes go from 0 to 400 pixels wide. We're going to use a command called 'map()' to adjust the effect the mouse has on the eyes. 'map()' takes a value between two numbers, and 'maps' it onto a value between two different numbers. For example, this sketch maps the mouse's X position between 0 and 500 onto a new number, named 'redBarX,' between 200 and 300. You can see the effect - when you move the mouse from 0 to 500, the red bar only moves from 200 to 300:
Here is the actual map() code we're going to add to our program.
eyemove = map(mouseX, 0, width, 20, 50);
It maps 'mouseX' between 0 and the width of our screen, onto 'eyemove' between 20 and 50. So when we move our mouse across the screen, the eyes will just grow from 20 pixels wide to 50.
Try adding the following code to your sketch and trying it out:
var eyemove;
function setup(){
createCanvas(400, 300); //sets the size for the window
}
function draw(){
eyemove = map(mouseX, 0, width, 20, 50);
background(0, 200, 100);
strokeWeight(4);
fill(255, 0, 100);
stroke(100, 0, 50);
rect(100, 250, 200, 100, 35); //shoulders
ellipse(200, 150, 150, 200); //face
strokeWeight(1);
stroke(0,0,0);
fill(255,255,255);
ellipse(250, 150, eyemove, eyemove); //eye
ellipse(150, 150, eyemove, eyemove); //eye
fill(255,255,0);
stroke(150,100,0);
ellipse(200, 180, 20, 40); //nose
strokeWeight(2);
stroke(100, 0, 50);
line(150, 210, 200, 205);//mouth part 1
line(200, 205, 250, 210);//mouth part 2
}
5. Much better! Now, we can use these same techniques to add more variation to our face's movement, all tied to our MouseX value.
Below, I've added a few more variables, and 'mapped' the mouse movement onto them, then put them into different lines of code in my drawing. You not only can change the size of shapes, but their positions - and by adding variables to the fill() commands, you can also make colors change, too!
Try adding the following code to your sketch and trying it out, or play around with making other changes:
var eyemove;
var headcolor;
var headsize;
var mouthmove;
function setup(){
createCanvas(400, 300); //sets the size for the window
}
function draw(){
eyemove = map(mouseX, 0, width, 20, 50);
headcolor = map(mouseX, 0, width, 0, 100);
headsize = map(mouseX, 0, width, 1, 1.5);
mouthmove = map(mouseX, 0, width, 0, 50);
background(0+headcolor, 200+headcolor, 100-headcolor);
strokeWeight(4);
fill(255, 0, 100-headcolor);
stroke(100, 0, 50);
rect(100, 250, 200, 100, 35); //shoulders
ellipse(200, 150, 150*headsize, 200*headsize); //face
strokeWeight(1);
stroke(0,0,0);
fill(255,255,255);
ellipse(250, 150, eyemove, eyemove); //eye
ellipse(150, 150, eyemove, eyemove); //eye
fill(255,255,0);
stroke(150,100,0);
ellipse(200, 180, 20, 40); //nose
strokeWeight(2);
stroke(100, 0, 50);
line(150, 210, 200, 205+mouthmove);//mouth part 1
line(200, 205+mouthmove, 250, 210);//mouth part 2
}
6. Now the face reacts to our mouse. But lets add another dimension of interaction. To do this, we'll tweak our code a little to use m-responsive code in P5.
To begin, we're going to add some code to make our program start listening to the microphone. First, we'll create a variable called mic to keep track of our microphone's status (which, as far as the computer is concerned, is just another number to track). Then in our setup() function, we'll add mic = new p5.AudioIn();, which connects our 'mic' variable to the data coming in from the actual microphone. After that, we'll add mic.start();, which "turns on" the microphone so we can use it. Finaly, in the draw() function, we'll add var vol = mic.getLevel();, which creates a new variable called "vol" and stores a number between 0 and 1 representing the volume of the microphone.
var eyemove;
var headcolor;
var headsize;
var mouthmove;
var mic; //variable to control our mic
function setup(){
createCanvas(400, 300); //sets the size for the windowmic = new p5.AudioIn();//connect variable to microphone
mic.start();//turn on mic
}
function draw(){
var vol = mic.getLevel(); //store mic volume in 'vol'
eyemove = map(mouseX, 0, width, 20, 50);
headcolor = map(mouseX, 0, width, 0, 100);
headsize = map(mouseX, 0, width, 1, 1.5);
mouthmove = map(mouseX, 0, width, 0, 50);
background(0+headcolor, 200+headcolor, 100-headcolor);
strokeWeight(4);
fill(255, 0, 100-headcolor);
stroke(100, 0, 50);
rect(100, 250, 200, 100, 35); //shoulders
ellipse(200, 150, 150*headsize, 200*headsize); //face
strokeWeight(1);
stroke(0,0,0);
fill(255,255,255);
ellipse(250, 150, eyemove, eyemove); //eye
ellipse(150, 150, eyemove, eyemove); //eye
fill(255,255,0);
stroke(150,100,0);
ellipse(200, 180, 20, 40); //nose
strokeWeight(2);
stroke(100, 0, 50);
line(150, 210, 200, 205+mouthmove);//mouth part 1
line(200, 205+mouthmove, 250, 210);//mouth part 2
}
7. Now that we've added that code, we're ready to make our image sound responsive with a few easy tweaks!
In our "map" functions, we'll replace "mouseX, 0, width" with "vol, 0, 1" so instead of taking in the mouse's x movement from 0 to the width of the screen, it will instead read the volume between 0 and 1.
...and that's it! When you run your program, the image should respond to the sounds heard by the microphone.
var eyemove;
var headcolor;
var headsize;
var mouthmove;
var mic; //variable to control our mic
function setup(){
createCanvas(400, 300); //sets the size for the window
mic = new p5.AudioIn();//connect variable to microphone
mic.start();//turn on mic
}
function draw(){
var vol = mic.getLevel(); //store mic volume in 'vol'
eyemove = map(vol, 0, 1, 20, 50);
headcolor = map(vol, 0, 1, 0, 100);
headsize = map(vol, 0, 1, 1, 1.5);
mouthmove = map(vol, 0, 1, 0, 50);
background(0+headcolor, 200+headcolor, 100-headcolor);
strokeWeight(4);
fill(255, 0, 100-headcolor);
stroke(100, 0, 50);
rect(100, 250, 200, 100, 35); //shoulders
ellipse(200, 150, 150*headsize, 200*headsize); //face
strokeWeight(1);
stroke(0,0,0);
fill(255,255,255);
ellipse(250, 150, eyemove, eyemove); //eye
ellipse(150, 150, eyemove, eyemove); //eye
fill(255,255,0);
stroke(150,100,0);
ellipse(200, 180, 20, 40); //nose
strokeWeight(2);
stroke(100, 0, 50);
line(150, 210, 200, 205+mouthmove);//mouth part 1
line(200, 205+mouthmove, 250, 210);//mouth part 2
}
THAT'S IT! You now know all the code you need to do this assignment, and make your Processing face sound-responsive. Look at the examples below, then look at the "Assignment" link for the resources and requirements.
The examples included here respond instead to mouse movement, since it can cause problems to have multiple programs all listening to the mic at once - but now you know how to tweak them to make them sound responsive, if you want!