// Timothy Liu
// 15104 Section C
// Open Ended-02
// facial features (variables)
var eyeWidth = 25;
var eyeHeight = 15;
var pupilWidth = eyeWidth / 2;
var pupilHeight = 11 * eyeHeight / 16;
var noseWidth = 15;
var noseHeight = 40;
var earSize = 30;
var headWidth = 125;
var headHeight = 150;
var mouthWidth = 60;
var mouthHeight = 40;
var mouthStart;
var mouthEnd;
var skin1 = "#FFD3A1";
var eyeL;
var eyeR;
// body shape and size (variables)
var bodyWidth = 200;
var bodyHeight = 370;
var colorR = 105;
var colorG = 64;
var colorB = 122;
// hat dimensions and color (variables)
var hatR = 14;
var hatG = 28;
var hatB = 117;
var hatBottom;
// function time!
function setup() {
createCanvas(600, 480);
mouthStart = TWO_PI;
mouthEnd = PI;
eyeL = width / 2 - headWidth / 5;
eyeR = width / 2 + headWidth / 5;
hatBottom = height / 4 - headHeight / 6;
// initializing P5.js functions in setup()
}
function draw() {
// background color
background(240, 196, 101);
noStroke();
// ears
fill(skin1);
ellipse(width / 2 - headWidth / 2, height / 4, headWidth / 8, headHeight / 6);
ellipse(width / 2 + headWidth / 2, height / 4, headWidth / 8, headHeight / 6);
// neck
fill(skin1);
rect(width / 2 - headWidth / 4, height / 4 + headHeight / 4, headWidth / 2, headHeight);
// head and face
fill(skin1);
ellipse(width / 2, height / 4, headWidth, headHeight);
// bucket hat
fill(hatR, hatG, hatB);
quad(width / 2 - headWidth / 2, hatBottom, width / 2 - headWidth / 3, height / 4 - headHeight / 2,
width / 2 + headWidth / 3, height / 4 - headHeight / 2, width / 2 + headWidth / 2, hatBottom);
rect(width / 2 - 2 * headWidth / 3, hatBottom, headWidth * 1.35, headWidth / 32);
// eyeballs
fill("white");
ellipse(eyeL, height / 4 - height / 48, eyeWidth, eyeHeight);
fill("white");
ellipse(eyeR, height / 4 - height / 48, eyeWidth, eyeHeight);
// pupils
fill(59, 35, 18);
ellipse(eyeL, height / 4 - height / 48, pupilWidth, pupilHeight);
fill(59, 35, 18);
ellipse(eyeR, height / 4 - height / 48, pupilWidth, pupilHeight);
// nose
fill("#D39972");
arc(width / 2, height / 4 + headHeight / 8, noseWidth, noseHeight, PI, TWO_PI);
// mouth
fill(255, 150, 150);
arc(width / 2, height / 3, mouthWidth, mouthHeight, mouthStart, mouthEnd, CHORD);
// body and shirt
fill(colorR, colorG, colorB);
arc(width / 2, 5 * height / 6, bodyWidth, bodyHeight, PI, TWO_PI);
// pants
fill("#003366");
rect(width / 2 - bodyWidth / 2, 5 * height / 6, bodyWidth, height / 6);
// thigh gap
fill(240, 196, 101);
rect(width / 2 - bodyWidth / 8, 15 * height / 16, bodyWidth / 4, bodyWidth / 4)
}
function mousePressed() {
// brackets to denote an array. The coinFlip variable helps determine whether it's a smile or frown.
var coinFlip = random([0, 1]);
// randomly generating head proportions including eyes, face size, pupil, nose, and mouth.
headWidth = random(100, 200);
headHeight = random(121, 180);
eyeWidth = random(15, 40);
eyeHeight = random(10, 20);
eyeL = width / 2 - headWidth / 5;
eyeR = width / 2 + headWidth / 5;
pupilSize = 9 * eyeWidth / 16;
noseWidth = random(10, 30);
noseHeight = random(20, 50);
mouthWidth = random(20, 60);
mouthHeight = random(20, 60);
// randomly generating body size and color.
bodyWidth = random(170, 350);
colorR = random(0, 255);
colorG = random(0, 255);
colorB = random(0, 255);
// randomly generating hat color.
hatR = random(0, 255);
hatB = random(0, 255);
hatG = random(0, 255);
// this is an array of different hex values for skin tones.
// the program randomly selects a skin tone every time the mouse is pressed.
skin1 = random(["#FFD3A1", "#F5CB9A", "#C39582", "#FFCEB4", "#A57E6E", "#EABD9D", "#FFCEB4", "#DEAB7F", "#FFDCB1"]);
// this if statement helps determine whether the character is smiling or frowning using the coinFlip variable defined above.
if (coinFlip == 0) {
mouthStart = 6.28;
mouthEnd = 3.14;
// Smiley mouth
} else {
mouthStart = 3.14;
mouthEnd = 6.28;
// Frowny mouth
}
// condition to ensure that the Smiley mouth never sticks out past the chin
// note: this was originally an if-and statement, but the ampersand was causing issues with WordPress embedding.
if (mouthStart == 6.28) {
if ((height / 3 + mouthHeight) > (height / 4 + headHeight / 2)) {
mouthHeight = mouthHeight / 2;
}
}
// condition to ensure Frowny mouth never touches the nose
if (mouthStart == 3.14) {
if ((height / 3 - mouthHeight) < (height / 4 + headHeight / 8 + noseHeight)) {
mouthHeight = mouthHeight / 2;
}
}
}
This project was a fun challenge for me because it required a heavy amount of step-by-step variable referencing, but it also encouraged me to think very logically. Every time I set up coordinates, I actively made sure to question if I could use a variable to simplify my code, and this made it significantly easier to randomize the face (as well as other features) later because all of my variables were already consolidated.
I enjoyed getting to play with an abstract art style, and I made my characters reflect that; they each have simplified features, but my program incorporates a wide array of body types and shapes. I’ve come away from this project with a much stronger understanding of how to utilize local and global variables, as well as how to use if-else statements to set up different conditions to ensure my faces didn’t distort in odd ways.