Catherine Coyle – Project 06 – Abstract Clock

 

sketch

// 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.

Here was my initial sketch design for the clock

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.

Screenshot of the program I mention above (was really useful for this)

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.)

Leave a Reply