// Catherine Coyle
// ccoyle@andrew.cmu.edu
// Section C
// Project 6 - Abstract Clock
var notes = [];
var audience = [];
var mouthY = 120;
var dir = .3;
function setup() {
createCanvas(480, 480);
}
function draw() {
var H = hour() % 12;
var M = minute();
var S = second();
// this accounts for an off by 1 error that happens in the afternoon
if (hour() > 12) {
H = (hour() % 12) - 1;
}
// resetting the storage of notes/audience members every
// new minute/new hour
if (S == 0) {
notes = [];
}
if (M == 0) {
audience = [];
}
// the basic bg art of the clock is gonna be really complicated
// so to keep draw() from getting too messy im doing it
// in another function
drawBG();
// generating randomized notes
for(var i = 0; i < S; i++) {
// only add on one per draw call so its not
// generating a ton of notes every second
if (i == notes.length) {
notes.push([random(15,width-10), random(height / 2),
random(-3,3), random(-3,3), 1, 1]);
}
}
// do same thing for minutes
for(var i = 0; i < M; i++) {
if (i == audience.length) {
audience.push([random(20, width - 20), random(height / 2 + 80, height - 20)]);
}
}
// i want to draw the notes and have them float around!
for(var i = 0; i < notes.length; i++) {
// 0 is x, 1 is y, 2 is xvel, 3 is yvel, 4 is xdir, 5 ydir
notes[i][0] += notes[i][4] * notes[i][2];
if (notes[i][0] > width - 10 || notes[i][0] < 15) {
notes[i][4] = -1 * notes[i][4]
}
notes[i][1] += notes[i][5] * notes[i][3];
if (notes[i][1] > height / 2 + 20 || notes[i][1] < 0) {
notes[i][5] = -1 * notes[i][5];
}
// this whole thing is just basic movement stuff
// but it looks more complicated bc the values are stored in
// nested lists
drawNote(notes[i][0], notes[i][1]);
}
// partially hardcoding drawing locations for coffee cups (hours)
for(var i = 0; i <= H; i++) {
if (i < 3) {
drawCoffee(25 + i*45, height / 2 + 20);
}
if ((i >= 3) & (i < 5)) {
drawCoffee(50 + (i - 3) * 45, height / 2 - 23);
}
if (i == 5) {
drawCoffee(75 + (i - 5) * 45, height / 2 - 65);
}
if ((i > 5) & (i < 9)) {
drawCoffee(width - 10 - (i - 5) * 45, height / 2 + 20);
}
if ((i >= 9) & (i < 11)) {
drawCoffee(width - 35 - (i - 8) * 45, height / 2 - 23);
}
if (i == 11) {
drawCoffee(width - 105, height / 2 - 65);
}
}
// i want him to be in front of the music
drawKK();
// the audience (minutes) are randomized in front of him
for(var i = 0; i < audience.length; i++) {
drawAudience(audience[i][0], audience[i][1]);
}
// i want his mouth to move as he sings!
mouthY += dir;
if (mouthY > 128) {
dir = -dir;
}
if (mouthY < 120) {
dir = -dir;
}
// drawing the actual mouth
fill(0);
stroke(0);
strokeWeight(3);
line(width / 2, 105, width / 2, 115);
line(width / 2, 115, width / 2 + 10, 120);
line(width / 2, 115, width / 2 - 10, 120)
noStroke();
quad(width / 2 + 10, 120, width / 2, 115, width / 2 - 10, 120, width / 2, mouthY);
// i want him to blink too
drawEyes(S);
drawSpotlight();
}
// everything below here is less coding magic and
// more magic numbers for graphics
function drawBG() {
noStroke();
background(193, 120, 51);
// platform top
fill(197, 155, 113);
rect(0, height / 2 + 40, width, 200);
// platform front
fill(132, 62, 11);
rect(0, height / 2 + 70, width, 200);
}
function drawKK() {
// stool legs
fill(209, 175, 66);
rect(width / 2 - 60, height / 2, 20, 60);
rect(width / 2 + 40, height / 2, 20, 60);
fill(201, 146, 58); // back leg
rect(width / 2 - 10, height / 2, 20, 45);
// stool
fill(201, 146, 58); // stool shadow
ellipse(width / 2, height / 2 + 3, 150, 38);
fill(209, 175, 66); // this is the main stool color
ellipse(width / 2, height / 2, 150, 30);
// kk body
fill(255);
ellipse(width / 2, 180, 90, 120)
fill(247, 242, 234); // kk shadow color
ellipse(width / 2, 110, 68, 68);
// kks head
fill(255);
ellipse(width / 2, 75, 90, 90);
ellipse(width / 2, 100, 70, 70);
// eyebrowsss
fill(0);
ellipse(width / 2 + 22, 65, 23, 25);
ellipse(width / 2 - 22, 65, 23, 25);
fill(255);
ellipse(width / 2 + 22, 70, 24, 15);
ellipse(width / 2 - 22, 70, 24, 15);
// ears
noStroke();
fill(255);
triangle(width / 2 + 40, 40, width / 2 + 60, 40, width / 2 + 57.5, 70);
triangle(width / 2 - 40, 40, width / 2 - 60, 40, width / 2 - 57.5, 70);
// right leg
ellipse(width / 2 + 25, height / 2 - 10, 35, 100);
fill(247, 242, 234);
ellipse(width / 2 + 30, height / 2 + 40, 30, 30);
fill(255);
ellipse(width / 2 + 30, height / 2 + 35, 30, 30);
//left leg
fill(255);
ellipse(width / 2 - 15, height / 2 - 5, 70, 35);
fill(247, 242, 234);
ellipse(width / 2 + 18, height / 2, 20, 28);
fill(255);
ellipse(width / 2 + 15, height / 2, 20, 30);
// guitar neck
fill(160, 109, 27);
rect(width / 2, height / 2 - 60, 130, 20);
fill(102, 69, 17);
rect(width / 2 + 120, height / 2 - 62.5, 30, 25);
fill(183, 177, 167); // little knobs at the end
ellipse(width / 2 + 125, height / 2 - 65, 4, 4);
ellipse(width / 2 + 135, height / 2 - 65, 4, 4);
ellipse(width / 2 + 145, height / 2 - 65, 4, 4);
ellipse(width / 2 + 125, height / 2 - 35, 4, 4);
ellipse(width / 2 + 135, height / 2 - 35, 4, 4);
ellipse(width / 2 + 145, height / 2 - 35, 4, 4);
// guitar body
fill(209, 175, 6);
beginShape();
curveVertex(192, 220);
curveVertex(181, 188);
curveVertex(187, 160);
curveVertex(199, 153);
curveVertex(221, 156);
curveVertex(234, 163);
curveVertex(247, 162);
curveVertex(256, 160);
curveVertex(267, 167);
curveVertex(277, 188);
curveVertex(277, 205);
curveVertex(268, 213);
curveVertex(254, 214);
curveVertex(239, 213);
curveVertex(228, 217);
curveVertex(210, 221);
curveVertex(185, 211);
curveVertex(181, 188);
curveVertex(183, 173);
endShape();
// guitar details
fill(175, 123, 40); // background thing
ellipse(width / 2 + 3, height / 2 - 45, 30, 20);
fill(102, 69, 17); // hole
ellipse(width / 2 + 10, height / 2 - 52, 25, 25);
ellipse(width / 2 - 30, height / 2 - 52, 10, 25);
// kks hands
fill(255);
ellipse(width / 2 - 55, height / 2 - 75, 30, 30);
ellipse(width / 2 + 70, height / 2 - 35, 30, 30);
}
function drawCoffee(x, y) {
// mug
noStroke();
fill(255);
rect(x, y, 30, 40);
ellipse(x + 15, y, 30, 5);
ellipse(x + 15, y + 40, 30, 5);
// handle
stroke(255);
strokeWeight(5);
noFill();
ellipse(x, y + 20, 20, 20);
// coffee
noStroke();
fill(132, 62, 11);
ellipse(x + 15, y, 25, 2);
}
// will draw music note at given coords
function drawNote(x, y) {
fill(0);
stroke(0);
strokeWeight(5);
line(x, y, x, y + 20);
noStroke();
ellipse(x - 5, y + 20, 15, 10);
triangle(x, y-2.25, x, y + 5.75, x + 12, y + 1.75);
}
// will draw audience member at coords
function drawAudience(x, y) {
noStroke();
fill(239, 239, 208);
ellipse(x, y-1, 48, 50);
fill(48, 49, 51);
ellipse(x, y, 50, 50);
fill(0);
ellipse(x, y + 3, 46, 46);
}
function drawEyes(S) {
if (S % 5 == 0) {
fill(0);
ellipse(width / 2, 105, 15, 10);
strokeWeight(3);
stroke(0);
noFill();
beginShape();
curveVertex(width / 2 + 11, 85);
curveVertex(width / 2 + 11, 85);
curveVertex(width / 2 + 22, 88);
curveVertex(width / 2 + 34, 85);
curveVertex(width / 2 + 34, 85);
endShape();
beginShape();
curveVertex(width / 2 - 11, 85);
curveVertex(width / 2 - 11, 85);
curveVertex(width / 2 - 22, 88);
curveVertex(width / 2 - 34, 85);
curveVertex(width / 2 - 34, 85);
endShape();
} else {
// eyes and nose
fill(0);
ellipse(width / 2 + 22, 75, 15, 15);
ellipse(width / 2 - 22, 75, 15, 15);
ellipse(width / 2, 105, 15, 10);
//eyelids
strokeWeight(3);
stroke(0);
beginShape();
curveVertex(width / 2 + 11, 71);
curveVertex(width / 2 + 11, 71);
curveVertex(width / 2 + 22, 68);
curveVertex(width / 2 + 34, 71);
curveVertex(width / 2 + 34, 71);
endShape();
beginShape();
curveVertex(width / 2 - 11, 71);
curveVertex(width / 2 - 11, 71);
curveVertex(width / 2 - 22, 68);
curveVertex(width / 2 - 34, 71);
curveVertex(width / 2 - 34, 71);
endShape();
}
}
function drawSpotlight() {
noStroke();
fill(0, 0, 0, 30);
quad(0, 0, width / 2 - 70, 0, width / 2 - 150, height / 2 + 70, 0, height / 2 + 70);
quad(width, 0, width / 2 + 70, 0, width / 2 + 150, height / 2 + 70, width, height / 2 + 70);
rect(0, height / 2 + 70, width, 200);
}
I simultaneously had a really fun time with this project while I’m also extremely happy I’m finished.
Anyone who’s played the Nintendo game Animal Crossing will recognize this character as KK Slider. Animal Crossing has always been one of my favorite series, and I thought that it was fitting to do a project related to it for this assignment because the game plays in real time as well.
The musical notes represent seconds, audience members minutes, and coffee mugs hours.
I had a lot more trouble with this than I expected too. I got stuck on more than a few off by one errors, and its probably the most graphically complex project I’ve made for this class so far. I had a really hard time with plotting out the acoustic guitar (it’s still a bit lopsided but much better now). I ended up writing a program that would let me click on the screen where I wanted to place my dots and then would print the array of coordinates. It also removed the most recent coordinate when you clicked a key because it was very easy to mess up, and I didn’t want to have to start over entirely.
Altogether this project was fun and I’m really proud of what I made! (My code is super long so I’m crossing my fingers for no missed style errors.)