Using your best skills of observation, attempt to draw a portrait of a partner. Consider skin, hair, eyes, features, clothing and accessories. Drawing a portrait is already difficult. Please exercise generosity in your “code sketching,” both in the creation of a sketch of your neighbor and in how you judge someone’s style and accuracy in “code sketching.”
Start to create a face as detailed as you can, with hair, all facial features, potentially even hat, glasses, shirt, and what else?
rect(width/2,height/2,100,100);
ellipse(width/2,height/2,100,100);
triangle(width/2,height/2,100,300,300,300);
function setup() {
// Create the canvas
createCanvas(720, 400);
background(200);
// Set colors
fill(204, 101, 192, 127);
stroke(127, 63, 120);
// A rectangle
rect(40, 120, 120, 40);
// An ellipse
ellipse(240, 240, 80, 80);
// A triangle
triangle(300, 100, 320, 100, 310, 80);
// A design for a simple flower
translate(580, 200);
noStroke();
for (let i = 0; i < 10; i ++) {
ellipse(0, 30, 20, 80);
rotate(PI/5);
}
}
You can change the defaults of how our shapes are drawn
rectMode(CENTER); //default is CORNER
rect(width/2,height/2,100,100);
ellipseMode(CORNER); //default is CENTER
ellipse(width/4,height/4,100,100);
We use beginShape() and endShape() to create more complex shapes not built into p5.js. Between these two commands we use vertex(x,y);
to specify points.
Start with:
beginShape();
//or
beginShape(LINES);
//or
beginShape(POINTS);
Specifying POINTS, LINES, or additional options tells the program what kind of shape we’ll be creating from specified ertices (aka the points).
Then specify your vertices points between.
Then close with:
endShape();
//or
endShape(CLOSE);
Examples:
function setup() {
createCanvas(600, 500);
background(240);
fill(40);
noStroke();
beginShape();
vertex(0, height);
vertex(width * 0.2, height * 0.4);
vertex(width * 0.35, height * 0.6);
vertex(width * 0.50, height * 0.2);
vertex(width * 0.70, height * 0.5);
vertex(width * 0.85, height * 0.3);
vertex(width, height);
endShape();
noLoop();
}
–Example from Rune Madsen’s Programming Design Systems
The stroke is our ‘line’ outlining basic shapes.
Turn off lines
noStroke();
To turn them back on, you must specify a color.
stroke(0); //black
Two squares:
change the stroke line color
Variables are symbolic containers. It is a symbol that contains a value that you want to change while your program is running. An example is age. I always have an age, but the value of age changes over time. Each year that I continue to run, the value of my age increases by 1. When I was born my age was 0. A year later on my birthday, 1 was added to my age. A year after that another 1 was added to my age. And so on.
In your code sketch, any value that you want to change over time should be a variable. You have already been working with built-in variables, mouseX and mouseY. As a test, let’s print out the value of mouseX.
function setup(){
createCanvas(200,200);
}
function draw(){
print(mouseX);
}
Run the program and look in the console. As you move around the mouse, draw is continuously (approximately 60 times a second) printing the variable mouseX’s value. Notice that if you hold the mouse in one spot the value doesn’t change. What happens when you move the mouse off the canvas?
We can also create our own variables. There are two parts to create a variable: declaring and initializing.
Declaring is when you name a variable. You are telling the program “I want a variable. I’m calling it age.”
In some languages, you have to specify what kind of variable you want depending on what you want it to hold, like a decimal, a word, a whole number, or something else. In p5.js (and Javascript), you only have to say let
to show you want a variable and follow it with the name of the variable you would like. (Note: Several years ago it was common to use var
instead of let
and you will sometimes see that instead. For our purposes, they are interchangeable!)
let age;
After you declare a variable you need to set it to some value. This is called initializing a variable.
age = 22;
We can also set a variable equal to an equation, including with other variables.
let myAge
let mySistersAge;
myAge = 54;
mySistersAge = myAge - 3;
You can initialize and declare a variable at the same time.
Example
let myAge = 28;
When you get stuck while programming, you might be confused why your program is acting a certain way. Many times, it’s because your variable is not set to what you think it should be set to. We can use the print command to tell us the value of a variable. You can print text and/or the value of a variable. It will appear in the console.
example
print("mouseX is "+mouseX);
In Javascript, the location where you declare your variable is important. It sets where you are allowed to use that variable’s value in the rest of your program.
If you declare a variable inside a function then it cannot be used inside other functions.
To be able to use a particular variable anywhere in your program, you need to declare it globally. By habit, most programmers will declare their variables at the very top of their program, before their setup.
Example with a global variable, accessible everywhere
let mySistersAge = 24;
function setup(){
noCanvas(); //use this when you don't need a canvas
print("My sister's age is "+mySistersAge);
}
Example with a local variable, only accessible inside its own function
function setup(){
noCanvas();
let mySistersAge = 24;
}
function draw(){
print("My sister's age is "+mySistersAge);
//THIS WILL CREATE AN ERROR!
}
This will not work and instead create an error in the console. It does not work because the variable mySistersAge was created inside the setup function. This means it is a local variable that can only work inside setup and therefore will not work inside the draw function. To have it work in both, it needs to be created globally, outside of these functions, and best practices is to create it at the top of the program. Note: it is where the variable is declared (not initialized) that sets whether it is local or global.
We are used to reading from left to right.
But when you set the value of a variable you first take everything to the right of the equal sign and that value is placed in the variable.
Take the following example. What do you expect to see?
let ballX=0;
function setup(){
createCanvas(200,200);
}
function draw(){
ellipse(ballX,height/2,20,20);
ballX = ballX + 1;
}
The line ballX = ballX + 1
may look strange but it’s perfectly valid. We start on the right side of the equal sign, so we are taking the current value of ballX, whatever it is, and adding 1 to it. When the program starts, ballX has been set to 0. So 0 + 1 is 1. Finally, we look on the left side of the equal sign. We see ballX there, so we set ballX equal to that amount, 1. The next time we run draw we start on the right side of the equal sign. ballX is 1 and we add 1 to it, totalling 2. So we set ballX (which is on the left side of the equal sign) to be 2.
There are some shorthand ways to increase or decrease a variable. To simplify writing someVariable = someVariable + 1;
you can instead write someVariable++;
Likewise, if you want to write someVariable = someVariable - 1;
that can be simplified as someVariable--;
. The number doesn’t always have to change by 1. If you want to increase a variable by the number 10 for example, instead of someVariable = someVariable+10;
you can write someVariable += 10;
.
How do we get a random number? We can ask a friend, try to pick one without thinking too hard, or look up a number in a book. In programming, there are a number of ways to generate a random number. p5.js has the random
function.
By itself, random will generate a random decimal (called a float) between 0 and 1. Commonly, we will want to get a random number between a certain minimum and maximum value. We can specify this range and get a result.
let myNum = random(10,100);
print(myNum); //will print a number between 10 and 100, like 76.87680
If you want an integer, a whole number, you need to round it.
let myNum = round(random(10,100));
print(myNum); //will print a whole number between 10 and 100, like 76
If you want to create a random global variable you must first declare it globally at the start before setup, and then initialize it with random in the setup after you’ve created your canvas.
Revisit your portrait code sketching from earlier. Start by duplicating it so you have a copy of the code that you can now work with and alter.
Now try adding global x and y variables such as eyeX, eyeY and eyeWidth and eyeHeight, mouthWidth, mouthHeight. Create these as global variables and try running the program several times with different values based on using random numbers. Hint: you’ll generally need to set a minimum and maximum value.
In the above section we created a ball, then changed its x location by having the ballX variable increase. The ball kept moving to the right and eventually moved off the screen. How do we get it back if the program keeps running?
A conditional is a test. We can state it like this: If this thing is true, then do this:
The way we do this in code is with an IF statement.
In p5.js it looks like this.
let myName = 'Lee';
if (myName == 'Lee'){
print('Hi Lee');
}
The if tells the software to evaluate whatever follows that in the ( ) parenthesis. If what is in the parenthesis is true, then it will do the action within the following { } brackets.
What’s with the double equal sign? Due to the way the software works, if you use a single equal sign, the program will immediately take anything to the right of the equal sign and place it in the variable on the left. And then since they are equal, the if statement will say, yes, it’s true and then always perform the actions in the following { } brackets. To get around this issue, when we are coding we use the double equal sign == which means test if they are equal.
//NOTE THIS PROGRAM IS SHOWING A MISTAKE!
let myName = 'Pierre';
if (myName = 'Lee'){ //this line has a mistake! should be ==
print('Hi Lee'); //This will print out because of the mistake above!
}
Now that we know about conditionals, we can fix our moving ball program from earlier. Now we will add a conditional statement. If the ball goes off screen to the right, let’s have it appear again on the left side of the canvas. How do we do this? Let’s check where the ball’s x position is located.
let ballX = 0;
function setup(){
createCanvas(200,200);
}
function draw(){
ellipse(ballX,height/2,20,20);
ballX++;
if (ballX > 200){
ballX = 0;
}
}
We have already learned about the builtin variables mouseX and mouseY. There are also the builtin variables width
and height
, that are set to the width and height of the canvas once createCanvas in setup runs. In our code above we can replace the line if (ballX > 200){ }
with if (ballX > width){ }
Sometimes we need to be able to choose from several options. We use else and else if to create the options.
let parkingTickets = 120;
if (parkingTickets < 50){
print("That's annoying, but you can pay that.");
} else if (parkingTickets < 80){
print("Better pay off that bill and try to save some money.");
} else {
print("That's so much money. Better wise up! You owe $"+parkingTickets);
}
else is the default. If nothing else is true in the if and else if statements then the else statement will be executed.
Sometimes it’s not enough to test one thing. You can use and, or.
&&
= AND
||
= OR
example
if ((myName == 'Lee') && (myAge < 60)){
print("that's probably him");
}
Revisit your coding assignment from our class warmup.
This week we are practicing working with interactivity and randomness.
Make sure you are working on a duplicate (file > duplicate) of your previous code sketch.
Now start by creating global variables for elements of your sketch. You can create variables for x, y locations, colors, widths, etc. Use variable names that are descriptive. Examples:
eyeballLeftX
noseWidth
mouthColor
faceHeight
pupilR
earX
Now introduce some randomness to your sketch. It is recommended you set the value in setup, not draw, so that you only get a random result once and not in a rapid loop in draw. Remember that you can set the minimum and maximum variable range.
For example, if you want the left eyeball’s X to be within a rango of 100 or 200 in the X, and a random shade of gray, you could do:
let leftEyeballX;
let leftEyeballGrayness;
void setup(){
createCanvas(500,500);
leftEyeballX = random(100,200);
leftEyeballGrayness = random(100,150);
}
void draw(){
fill(leftEyeballGrayness);
ellipse(leftEyeballX,100,15,15);
//DRAW THE REST OF THE FACE HERE
//
}
Use at least 10 variables, though you can use much more if you like.
In addition to these variables, be sure to use mouseX and mouseY somewhere in your sketch so that the user’s interactivity (moving the mouse in this case) alters some fundamental part of the sketch, such as background colors, placement of a body, etc.
You may find that you are struggling a little with randomness in your sketch. Maybe the random numbers you generate are all over the place, or maybe using mouseX is wreaking havoc because the numbers get too high. We can use constrain to limit our variables and map too stretch out, shrink or reverse our variable number range.
Let’s start with constrain:
let newX = constrain(mouseX,50,340);
In the above code, even though newX is a copy of mouseX, a built-in variable that can normally go from 0 to the width of our canvas, we have created a new variable newX that has a minimum of 50 and max of 340.
Here’s an example with map:
let newY = map(mouseY,0,400,400,0);
In this example, even though mouseY goes from 0 to 400, now we are forcing newY (a copy of mouseY) to reverse and change from 400 to 0 as we move down the page.