nayeonk1-Final Project

nayeonk1

//Na-yeon Kim
//Section B
//nayeonk1@andrew.cmu.edu
//Final project

//global variables
var music;
var amp;
var volHistory = [];
var spectrumHistory = [];
var wave = [];
var fft;
var rainSize = 5;
var streams = [];
var w = 960;
var h = 540;


//load the song
function preload() {
    music = loadSound('city.mp3');
}

//setup canvas, music, aplitude and fft of the music, rainstream
function setup() {
    frameRate(20);
    createCanvas(1920, 1080);
    angleMode(DEGREES);

    music.play(); //play the song

    amp = new p5.Amplitude(0.9, 64); //get the aplitude value of the music
    fft = new p5.FFT(); //get the spectrum analysis value of the music

//generate and render the rains
    var x = 0;
    for (var i = 0; i <= width / rainSize; i++) {
      var stream = new Stream();
      stream.generate(x, random(-1000, 0));
      streams.push(stream);
      x += random(10, 50);
    }
}

//draw lighting and disk changing based on song. render raindrops
function draw() {
    background(0);

    light(0, 0); // lighting that changes with fft
    disk(0, 0); //disk that changes with amp

//render the streams
    streams.forEach(function(stream) {
      stream.render();
    });
}

//function rain-setting values for it-
function rain(x, y, vel, first) {
    this.x = x;
    this.y = y;
    this.vel = vel;
    this.first = first;

//reset raindrops to top when they hit the bottom
    this.reset = function() {
      if (this.y >= height) {
        this.y = 0;
      } else {
        this.y += this.vel;
      }
    }
}

//rain stream function. set speed and generation ofr rain drops
function Stream() {
    this.rainDrops = [];
    this.totalDrops = round(random(10, 50));
    this.vel = random(10);

//set the function of generating the rains
    this.generate = function(x, y) {
      var first = round(random(4)) == 1;
      for (var i = 0; i < this.totalDrops; i++) {
        rains = new rain(x, y, this.vel, first);
        this.rainDrops.push(rains);
        y -= rainSize * random(5);
        first = false;
      }
    }
    //setting the rendering funtion to the rain
    this.render = function() {
      this.rainDrops.forEach(function(rains) {
        if (rains.first) {
          fill(170, 50, 130, random(200));
        } else {
          fill(230, 100, 200, 50);
        }
        //draw rain drops
        noStroke();
        push();
        ellipse(rains.x, rains.y, rainSize, rainSize);
        rains.reset();
        pop();
      });
    }
}

//draw a light that changes it's shapes based on spectrum of the music(fft)
function light() {

    push();
    translate(w, h)

//get the value of fft and put them in spectrum array
    var spectrum = fft.analyze();
    spectrumHistory.push(spectrum);

//erase old spectrum from the array
    if (spectrumHistory.length > width) {
      spectrumHistory.splice(0, 1);
    }

//draw shapes
    for (var i = 0; i < spectrum.length; i++) {
      var spec = spectrum[i];
      var angle = map(i, 0, spectrum.length, 0, 520);
      var r = map(spec, 0, 100, 50, 150);
      var x = r * cos(angle);
      var y = r * sin(angle);

      beginShape();
      stroke(y * 2, x / 2, r / 2);
      strokeWeight(0.5);

      line(0, 0, x, y);
      line(0, 0, -x, -y);
      }
      endShape();
      pop();
}

//draw disk that change its radius based on volum of the music(amp)
function disk(x, y) {
    push();
    translate(w, h);

//get the amp level from the music and put them in vol array
    var vol = amp.getLevel();
    volHistory.push(vol);

//erase old volume from the array
    if (volHistory.length > width) {
      volHistory.splice(0, 1);
    }

//more circles on center
    var rad = map(vol, 0, 1, 100, 250);
    noStroke();
    fill(50, 50, 200, 100);
    ellipse(x, y, rad, rad);
    fill(200, 50, 50, 100);
    ellipse(x, y, rad - 5, rad - 5);
    fill(50, 50, 200, 100);
    ellipse(x, y, rad - 20, rad - 20);
    fill(255, 25);
    ellipse(x, y, rad - 40, rad - 40);
    pop();
}

For the final project, I worked with Jiaxin. It was really fun to work with the friend for something I wanted to do! I’m interested in media art, especially interactive installation art. I proposed this idea to Jiaxin and she also loves to work with Kinect. Since both of us are ETC student, we could get access to all of the equipment like Kinect and projector very easily. So we teamed up and divided works into two. As Jiaxin wanted to work with Kinect, I took charge of background animation and music. I play with sound on p5js and interactive images for days. Meanwhile, me and Jiaxing had several meetings to settle down the idea on this project. We worked on mood board first to see how we are picturing the outcome.

Moodboard1
Moodboard2
Reference

And then we moved on to work on actual work process. For me, it was getting interact images with sound done. I searched on how to make interactive images with sounds in p5js and got some ideas about what I want to create.
First interactive thing is volume. circle on the center of the canvas is changing its radius by music volume. Second is frequency spectrum. It shows analysis of spectrum from low frequency to high frequency, of course, different sound effects have the different frequency.
It was really fun to work on installation art as I wished! I’d love to work on this kind of artwork later again.

Special thanks to Julian Korzeniowsky -a talented and awesome musician- for providing awesome music for our project.

1.download this file Final project(Jiaxin_Nayeon)
2.set up a local server
3.(get a Kinect and) open the file in chrome

danakim-FinalProject

sketch

//Dana Kim
//danakim@andrew.cmu.edu
//Section D
// Final Project

var AxonImage;
var Axonometric = "https://i.imgur.com/doaZlfr.jpg"

var DiagramSetAImage;
var DiagramSetA = "https://i.imgur.com/EVVcKCe.jpg"

var DiagramSetBImage;
var DiagramSetB = "https://i.imgur.com/qKSqajN.jpg"

var RenderingImage;
var Rendering = "https://i.imgur.com/A4ayosV.jpg"

var SPImage;
var SectionalPerspective = "https://i.imgur.com/Xpo6ExI.jpg"

function preload(){
  AxonImage = loadImage(Axonometric);

  DiagramSetAImage = loadImage(DiagramSetA);

  DiagramSetBImage = loadImage(DiagramSetB);

  RenderingImage = loadImage(Rendering);

  SPImage = loadImage(SectionalPerspective);
}

function setup() {
  createCanvas(480, 480);
  image(AxonImage, 0 ,0); //Initial image is Axonometric
}

function draw(){
  //Menu Buttons
  fill(255);
  strokeWeight(0.5);
  rect(10, 50, 205, 20, 20);
  rect(10, 80, 160, 20, 20);
  rect(10, 110, 115, 20, 20);
  rect(10, 140, 70, 20, 20);

  //Menu Buttons Text
  fill(150);
  textSize(10);
  text("Multi-Use Room Transformation Diagrams", 20, 63);
  text("Lobby Transformation Diagrams", 20, 93);
  text("Sectional Perspective", 20, 123);
  text("Rendering", 20, 153);

}

function mousePressed(){
  //Multi-Use Room Transformation Diagrams Page
  if(10 < mouseX & mouseX < 215 && 50 < mouseY && mouseY < 70){
    image(DiagramSetAImage, 0, 0);
    fill(0)
    rect(10, 19, 53, 15, 20);
    fill(255);
    textSize(10);
    text("H O M E", 16, 30);
    fill(0);
    text("Multi-Use Room Transformation Diagrams", 15, height-10);
  }

  //Lobby Transformation Diagrams Page
  else if(10 < mouseX & mouseX < 170 && 80 < mouseY && mouseY < 100){
    image(DiagramSetBImage, 0, 0);
    fill(0)
    rect(10, 19, 53, 15, 20);
    fill(255);
    textSize(10);
    text("H O M E", 16, 30);
    fill(0);
    text("Lobby Transformation Diagrams", 15, height-10);
  }

  //Sectional Perspective Page
  else if(10 < mouseX & mouseX < 125 && 110 < mouseY && mouseY < 130){
    image(SPImage, 0, 0);
    fill(0)
    rect(10, 19, 53, 15, 20);
    fill(255);
    textSize(10);
    text("H O M E", 16, 30);
    fill(0);
    text("Sectional Perspective", 15, height-10);
  }

  //Rendering Page
  else if(10 < mouseX & mouseX < 80 && 140 < mouseY && mouseY < 160){
    image(RenderingImage, 0, 0);
    fill(0)
    rect(10, 19, 53, 15, 20);
    fill(255);
    textSize(10);
    text("H O M E", 16, 30);
    fill(0);
    text("Stair Rendering", 15, height-10);
  }

  // Home Page (Axonometric)
  else if(10 < mouseX & mouseX < 63 && 19 < mouseY && mouseY < 34){
    image(AxonImage, 0 , 0);
  }
}

I wanted to create an interactive page for one of my past studio projects. I had originally intended to do an informative exploded axon but due to time constraints I was unable to do so. Although the project wasn’t what I had initially intended to do and is fairly simple, I’m still pretty satisfied with the way that it turned out.

merlebac Final Project

Rwanda Animation

var ImageN = 81; // Creates a global variable for the number of images

var diameter = 30; // Determines the diameter for the circles

var ImageX = []; // Creates an empty array for the x-coordinate of the images
var ImageY = []; // Creates an empty array for the y-coordinate of the images

var ImageWidth = []; // Creates an empty array for the width of the images
var ImageHeight = []; // Creates an empty array for the height of the images

var AdelineAudio; // Creates a variable for the audio of Adeline
var HelenAudio; // Creates a variable for the audio of Helen
var TeddyAudio; // Creates a variable for the audio of Teddy

var AdelineX = 225; // Creates the x-coordinate for the Adeline icon
var AdelineY = 235; // Creates the y-coordinate for the Adeline icon

var HelenX = 350; // Creates the x-coordinate for the Helen icon
var HelenY = 150; // Creates the y-coordinate for the Helen icon

var TeddyX = 150; // Creates the x-coordinate for the Teddy icon
var TeddyY = 320; // Creates the y-coordinate for the Teddy icon

var AdelineStart = false; // The state that triggers the animation for Adeline
var HelenStart = false; // The state that triggers the animation for Helen
var TeddyStart = false; // The state that triggers the animation for Teddy

var ImageAnimation = []; // This creates an array to store the images

var StarterImage = 0; // Determines what value the images will start at

function preload() {
    mapRwanda = loadImage("https://upload.wikimedia.org/wikipedia/commons/0/04/Rwanda_location_map.svg");
    // Loads the image of the map

    var filenames1 = []; // Creates an array to load the images into

    // Preloads the images in the animation
    filenames1[0] = loadImage("https://i.imgur.com/Xt3gDqm.jpg");
    filenames1[1] = loadImage("https://i.imgur.com/aNZUiSs.jpg");
    filenames1[2] = loadImage("https://i.imgur.com/gOFPrGM.jpg");
    filenames1[3] = loadImage("https://i.imgur.com/Ic3Hh8v.jpg");
    filenames1[4] = loadImage("https://i.imgur.com/jYC0NH1.jpg");
    filenames1[5] = loadImage("https://i.imgur.com/WAqwQTz.jpg");
    filenames1[6] = loadImage("https://i.imgur.com/Am7j6ZZ.jpg");
    filenames1[7] = loadImage("https://i.imgur.com/GFyMdUP.jpg");
    filenames1[8] = loadImage("https://i.imgur.com/GFyMdUP.jpg");
    filenames1[9] = loadImage("https://i.imgur.com/gkgnugY.jpg");
    filenames1[10] = loadImage("https://i.imgur.com/sICGMTJ.jpg");
    filenames1[11] = loadImage("https://i.imgur.com/iHqguHk.jpg");
    filenames1[12] = loadImage("https://i.imgur.com/cBuPUKt.jpg");
    filenames1[13] = loadImage("https://i.imgur.com/p6JMhb5.jpg");
    filenames1[14] = loadImage("https://i.imgur.com/Khc6B7j.jpg");
    filenames1[15] = loadImage("https://i.imgur.com/gDo4pij.jpg");
    filenames1[16] = loadImage("https://i.imgur.com/kBEHLxL.jpg");
    filenames1[17] = loadImage("https://i.imgur.com/YH505J9.jpg");
    filenames1[18] = loadImage("https://i.imgur.com/dg5jH5Q.jpg");
    filenames1[19] = loadImage("https://i.imgur.com/8UNZ6wd.jpg");
    filenames1[20] = loadImage("https://i.imgur.com/NQrlsmd.jpg");
    filenames1[21] = loadImage("https://i.imgur.com/kUGPt3r.jpg");
    filenames1[22] = loadImage("https://i.imgur.com/jedzdQJ.jpg");
    filenames1[23] = loadImage("https://i.imgur.com/1SB8VWa.jpg");
    filenames1[24] = loadImage("https://i.imgur.com/YxKw9wy.jpg");
    filenames1[25] = loadImage("https://i.imgur.com/EtFlQRR.jpg");
    filenames1[26] = loadImage("https://i.imgur.com/ueL8zi0.jpg");
    // Stores the Adeline images in a local array
    filenames1[27] = loadImage("https://i.imgur.com/SsolDPA.jpg");
    filenames1[28] = loadImage("https://i.imgur.com/hpPgQ7o.jpg");
    filenames1[29] = loadImage("https://i.imgur.com/47dWUGt.jpg");
    filenames1[30] = loadImage("https://i.imgur.com/uLMP5Rf.jpg");
    filenames1[31] = loadImage("https://i.imgur.com/XKZ4XUX.jpg");
    filenames1[32] = loadImage("https://i.imgur.com/sOFGz2P.jpg");
    filenames1[33] = loadImage("https://i.imgur.com/Lkp1T2v.jpg");
    filenames1[34] = loadImage("https://i.imgur.com/oH9vodk.jpg");
    filenames1[35] = loadImage("https://i.imgur.com/MqUKLwm.jpg");
    filenames1[36] = loadImage("https://i.imgur.com/786JyXJ.jpg");
    filenames1[37] = loadImage("https://i.imgur.com/1sPhMmn.jpg");
    filenames1[38] = loadImage("https://i.imgur.com/UmJs8Iv.jpg");
    filenames1[39] = loadImage("https://i.imgur.com/DH8w2l8.jpg");
    filenames1[40] = loadImage("https://i.imgur.com/mnZLn35.jpg");
    filenames1[41] = loadImage("https://i.imgur.com/gcepiH6.jpg");
    filenames1[42] = loadImage("https://i.imgur.com/oHh4KdS.jpg");
    filenames1[43] = loadImage("https://i.imgur.com/PjUGPdb.jpg");
    filenames1[44] = loadImage("https://i.imgur.com/xrnJEfl.jpg");
    filenames1[45] = loadImage("https://i.imgur.com/1N6GpHO.jpg");
    filenames1[46] = loadImage("https://i.imgur.com/bEWtlW8.jpg");
    filenames1[47] = loadImage("https://i.imgur.com/DS4qtcF.jpg");
    filenames1[48] = loadImage("https://i.imgur.com/Dzx5Ul6.jpg");
    filenames1[49] = loadImage("https://i.imgur.com/cCaVVVj.jpg");
    filenames1[50] = loadImage("https://i.imgur.com/0l3369g.jpg");
    filenames1[51] = loadImage("https://i.imgur.com/2ddOYo1.jpg");
    filenames1[52] = loadImage("https://i.imgur.com/ho9OszF.jpg");
    filenames1[53] = loadImage("https://i.imgur.com/6Qc27oG.jpg");
    filenames1[54] = loadImage("https://i.imgur.com/SsolDPA.jpg");
    // Stores the Helen images in a local array
    filenames1[55] = loadImage("https://i.imgur.com/qo2L1rH.jpg");
    filenames1[56] = loadImage("https://i.imgur.com/5U3v4v5.jpg");
    filenames1[57] = loadImage("https://i.imgur.com/v5S7VFh.jpg");
    filenames1[58] = loadImage("https://i.imgur.com/lpbOQtX.jpg");
    filenames1[59] = loadImage("https://i.imgur.com/x5MgUep.jpg");
    filenames1[60] = loadImage("https://i.imgur.com/4yIHLh5.jpg");
    filenames1[61] = loadImage("https://i.imgur.com/CWntA53.jpg");
    filenames1[62] = loadImage("https://i.imgur.com/DCOiLSl.jpg");
    filenames1[63] = loadImage("https://i.imgur.com/1xi8u1b.jpg");
    filenames1[64] = loadImage("https://i.imgur.com/g2OVV0K.jpg");
    filenames1[65] = loadImage("https://i.imgur.com/1KiO1hf.jpg");
    filenames1[66] = loadImage("https://i.imgur.com/g4G1rUs.jpg");
    filenames1[67] = loadImage("https://i.imgur.com/HzGsbXl.jpg");
    filenames1[68] = loadImage("https://i.imgur.com/bYq0mBM.jpg");
    filenames1[69] = loadImage("https://i.imgur.com/7QigKZk.gif");
    filenames1[70] = loadImage("https://i.imgur.com/fgkHSYK.jpg");
    filenames1[71] = loadImage("https://i.imgur.com/zC1kELS.jpg");
    filenames1[72] = loadImage("https://i.imgur.com/YYjX72S.jpg");
    filenames1[73] = loadImage("https://i.imgur.com/2aUJJtq.jpg");
    filenames1[74] = loadImage("https://i.imgur.com/VnHBFlX.jpg");
    filenames1[75] = loadImage("https://i.imgur.com/zK7wB45.jpg");
    filenames1[76] = loadImage("https://i.imgur.com/2aVbY6o.jpg");
    filenames1[77] = loadImage("https://i.imgur.com/agfG6di.jpg");
    filenames1[78] = loadImage("https://i.imgur.com/iRTZlIH.jpg");
    filenames1[79] = loadImage("https://i.imgur.com/1q460zU.jpg");
    filenames1[80] = loadImage("https://i.imgur.com/fGFJEdn.jpg");
    // Stores the Teddy images in a local array

    for (var i = 0; i < ImageN; i++) {
        ImageAnimation[i] = filenames1[i];
        // Stores the images in a global array
    }

    AdelineAudio = loadSound("Adeline.mp3"); // Stores the Adeline audio
    AdelineAudio.setVolume(0.5); // Sets volume of Adeline audio

    HelenAudio = loadSound("Helen.mp3"); // Stores the Helen audio
    HelenAudio.setVolume(0.5); // Sets volume of Helen audio

    TeddyAudio = loadSound("Teddy.mp3"); // Stores the Teddy audio
    TeddyAudio.setVolume(0.5); // Sets volume of Teddy audio
}

function setup() {
    createCanvas(1000, 875 / 2); // Creates the canvas
    frameRate(30); // Sets the framerate at 30

    for (var i = 0; i < ImageN; i += 9) {
        // For loop for storing values in the empty arrays
        ImageX[i] = 500;
        ImageX[i + 1] = 1000;
        ImageX[i + 2] = 500;
        ImageX[i + 3] = 750;
        ImageX[i + 4] = 1000;
        ImageX[i + 5] = 500;
        ImageX[i + 6] = 500;
        ImageX[i + 7] = 500;
        ImageX[i + 8] = 500;
        // Stores the ImageX array with x-coordinates
        ImageY[i + 0] = -500;
        ImageY[i + 1] = 0;
        ImageY[i + 2] = 0;
        ImageY[i + 3] = 875 / 4;
        ImageY[i + 4] = -500;
        ImageY[i + 5] = 0;
        ImageY[i + 6] = 0;
        ImageY[i + 7] = 0;
        ImageY[i + 8] = 0;
        // Stores the ImageY array with y-coordinates
        ImageWidth[i] = 500;
        ImageWidth[i + 1] = 500;
        ImageWidth[i + 2] = 1;
        ImageWidth[i + 3] = 1;
        ImageWidth[i + 4] = 500;
        ImageWidth[i + 5] = 1;
        ImageWidth[i + 6] = 1;
        ImageWidth[i + 7] = 1;
        ImageWidth[i + 8] = 1;
        // Stores the ImageWidth array with widths
        ImageHeight[i] = 875 / 2;
        ImageHeight[i + 1] = 875 / 2;
        ImageHeight[i + 2] = 0.875;
        ImageHeight[i + 3] = 0.875;
        ImageHeight[i + 4] = 875;
        ImageHeight[i + 5] = 0.875;
        ImageHeight[i + 6] = 0.875;
        ImageHeight[i + 7] = 0.875;
        ImageHeight[i + 8] = 0.875;
        // Stores the ImageHeight array with heights
    }
}

function playAdeline() {
    HelenAudio.stop();
    TeddyAudio.stop();
    AdelineAudio.stop();
    // Resets and stops all audio if an icon is pressed when audio is playing

    for (var i = 0; i < ImageN; i += 9) {
        // For lopp resets images so they don't overlap
        ImageX[i] = 500;
        ImageX[i + 1] = 1000;
        ImageX[i + 2] = 500;
        ImageX[i + 3] = 750;
        ImageX[i + 4] = 1000;
        ImageX[i + 5] = 500;
        ImageX[i + 6] = 500;
        ImageX[i + 7] = 500;
        ImageX[i + 8] = 500;
        // Ressets the x-coordinates of all images
        ImageY[i + 0] = -500;
        ImageY[i + 1] = 0;
        ImageY[i + 2] = 0;
        ImageY[i + 3] = 875 / 4;
        ImageY[i + 4] = -875 / 2;
        ImageY[i + 5] = 0;
        ImageY[i + 6] = 0;
        ImageY[i + 7] = 0;
        ImageY[i + 8] = 0;
        // Resets the y-coordinates of all images
        ImageWidth[i] = 500;
        ImageWidth[i + 1] = 500;
        ImageWidth[i + 2] = 1;
        ImageWidth[i + 3] = 1;
        ImageWidth[i + 4] = 500;
        ImageWidth[i + 5] = 1;
        ImageWidth[i + 6] = 1;
        ImageWidth[i + 7] = 1;
        ImageWidth[i + 8] = 1;
        // Resets the widths of all images
        ImageHeight[i] = 875 / 2;
        ImageHeight[i + 1] = 875 / 2;
        ImageHeight[i + 2] = 0.875;
        ImageHeight[i + 3] = 0.875;
        ImageHeight[i + 4] = 875 / 4;
        ImageHeight[i + 5] = 0.875;
        ImageHeight[i + 6] = 0.875;
        ImageHeight[i + 7] = 0.875;
        ImageHeight[i + 8] = 0.875;
        // Resets the heights of all images
    }

    AdelineAudio.play(); // Starts the Adeline audio
    AdelineStart = true; // Starts the Adeline animation
    HelenStart = false; // Prevents the Helen animation from restarting
    TeddyStart = false; // Prevents the Teddy animation from restarting
}

function playHelen() {
    HelenAudio.stop();
    TeddyAudio.stop();
    AdelineAudio.stop();
    // Resets and stops all audio if an icon is pressed when audio is playing

    for (var i = 0; i < ImageN; i += 9) {
        // For loop resets images so they don't overlap
        ImageX[i] = 500;
        ImageX[i + 1] = 1000;
        ImageX[i + 2] = 500;
        ImageX[i + 3] = 750;
        ImageX[i + 4] = 1000;
        ImageX[i + 5] = 500;
        ImageX[i + 6] = 500;
        ImageX[i + 7] = 500;
        ImageX[i + 8] = 500;
        // Resets the x-coordinates of all images
        ImageY[i + 0] = -500;
        ImageY[i + 1] = 0;
        ImageY[i + 2] = 0;
        ImageY[i + 3] = 875 / 4;
        ImageY[i + 4] = -875;
        ImageY[i + 5] = 0;
        ImageY[i + 6] = 0;
        ImageY[i + 7] = 0;
        ImageY[i + 8] = 0;
        // Resets the y-coordinates of all images
        ImageWidth[i] = 500;
        ImageWidth[i + 1] = 500;
        ImageWidth[i + 2] = 1;
        ImageWidth[i + 3] = 1;
        ImageWidth[i + 4] = 500;
        ImageWidth[i + 5] = 1;
        ImageWidth[i + 6] = 1;
        ImageWidth[i + 7] = 1;
        ImageWidth[i + 8] = 1;
        // Resets the widths of all images
        ImageHeight[i] = 875 / 2;
        ImageHeight[i + 1] = 875 / 2;
        ImageHeight[i + 2] = 0.875;
        ImageHeight[i + 3] = 0.875;
        ImageHeight[i + 4] = 437.5;
        ImageHeight[i + 5] = 0.875;
        ImageHeight[i + 6] = 0.875;
        ImageHeight[i + 7] = 0.875;
        ImageHeight[i + 8] = 0.875;
        // Resets the heights of all images
    }

    HelenAudio.play(); // Starts the Helen Audio
    AdelineStart = false; // Prevents the Adeline animation from restarting
    HelenStart = true; // Starts the Helen animation from restarting
    TeddyStart = false; // Prevents the Teddy animation from restarting
}

function playTeddy() {
    HelenAudio.stop();
    TeddyAudio.stop();
    AdelineAudio.stop();
    // Resets all audio if an icon is pressed when audio is playing

    for (var i = 0; i < ImageN; i += 9) {
        // For loop resets images so they don't overlap
        ImageX[i] = 500;
        ImageX[i + 1] = 1000;
        ImageX[i + 2] = 500;
        ImageX[i + 3] = 750;
        ImageX[i + 4] = 1000;
        ImageX[i + 5] = 500;
        ImageX[i + 6] = 500;
        ImageX[i + 7] = 500;
        ImageX[i + 8] = 500;
        // Resets the x-coordinates of all images
        ImageY[i + 0] = -500;
        ImageY[i + 1] = 0;
        ImageY[i + 2] = 0;
        ImageY[i + 3] = 875 / 4;
        ImageY[i + 4] = -875;
        ImageY[i + 5] = 0;
        ImageY[i + 6] = 0;
        ImageY[i + 7] = 0;
        ImageY[i + 8] = 0;
        // Resets the y-coordinates of all images
        ImageWidth[i] = 500;
        ImageWidth[i + 1] = 500;
        ImageWidth[i + 2] = 1;
        ImageWidth[i + 3] = 1;
        ImageWidth[i + 4] = 500;
        ImageWidth[i + 5] = 1;
        ImageWidth[i + 6] = 1;
        ImageWidth[i + 7] = 1;
        ImageWidth[i + 8] = 1;
        // Resets the widths of all images
        ImageHeight[i] = 875 / 2;
        ImageHeight[i + 1] = 875 / 2;
        ImageHeight[i + 2] = 0.875;
        ImageHeight[i + 3] = 0.875;
        ImageHeight[i + 4] = 437.5;
        ImageHeight[i + 5] = 0.875;
        ImageHeight[i + 6] = 0.875;
        ImageHeight[i + 7] = 0.875;
        ImageHeight[i + 8] = 0.875;
        // Resets the heights of all images
    }

    TeddyAudio.play(); // Starts the Teddy audio
    AdelineStart = false; // Prevents the Adeline animation from restarting
    HelenStart = false; // Prevents the Adeline animation from restarting
    TeddyStart = true; // Starts the Teddy animation
}

function draw() {
    background(255);
    scale(0.48, 0.48);
    imageMode(CORNER);
    // Makes the corner the pivot point of the image
    image(mapRwanda, 0, 0, width / 2, height);
    // Displays map on canvas

    fill(255, 0, 0); // Makes circles and text red
    textAlign(CENTER); // Centers the text
    textSize(18); // Sets the text size to 18
    ellipse(AdelineX, AdelineY, diameter); // Creates marker for Adeline story
    text("Adeline", AdelineX, AdelineY + 45);
    ellipse(HelenX, HelenY, diameter); // Creates marker for Teddy story
    text("Helen", HelenX, HelenY + 45);
    ellipse(TeddyX, TeddyY, diameter); // Creates marker for Teddy story
    text("Teddy", TeddyX, TeddyY + 45);
    // Click one of the red circles to start audio and animation

    if (AdelineStart == true &
        HelenStart == false &&
        TeddyStart == false) {
        StarterImage = 0; 
        // Gives StarterImage a value which displays the Adeline images
    } else if (AdelineStart == false &
        HelenStart == true &&
        TeddyStart == false) {
        StarterImage = 27;
        // Gives StarterImage a value which displays the Helen images
    } else if (AdelineStart == false &
        HelenStart == false &&
        TeddyStart == true) {
        StarterImage = 54;
        // Gives StarterImage a value which display the Teddy images
    } else {
        StarterImage = 0;
        // I included this so that I could code using an if else statement
    }

    if (AdelineStart == true || HelenStart == true|| TeddyStart == true) {
        // Occurs when one of the icons are clicked
        ImageY[StarterImage + 0] += 2;
        // Moves the 0th image of each series down
    }

    if (ImageY[StarterImage + 0] >= 0) {
        // Occurs when 1st image is fully on the screen
        ImageY[StarterImage + 0] = 0;
        // Stops the 1st image from moving down more
        ImageX[StarterImage + 1] -= 2;
        // Moves the 1st image in each series to the left
    }

    if (ImageX[StarterImage + 1] < width / 2) {
        // Occurs when the 2nd image is fully on screen
        ImageX[StarterImage + 1] = width / 2;
        // Stops the 2nd image from moving more to the left
    }

    if (ImageX[StarterImage + 1] == width / 2) {
        // Occurs when the 2nd image stops moving to the left
        ImageWidth[StarterImage + 2] += 2;
        // Increases the width of the 2nd image in each series
        ImageHeight[StarterImage + 2] += 1.75;
        // Increases the height of the 2nd image in each series
    }

    if (ImageWidth[StarterImage + 2] >= width / 2 ||
        ImageHeight[StarterImage + 2] >= height) {
        // Occurs when the 2nd image is equal to half the width
        // or half the height
        ImageWidth[StarterImage + 2] = width / 2;
        // Sets the width equal to half the width
        ImageHeight[StarterImage + 2] = height;
        // Sets the height equal to half the height
    }

    if (ImageWidth[StarterImage + 2] == width / 2 ||
        ImageHeight[StarterImage + 2] == height) {
        // Occurs when the width of the 2nd image equals half the width of
        // the canvas or when the height equals half the height of the canvas
        ImageWidth[StarterImage + 3] += 3;
        // Increases the width of the 3rd image in each series
        ImageHeight[StarterImage + 3] += 2.625;
        // Increases the height of the 3rd image in each series 
    }

    if (ImageWidth[StarterImage + 3] >= width / 2 ||
        ImageHeight[StarterImage + 3] >= height) {
        // Occurs when the width of the 3rd image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 3] = width / 2;
        // Sets the width of the 3rd image to half the width of the canvas
        ImageHeight[StarterImage + 3] = height;
        // Sets the height of the 3rd image to half the height of the canvas
        ImageX[StarterImage + 4] -= 2;
        // Moves the 4th image in the series to the left
        ImageY[StarterImage + 4] += 1.75;
        // Moves the 4th image in the series down
    }

    if (ImageX[StarterImage + 4] <= width / 2 ||
        ImageY[StarterImage + 4] >= 0) {
        // Occurs when the x-coordinate of the 4th image is equal to half the
        // width or when the y-coordinate is equal to 0
        ImageX[StarterImage + 4] = width / 2;
        // Locks the x-coordinate of the 4th image at half the width
        ImageY[StarterImage + 4] = 0;
        // Loocks the y-coordinate of the 4th image at 0
        ImageWidth[StarterImage + 5] += 6;
        // Increases the width of the 5th Adeline image
    }

    if (ImageWidth[StarterImage + 5] >= width / 2) {
        // Occurs if the width of the 5th image equals half the canvas width
        ImageWidth[StarterImage + 5] = width / 2;
        // Sets the width of the 5th image equal to half the canvas
        ImageHeight[StarterImage + 5] += 2;
        // Increases the height of the 5th image
    }

    if (ImageHeight[StarterImage + 5] >= height) {
        // Occurs if the height of the 5th image is equal to the canvas height
        ImageHeight[StarterImage + 5] = height;
        // Sets the height of the 5th image equal to the height
        ImageWidth[StarterImage + 6] += 2;
        // Increases the width of the 6th image
        ImageHeight[StarterImage + 6] += 1.75;
        // Increases the height of the seveth image
    }

    if (ImageWidth[StarterImage + 6] >= width / 2 ||
        ImageHeight[StarterImage + 6] >= height) {
        // Occurs when the width of the 6th image equals half the canvas
        // width or when the height equals the height of the canvas
        ImageWidth[StarterImage + 6] = width / 2;
        // Sets the width of the 6th image equal to half the canvas width
        ImageHeight[StarterImage + 6] = height;
        // Sets the height of the 6th image equal to the canvas height
    }
    if (ImageWidth[StarterImage + 6] >= width / 2 ||
        ImageHeight[StarterImage + 6] >= height) {
        // Occurs when the width of the 6th image equals half the canvas
        // width or when the height equals the height of the canvas
        ImageHeight[StarterImage + 7] += 4;
        // Increases the height of the 7th image
    }

    if (ImageHeight[StarterImage + 7] >= height) {
        // Occurs when the height of the 7th image equals the canvas height
        ImageHeight[StarterImage + 7] = height;
        // Sets the height of the 7th image equal to the canvas height
        ImageWidth[StarterImage + 7] += 2;
        // Increases the width of the 6th image
    }

    if (ImageWidth[StarterImage + 7] >= width / 2) {
        // Occurs when the width of the 7th image is half the canvas width
        ImageWidth[StarterImage + 7] = width / 2;
        // Sets the width of the 7th image equal to half the canvas width
    }

    if (ImageWidth[StarterImage + 7] == width / 2) {
        // Occurs when the width of the 8th image equals half the width of
        // the canvas
        ImageWidth[StarterImage + 8] += 3;
        // Increases the width of the 8th image
        ImageHeight[StarterImage + 8] += 2.625;
        // Increases the height of the 8th image
    }

    if (ImageWidth[StarterImage + 8] >= width / 2 ||
        ImageHeight[StarterImage + 8] >= height) {
        // Occurs when the width of the eight image equals the half the canvas
        // width or when the height equals the height of the canvas
        ImageWidth[StarterImage + 8] = width / 2;
        // Sets the width of the 8th image equal to half the canvas width
        ImageHeight[StarterImage + 8] = height;
        // Sets the height of the 8th image equal to the canvas height
    }

    if (ImageWidth[StarterImage + 8] == width / 2 ||
        ImageHeight[StarterImage + 8] == height) {
        ImageY[StarterImage + 9] += 2;
        // Increases the y-coordinate of the 9th image
    }

    // Many of the if statements below are copied from the previous ones
    // I couldn't use of for or a while loop because I needed each image to
    // trigger the next one

    if (ImageY[StarterImage + 9] >= 0) {
        // Occurs when the 9th image is fully on screen
        ImageY[StarterImage + 9] == 0;
        ImageX[StarterImage + 10] -= 2;
        // Animates the 1st Adeline image
    }

    if (ImageX[StarterImage + 10] <= width / 2) {
        // Occurs when the 10th image is fully on screen
        ImageX[StarterImage + 10] = width / 2;
        // Stops the 10th image from moving
        ImageWidth[StarterImage + 11] += 2;
        // Increases the width of the 11th image
        ImageHeight[StarterImage + 11] += 1.75;
        // Increases the height of the 11th image
    }

    if (ImageWidth[StarterImage + 11] >= width / 2 ||
        ImageHeight[StarterImage + 11] >= height) {
        // Occurs when the width of the 11th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 11] = width / 2;
        // Sets the width of the 11th image equal to half the canvas width
        ImageHeight[StarterImage + 11] = height;
        // Sets the heightof the 11th image equal to half the canvas width
    }

    if (ImageWidth[StarterImage + 11] == width / 2 ||
        ImageHeight[StarterImage + 11] == height) {
        // Occurs when the width of the 11th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 12] += 3;
        // Increases the width of the 12th image
        ImageHeight[StarterImage + 12] += 2.625;
        // Increases the height of the 12th image
    }

    if (ImageWidth[StarterImage + 12] >= width / 2 ||
        ImageHeight[StarterImage + 12] >= height) {
        // Occurs when the width of the 12th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 12] = width / 2;
        // Sets the width of the 12th image to half the width
        ImageHeight[StarterImage + 12] = height;
        // Keeps the width and height of the 3rd Adeline image constant
    }

    if (ImageWidth[12] == width / 2 ||
        ImageHeight[12] == height / 2) {
        // Occurs when the width of the 12th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageX[StarterImage + 13] -= 2;
        // Lowers the 13th image
        ImageY[StarterImage + 13] += 1.75;
        // Moves the 13 image to the left
    }
    

    if (ImageX[StarterImage + 13] <= width / 2 ||
        ImageY[StarterImage + 13] >= 0) {
        // Occurs when the 13th image is fully on screen
        ImageX[StarterImage + 13] = width / 2;
        // Sets the width of the 13th image to half the width
    }

    if (ImageX[StarterImage + 13] == width / 2 ||
        ImageY[StarterImage + 13] >= 0) {
        // Occurs when the width of the 12th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageY[StarterImage + 13] = 0;
        // Stops the 4th Adeline image from moving
        ImageWidth[StarterImage + 14] += 6;
        // Increases the width of the 5th Adeline image
    }

    if (ImageWidth[StarterImage + 14] >= 500) {
        // Occurs when the width of the 14th image equals half the width of
        // the canvas
        ImageWidth[StarterImage + 14] = width / 2;
        // Sets the width of the 14th image to half the width
        ImageHeight[StarterImage + 14] += 2;
    }

    if (ImageHeight[StarterImage + 14] >= 875 / 2) {
        // Occurs when the height of the 14th image equals the canvas height
        ImageHeight[StarterImage + 14] = height;
        // Keeps the height of the 5th image constant
    }

    if (ImageHeight[StarterImage + 14] >= height) {
        // Occurs when the height of the 14th image equals the canvas height
        ImageWidth[StarterImage + 15] += 2;
        ImageHeight[StarterImage + 15] += 1.75;
        // Increases the width and height of the 6th image
    }

    if (ImageWidth[StarterImage + 15] >= width / 2 ||
        ImageHeight[StarterImage + 15] >= height) {
        // Occurs when the width of the 15th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 15] = width / 2;
        ImageHeight[StarterImage + 15] = height;
        ImageHeight[StarterImage + 16] += 4;
        // Keeps the width and height of the 6th image constant
    }

    if (ImageHeight[StarterImage + 16] >= height) {
        // Occurs when the height of the 14th image equals the canvas height
        ImageHeight[StarterImage + 16] = height;
        ImageWidth[StarterImage + 16] += 2;
    }

    if (ImageWidth[StarterImage + 16] >= width / 2) {
        // Occurs when the width of the 16th image equals half the width of
        // the canvas
        ImageWidth[StarterImage + 16] = width / 2;
        ImageWidth[StarterImage + 17] += 3;
        ImageHeight[StarterImage + 17] += 2.625;
    }

    if (ImageWidth[StarterImage + 17] >= width / 2 ||
        ImageHeight[StarterImage + 17] >= height) {
        // Occurs when the width of the 15th image equals half the width of
        // the canvas and when height equals half the height of the canvas
        ImageWidth[StarterImage + 17] = width / 2;
        ImageHeight[StarterImage + 17] = height;
        // Keeps the width and height of the 3rd Adeline image constant
        ImageY[StarterImage + 18] += 2;
        // Animates the 1st Adeline image
    }

    if (ImageY[StarterImage + 18] >= 0) {
        // Occurs when the 2nd image is fully on screen
        ImageY[StarterImage + 18] = 0;
        // Stops the 1st Adeline image from moving
        ImageX[StarterImage + 19] -= 2;
        // Animates the 1st Adeline image
    }

    if (ImageX[StarterImage + 19] <= width / 2) {
        // Occurs when the 19th image is fully on screen
        ImageX[StarterImage + 19] = width / 2;
        // Stops the 2nd Adeline image from moving
        ImageWidth[StarterImage + 20] += 2;
        ImageHeight[StarterImage + 20] += 1.75;
    }

    if (ImageWidth[StarterImage + 20] >= width / 2 ||
        ImageHeight[StarterImage + 20] >= height) {
        // Occurs when the width of the 20th image equals half the width of
        // the canvas and when height equals half the height of the canvas
        ImageWidth[StarterImage + 20] = width / 2;
        ImageHeight[StarterImage + 20] = height;
        // Keeps the width and height of the 2nd Adeline image constant
    }

    if (ImageWidth[StarterImage + 20] == width / 2 ||
        ImageHeight[StarterImage + 20] == height) {
        ImageWidth[StarterImage + 21] += 3;
        ImageHeight[StarterImage + 21] += 2.625;
    }

    if (ImageWidth[StarterImage + 21] >= width / 2 ||
        ImageHeight[StarterImage + 21] >= height) {
        // Occurs when the width of the 15th image equals half the width of
        // the canvas and when height equals half the height of the canvas
        ImageWidth[StarterImage + 21] = width / 2;
        ImageHeight[StarterImage + 21] = height;
        // Keeps the width and height of the 3rd Adeline image constant
    }

    if (ImageWidth[StarterImage + 21] >= width / 2 ||
        ImageHeight[StarterImage + 21] >= height) {
        // Occurs when the width of the 21th image equals half the width of
        // the canvas and when height equals half the height of the canvas
        ImageX[StarterImage + 22] -= 2;
        ImageY[StarterImage + 22] += 1.75;
        // Animates the 4th Adeline image
    }

    if (ImageX[StarterImage + 22] <= width / 2 &
        ImageY[StarterImage + 4] >= 0) {
        // Occurs when the width of the 22th image equals half the width of
        // the canvas and when height equals half the height of the canvas
        ImageX[StarterImage + 22] = width / 2;
        ImageY[StarterImage + 22] = 0;
        // Stops the 4th Adeline image from moving
        ImageWidth[StarterImage + 23] += 6;
        // Increases the width of the 5th Adeline image
    }

    if (ImageWidth[StarterImage + 23] >= 500) {
        // Occurs when the width of the 15th image equals half the width of
        // the canvas
        ImageWidth[StarterImage + 23] = width / 2;
        ImageHeight[StarterImage + 23] += 2;
    }

    if (ImageHeight[StarterImage + 23] >= height) {
        // Occurs when the height of the image equals the canvas height
        ImageHeight[StarterImage + 23] = height;
        // Keeps the height of the 5th image constant
        ImageWidth[StarterImage + 24] += 2;
        ImageHeight[StarterImage + 24] += 1.75;
        // Increases the width and height of the 6th image
    }

    if (ImageWidth[StarterImage + 24] >= width / 2 ||
        ImageHeight[StarterImage + 6] >= height) {
        // Occurs when the width of the 24th image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 24] = width / 2;
        ImageHeight[StarterImage + 24] = height;
        ImageHeight[StarterImage + 25] += 4;
        // Keeps the width and height of the 6th image constant
    }

    if (ImageHeight[StarterImage + 25] >= height) {
        ImageHeight[StarterImage + 25] = height;
        ImageWidth[StarterImage + 25] += 2;
    }

    if (ImageWidth[StarterImage + 25] >= width / 2) {
        // Occurs when the width of the 25th image equals half the width of
        // the canvas
        ImageWidth[StarterImage + 25] = width / 2;
        ImageWidth[StarterImage + 26] += 3;
        ImageHeight[StarterImage + 26] += 2.625;
    }

    if (ImageWidth[StarterImage + 26] >= width / 2 ||
        ImageHeight[StarterImage + 26] >= height) {
        // Occurs when the width of the 3rd image equals half the width of
        // the canvas or when height equals half the height of the canvas
        ImageWidth[StarterImage + 26] = width / 2;
        ImageHeight[StarterImage + 26] = height;
        // Keeps the width and height of the 3rd Adeline image constant
    }

    // These are all the images in the code that are used for the presentation
    // Each of them have an assigned x and y coordinate, width and height
    // I wasn't able to put them in a for loop since I needed some of the to
    // be translated to the center
    // There are a total of 27 images and each has three variants
    image(ImageAnimation[StarterImage + 0], ImageX[StarterImage + 0],
        ImageY[StarterImage + 0], ImageWidth[StarterImage + 0],
        ImageHeight[StarterImage + 0]);
    image(ImageAnimation[StarterImage + 1], ImageX[StarterImage + 1],
        ImageY[StarterImage + 1], ImageWidth[StarterImage + 1],
        ImageHeight[StarterImage + 1]);
    image(ImageAnimation[StarterImage + 2], ImageX[StarterImage + 2],
        ImageY[StarterImage + 2], ImageWidth[StarterImage + 2],
        ImageHeight[StarterImage + 2]);
    imageMode(CENTER); // Makes the center of the image the pivot
    image(ImageAnimation[StarterImage + 3], ImageX[StarterImage + 3],
        ImageY[StarterImage + 3], ImageWidth[StarterImage + 3],
        ImageHeight[StarterImage + 3]);
    imageMode(CORNER); // Makes the upper left corrner of the image the pivot
    image(ImageAnimation[StarterImage + 4], ImageX[StarterImage + 4],
        ImageY[StarterImage + 4], ImageWidth[StarterImage + 4],
        ImageHeight[StarterImage + 4]);
    image(ImageAnimation[StarterImage + 5], ImageX[StarterImage + 5],
        ImageY[StarterImage + 5], ImageWidth[StarterImage + 5],
        ImageHeight[StarterImage + 5]);
    image(ImageAnimation[StarterImage + 6], ImageX[StarterImage + 6],
        ImageY[StarterImage + 6], ImageWidth[StarterImage + 6],
        ImageHeight[StarterImage + 6]);
    image(ImageAnimation[StarterImage + 7], ImageX[StarterImage + 7],
        ImageY[StarterImage + 7],ImageWidth[StarterImage + 7],
        ImageHeight[StarterImage + 7]);
    image(ImageAnimation[StarterImage + 8], ImageX[StarterImage + 8],
        ImageY[StarterImage + 8], ImageWidth[StarterImage + 8],
        ImageHeight[StarterImage + 8]);
    image(ImageAnimation[StarterImage + 9], ImageX[StarterImage + 9],
        ImageY[StarterImage + 9], ImageWidth[StarterImage + 9],
        ImageHeight[StarterImage + 9]);
    image(ImageAnimation[StarterImage + 10], ImageX[StarterImage + 10],
        ImageY[StarterImage + 10], ImageWidth[StarterImage + 10],
        ImageHeight[StarterImage + 10]);
    image(ImageAnimation[StarterImage + 11], ImageX[StarterImage + 11],
        ImageY[StarterImage + 11], ImageWidth[StarterImage + 11],
        ImageHeight[StarterImage + 11]);
    imageMode(CENTER);
    image(ImageAnimation[StarterImage + 12], ImageX[StarterImage + 12],
        ImageY[StarterImage + 12], ImageWidth[StarterImage + 12],
        ImageHeight[StarterImage + 12]);
    imageMode(CORNER);
    image(ImageAnimation[StarterImage + 13], ImageX[StarterImage + 13],
        ImageY[StarterImage + 13], ImageWidth[StarterImage + 13],
        ImageHeight[StarterImage + 13]);
    image(ImageAnimation[StarterImage + 14],ImageX[StarterImage + 14],
        ImageY[StarterImage + 14], ImageWidth[StarterImage + 14],
        ImageHeight[StarterImage + 14]);
    image(ImageAnimation[StarterImage + 15], ImageX[StarterImage + 15],
        ImageY[StarterImage + 15], ImageWidth[StarterImage + 15],
        ImageHeight[StarterImage + 15]);
    image(ImageAnimation[StarterImage + 16], ImageX[StarterImage + 16],
        ImageY[StarterImage + 16], ImageWidth[StarterImage + 16],
        ImageHeight[StarterImage + 16]);
    image(ImageAnimation[StarterImage + 17], ImageX[StarterImage + 17],
        ImageY[StarterImage + 17], ImageWidth[StarterImage + 17],
        ImageHeight[StarterImage + 17]);
    image(ImageAnimation[StarterImage + 18], ImageX[StarterImage + 18],
        ImageY[StarterImage + 18], ImageWidth[StarterImage + 18],
        ImageHeight[StarterImage + 18]);
    image(ImageAnimation[StarterImage + 19], ImageX[StarterImage + 19],
        ImageY[StarterImage + 19], ImageWidth[StarterImage + 19],
        ImageHeight[StarterImage + 19]);
    image(ImageAnimation[StarterImage + 20], ImageX[StarterImage + 20],
        ImageY[StarterImage + 20], ImageWidth[StarterImage + 20],
        ImageHeight[StarterImage + 20]);
    imageMode(CENTER);
    image(ImageAnimation[StarterImage + 21], ImageX[StarterImage + 21],
        ImageY[StarterImage + 21], ImageWidth[StarterImage + 21],
        ImageHeight[StarterImage + 21]);
    imageMode(CORNER);
    image(ImageAnimation[StarterImage + 22], ImageX[StarterImage + 22],
        ImageY[StarterImage + 22], ImageWidth[StarterImage + 22], height);
    image(ImageAnimation[StarterImage + 23], ImageX[StarterImage + 23],
        ImageY[StarterImage + 23], ImageWidth[StarterImage + 23],
        ImageHeight[StarterImage + 23]);
    image(ImageAnimation[StarterImage + 24], ImageX[StarterImage + 24],
        ImageY[StarterImage + 24], ImageWidth[StarterImage + 24],
        ImageHeight[StarterImage + 24]);
    image(ImageAnimation[StarterImage + 25], ImageX[StarterImage + 25],
        ImageY[StarterImage + 25], ImageWidth[StarterImage + 25],
        ImageHeight[StarterImage + 25]);
    image(ImageAnimation[StarterImage + 26], ImageX[StarterImage + 26],
        ImageY[StarterImage + 26], ImageWidth[StarterImage + 26],
        ImageHeight[StarterImage + 26]);

}

function mousePressed() { // Function for starting the animations and audio
    var AdelineDist = dist(mouseX, mouseY, 0.48 * AdelineX, 0.48 * AdelineY);
    // Creates variable to determine distance from the mouse to Adeline icon
    var HelenDist = dist(mouseX, mouseY, 0.48 * HelenX, 0.48 * HelenY);
    // Creates variable to determine distance from the mouse to Helen icon
    var TeddyDist = dist(mouseX, mouseY, 0.48 * TeddyX, 0.48 * TeddyY);
    // Creates variable to determine distance from the mouse to Teddy icon

    if (AdelineDist < 10) {
        playAdeline(); // Starts Adeline animation if mouse is pressed in icon
    }

    if (HelenDist < 10) {
        playHelen(); // Starts Helen animation if mouse is pressed in icon
    }

    if (TeddyDist < 10) {
        playTeddy(); // Starts Teddy animation if mouse pressed in icon
    }
}

Final_Project

Link to fixed project

This was a long project, and while I wasn’t able to accomplish everything that I wanted to it paid off. For my final project I decided that I should go out with a bang, and tried to help tell the stories of three survivors from the Rwandan genocide. I wanted to do help tell their story through imagery and help people understand some of the atrocities that were committed in Rwanda.  As a Jew, the stories of Rwanda reminded me of the atrocities committed during the Holocaust. I was also ashamed when I learned that America did almost nothing to aid the people of Rwanda.

Using the program is fairly simple. All you need to do is click on the red circles to play the story of each survivor. Each story will reset if you click a different circle.

Unfortunately I was unable to get my project working on Word Press. To view my project on the internet you will need to use a local server. To do this you will need to download either python or node.js.

Python:

For python, open the terminal and type in “python -m SimpleHTTPServer” (if you use python3 type in “python -m http.server”).

Next, you will need to type in “http://localhost:8000” in your web browser.

With this the project should load.

 

Node.js:

In a similar fashion to python, open your terminal or command panel.

Next, type in “sudo npm install -g http-server” if you use linux or “npm install -g http-server Then, type in “http-server”” if you use windows.

After that, cd the folder location on your computer. (For example, my folder is on my desktop, so I would type in “cd C:\Users\matth\Desktop\Final_Project”).

Then, type in “http-server”.

Finally, type “http://localhost:8080/” into a web browser.

Citations:

  • Processing. “Processing/p5.Js.” GitHub, 28 Sept. 2017, github.com/processing/p5.js/wiki/Local-server.

 

hannahk2-Final Project

Instructions to run the file:

1)Download and unzip the file below

spider

2) run a local server and access the file this way (it will not work otherwise unless you download the p5 editor and open it using the play button)

3) wait about 2 minutes before clicking the game to start. There are a lot of graphics so it takes a really long time to load so I would just keep clicking around the top of the screen after about 2 minutes until it loads and lets you play

4)refresh the page to restart if u lose and enjoy! Also don’t come too close to the edges of the screen.

Here is the embedded code just in case:

sketch

//Hannah Kim
//Section A
//hannahk2@andrew.cmu.edu
//Final Project

//variable for background image
var bg;
//variable for rain particles
var particles;
//variable for portal
var portalSprite;
//variable for random portal x position
var ran1;
//variable for random portal y position
var ran2;
//variable for spiders group
var spiders;

//arrays within array storing specific positions 
//of spiders on top of lillypads
var spiderPos = [
    [103, 242],
    [155, 260],
    [134, 292],
    [160, 311],
    [223, 290],
    [207, 299],
    [192, 304],
    [200, 328],
    [185, 322],
    [193, 362],
    [205, 347],
    [220, 374],
    [172, 377],
    [193, 405],
    [166, 399],
    [240, 422],
    [215, 428],
    [182, 430],
    [140, 410],
    [157, 339],
    [151, 362],
    [130, 315],
    [113, 347],
    [229, 413],
    [125, 377],
    [101, 389],
    [82, 356],
    [37, 397],
    [110, 429],
    [88, 440],
    [223, 459],
    [176, 468],
    [197, 488],
    [275, 450],
    [261, 436],
    [220, 476],
    [236, 518],
    [191, 536],
    [146, 546],
    [160, 518],
    [92, 480],
    [260, 543],
    [236, 582],
    [269, 284],
    [255, 289],
    [252, 313],
    [229, 314],
    [251, 334],
    [254, 378],
    [281, 384],
    [295, 271],
    [303, 286],
    [285, 300],
    [289, 331],
    [291, 352],
    [311, 338],
    [322, 318],
    [320, 292],
    [333, 340],
    [321, 380],
    [346, 361],
    [332, 403],
    [345, 429],
    [308, 428],
    [334, 449],
    [377, 415],
    [373, 391],
    [320, 492],
    [312, 476],
    [349, 484],
    [345, 502],
    [337, 548],
    [318, 529],
    [376, 510],
    [406, 375],
    [381, 352],
    [361, 301],
    [85, 539],
    [54, 575],
    [101, 610],
    [396, 301],
    [416, 317],
    [398, 338],
    [445, 325],
    [436, 352],
    [416, 397],
    [387, 448],
    [384, 481],
    [457, 437],
    [435, 484],
    [470, 352],
    [431, 555]
];

//sets normal game state with timer at 0
var gameState = "menu";
var timer = 0;

//preloads background image
function preload() {
    bg = loadImage("assets/spiderbg.png");
}

function setup() {
    createCanvas(500, 668);
    //sets random values for x position of portal
    ran1 = random(100, 400);
    //sets random values for y position of portal
    ran2 = random(550, 600);
    //creates sprite for the portal at random position 
    //and assigns animation
    portalSprite = createSprite(ran1, ran2);
    portalSprite.addAnimation("normal", "assets/portal0000.png", "assets/portal0002.png")
        //scales the portal to be smaller
    portalSprite.scale = .2;
    //slows down the frame rate of the animation
    portalSprite.animation.frameDelay = 20;

    //creates particle group for rain
    particles = new Group();
    //assign new sprites to groups
    for (var i = 0; i < 100; i++) {
        //puts all creation and initialization instructions in a 
        //premade function found at bottom of code
        createParticle();
    }

    //creates sprite group for spiders
    spiders = new Group();
    //for loop to create all spiders at positions in position array
    for (var i = 0; i < spiderPos.length; i++) {
        //creates spider sprites at specified positions
        var s = createSprite(spiderPos[i][0], spiderPos[i][1]);
        //animation for spiders in normal state
        s.addAnimation("playing", "assets/spider0000.png", "assets/spider0009.png");
        //plays the spider animation starting at different frames
        var f = floor(random(0, s.animation.getLastFrame()));
        s.animation.changeFrame(f);
        //animation for spiders when they're looking at you before game ends
        s.addAnimation("looking", "assets/spider0010.png", "assets/spider0012.png");
        //sets the circle around the spider which ends the game when touched
        s.setCollider("circle", 0, 0, 90);
        //increases the size of the spider as the y position increases
        //by indexing into the position array and multiplying by decimal
        var spiderSize = 0.04;
        s.scale = spiderSize * .005 * (spiderPos[i][1]);
        //trigger the looking function + looking animation when
        //mouse goes over the spider collider
        s.onMouseOver = function() {
                //changes animation to looking animation
                looking(spiders);
            }
        //add spider sprites
        spiders.add(s);
    }
}

//function for when you touch a spider and
//it looks at you and the game ends
function looking(g) {
    if (gameState == "game") {
        for (var i = 0; i < g.length; i++) {
            var sp = g[i];
            sp.changeAnimation("looking");
            //delays frame rate of animation
            sp.animation.frameDelay = 10;
        }
        gameState = "looking";
        //adds timer to countdown to game over state 
        //after the looking animation is triggered
        timer = 60;
    }
}

function draw() {
    background(255);
    //sets up the menu state with text and background
    if (gameState == "menu") {
        s = "OH NO! You have fallen down a sewer and have been plunged into a fantastical realm. Reach the portal swiftly to get back to the human realm without coming into contact with the spiders. Good luck! Click anywhere to begin."
        background(0)
        textSize(30);
        fill(156, 183, 226)
        text(s, 10, 10, 400, 400);
        s2 = "This fantasy realm, The Conjured Isles, is inhabited by hundred eyed spiders who are extremely wise. They usually pass their time playing in never ending rain. They live ontop of lillypads in the blood river. They are currently ruled by a mysterious creature that looms over the realm atop a black cloud, whom the people respect intensely."
        textSize(20);
        fill(156, 183, 226)
        text(s2, 10, 450, 400, 600);
        //on clicking on the screen the game starts + goes into "game" state
        if (mouseIsPressed) {
            gameState = "game";
        }
    }
    //draw sprites if the game state changes from menu
    if (gameState != "menu") {
        drawSprites();
        //counts down from timer once game state goes into "looking" and
        //at 0 the game state changes to "gameOver"
        if (gameState == "looking") {
            timer--;
            if (timer <= 0) {
                gameState = "gameOver";
            }
        }
        //sets up the game over state with text and background
        if (gameState == "gameOver") {
            background(0);
            s3 = "You were seen and banished by the spiders before you could reach the human realm. Better luck next time!"
            textSize(30);
            fill(156, 183, 226)
            text(s3, 10, 10, 400, 400);
            //if game state is not "gameOver" display normal background
        } else {
            image(bg);
            //if the mouse is within the bounds of the portal, 
            //change game state to won
            if (gameState == "game" & mouseX < ran1 + 25 && mouseX > ran1 - 25 &&
                mouseY < ran2 + 25 && mouseY > ran2 - 25) {
                gameState = "won";
            }
            //if the mouse gets too close to the left and right side
            //and the bottom side, (for cheaters), end game
            if (gameState == "game" & mouseX < 10 || mouseX > width - 10 || mouseY > height - 10) {
                gameState = "gameOver"
            }
            //sets up the won state with text and background
            //removes sprites
            if (gameState == "won") {
                background(0);
                s4 = "You reached successfully the portal and returned to the human realm! Congrats!"
                textSize(30);
                fill(156, 183, 226)
                text(s4, 10, 10, 400, 400);
                s.remove();
            }
            //code to draw the rain particles
            for (var i = 0; i < particles.length; i++) {
                //stores the particle in a temporary variable called p
                var p = particles[i];
                //scales it down
                p.scale = 0.15;
                //moves all the y positions of the particles down
                //for rain falling effect
                p.position.y += 10;
                //wraps particle to the top when it reaches the bottom
                if (p.position.y > height) {
                    p.position.y = -50;
                }
            }
            //draw all sprites
            drawSprites();
        }
    }
}
//function to create the rain particle
function createParticle() {
    //creates a sprite at a random position
    var newParticle = createSprite(random(0, width), random(0, height));
    //assigns an animation
    newParticle.addAnimation("falling", "assets/cloud.png");
    //adds it to the particle group
    particles.add(newParticle);
}

Here are screenshots of the game also:

^ the menu page

^the game in its normal state

^ the game when the player touches a spider

^ the game over state

^ the winning state

For this project I wanted to create a game based mostly on graphics, visuals, and backgrounds. I wanted to create a game where the player has to navigate through a tricky trap-like environment. The player has to avoid coming into contact with the inhabitants of an imaginary realm while hurrying to reach a portal to get back to the human realm. They have to navigate through a mob of spiders resting on top of lillypads without touching them and being seen. This project was really fun for me, despite having to code the positions of the spiders individually so that they would fit nicely on top of the lillypads that I chose. I really enjoyed making the background in particular, which I made for this project by painting first in watercolor, then scanning into photoshop and drawing ontop of it digitally. I also really enjoyed coming up with the narrative aspect of the project, and the world building.

jknip-Final-Project-SectionA

sketch

/*Jessica Nip
Section A
jknip@andrew.cmu.edu
Project-12
*/

//define global variables------------------------------------------------------
var x;
var y;
var dx;
var dy;
var current_block;
var old_blocks = [];
var blockw = 90;
var blockh = 70;
var clicked = false;
var score = 0;
var gameover = false;
var windowmargin = 10;
var start_speed;
var bground = ["https://i.imgur.com/gZ7wNWJ.png"];
var intro = "STACK THE HIGHEST TOWER.";

//colors
var darkblue;
var lightpink;
var lightred;
var grey;
var grey2;
var grey3;
var grey4;
var canvasw;
var canvash;


//---------------------------------------------------------------------------
function preload() {
    //background skyline
    bground = loadImage(bground[0]);
}


//---------------------------------------------------------------------------
function setup() {
    //define initial canvas settings
    createCanvas(350, 600);
    x = width/2;
    y = 10;
    dx = 1;
    dy = 0;
    frameRate(30);
    canvash = height;
    canvasw = width;
    start_speed = 1;

    //define color RGB
    darkblue = color(44,62,80);
    lightpink = color(252,146,179);
    lightred = color(252,67,73);
    grey = color(225);
    grey2 = color(215,218,219);
    grey3 = color(160);
    grey4 = color(200);

    //call object function
    current_block = new blockFeeder(width/2, 10, blockw,blockh,start_speed);
}


//---------------------------------------------------------------------------
function draw() {
    background(grey2);

    //skyline
    fill(darkblue);
    image(bground, 0, height*(3/5)-25, width, height/3);
    rect(0,height*(8/10), width, height);

    //sun
    fill(lightred);
    ellipse(width*(3/4),200,70,70);

    //gameover screen
    if (gameover){
        fill(darkblue);
        rect(0,0,width,height);
        fill(255);
        textSize(22);
        textStyle(BOLD);
        text("GAME OVER", width/4, height/2-height/30);
        textStyle(NORMAL);
        textSize(14);
        text("Your tower was " + score + "/F.", width/4, height/2);
    } 

    //stacking blocks correctly
    else {
        current_block.draw();
        current_block.update();

        for (var i = 0; i < old_blocks.length; i++) {
            if (score > 3){
                old_blocks[i].y += 2;
            }
            old_blocks[i].draw();
        }

        //gameover if blocks not stacked in same column
        if (score > 0){
            if (old_blocks[score-1].y > height){
                gameover = true;
            }      
        }

        countScore();

        //if block hits bottom of canvas, push block into old blocks array
        if (current_block.hitbottom) {
            old_blocks.push(current_block);
            start_speed += 1;
            current_block = new blockFeeder(width/2, 10, blockw,blockh,start_speed);
        }
    }
}


//create object-------------------------------------------------------------
function blockFeeder(x, y, width, height, speed) {
    this.x = x;
    this.y = y;
    this.dx = speed;
    this.dy = 0;
    this.width = width;
    this.height = height;
    this.isclicked = false;
    this.hitbottom = false;
    this.draw = function() {
    
    //crane (make it not fall with clicked block)
    if (!this.isclicked){
        fill(darkblue);
        noStroke();
        rect(this.x + this.width/2, this.y - windowmargin, this.width/6, this.height/6); 
    }

    //floor
    fill(grey3);
    stroke(grey);
    rect(this.x, this.y, this.width, this.height);

    //block window decor
    fill(grey);
    rect(this.x + windowmargin, this.y + windowmargin*2, this.width/3, this.height/2);
    rect(this.x + windowmargin*5, this.y + windowmargin*2, this.width/3, this.height/2);
    fill(grey4);
    stroke(grey);
    rect(this.x + windowmargin, this.y + windowmargin*2, this.width/3, this.height/3);
    rect(this.x + windowmargin*5, this.y + windowmargin*2, this.width/3, this.height/3);
    }

    //create horizontal crane movement
    this.update = function() {
        this.x += this.dx;
        this.y += this.dy;
        if ((this.x + this.width) > canvasw) {
            this.dx = -this.dx;
            } else if (this.x < 0) {
            this.dx = -this.dx;
        }

        //make new block stack on previous height boundary
        if (score == 0){
            if (this.y + this.height > canvash) {
                this.dy = 0;
                this.hitbottom = true;
                this.y = canvash - this.height;
            }
        }

        //check if new block collides with bottom block accordingly
        else {
            if (this.y + this.height > old_blocks[score-1].y) {
                if (abs(this.x-old_blocks[score-1].x) < blockw/2){
                    this.dy = 0;
                    this.hitbottom = true;
                    this.y = old_blocks[score-1].y - this.height;
                }
                else {
                    this.dy = 0;
                    this.hitbottom = true;
                    this.y = old_blocks[score-1].y - this.height;
                    gameover = true;
                }

            }
        }
    }

    //move block to bottom of canvas when clicked
    this.pressedButton = function(){
        this.isclicked = true;
        if (!this.hitbottom){
            this.dx = 0;
            this.dy = 10;
        }
    }

}


//---------------------------------------------------------------------------
function countScore(){
    //define type settings
    strokeWeight(1);
    fill(255);
    noStroke();
    textSize(20);
    textStyle(NORMAL);
    text(score + "/F", width - 45, height - 20);
    textSize(13);
    textStyle(BOLD);
    text(intro, windowmargin*2, height-20);

    //when block stacks, add score
    if (current_block.hitbottom) {
        score += 1;
    }

}


//---------------------------------------------------------------------------
function mousePressed() {
    //follow block rules when mouse is pressed
    current_block.pressedButton();
    //remove intro when mouse pressed
    intro = " ";
}


Instructions
Stack the highest tower by aligning blocks with at least 50% accuracy! The horizontal and vertical speed increases will make the level harder over time. Your tower height will also be recorded.

Description
Inspired by classic tower stack mobile games, I wanted to create an alternative version of it using a simple horizontal “crane”, with pressure given to the player from its increased speed over time. As the player begins to stack a higher tower, original blocks also begin to slide downwards, creating more time pressure for players. I also wanted to explore creating minimalistic graphics for a challenging, interactive game.

selinal-FinalProject

sketch

//Selina Lee
//Section C
//selinal@andrew.cmu.edu
//Final Project

var mapPic;//variable for image of map
var backPic; //background picture (collage of running in Pittsburgh)
var skiboStart; //turtle functions at different start poitns
//this one starts in front of skibo
var ovalStart; //this one occurs after reaching the schenley oval
var scaleX = 0.4; //scale down width wise from original canvas which is
// 480 / 1200
var scaleY = 0.6; //scale down height wise from original canvas whic is
// 480 / 800 

//arrays containing the points to draw run routes with turtle functions
//route titled beechwood (x and y points placed into arrays)
var beechX = [760, 789, 778, 808, 859, 895, 968, 980, 1014, 984, 1024, 950,
809, 737, 733];
var beechY = [277, 262, 244, 225, 221, 242, 242, 325, 324, 175, 111, 125, 189,
195, 237];
//route titled the point
var pointX = [740, 726, 719, 697, 687, 695, 677, 632, 592, 568, 560, 464, 402, 
268, 219, 35, 38, 61, 104, 148, 154, 201, 162, 183, 234, 418, 463, 502, 602, 
672, 695, 732, 722, 735, 733, 745];
var pointY = [295, 298, 312, 315, 327, 353, 372, 378, 365, 389, 418, 361, 356, 
379, 370, 279, 262, 258, 242, 226, 255, 244, 314, 328, 327, 338, 352, 355, 261,
235, 236, 234, 258, 261, 270, 275];
//route titled trader joe's
var traderX = [760, 789, 778, 808, 859, 859, 968, 1059, 1064, 1062, 1098, 964, 
943, 718, 731, 737, 733, 744, 734];
var traderY = [277, 262, 244, 225, 221, 242, 242, 221, 212, 204, 138, 24, 12, 
103, 147, 194, 234, 239, 270];
//route titled tranquil
var tranquilX = [760, 789, 778, 808, 859, 895, 968, 980, 1049, 1087, 1089, 1111,
1126, 1138, 1161, 1174, 1169, 1178, 1170, 1178, 1160, 1159, 1139, 1068, 1060, 
1059, 1139, 1068, 1060, 1059, 968, 895, 859, 808, 778];
var tranquilY = [277, 262, 244, 225, 221, 242, 242, 325, 324, 338, 345, 343, 
354, 346, 362, 350, 339, 322, 301, 287, 260, 234, 217, 191, 208, 218, 245, 242,
221, 225, 244];
//warmup route to work out location titled one-eight
var eightX = [743, 732, 715, 700, 686, 695, 687, 678, 687, 674, 673, 677, 671, 
683, 683, 692, 759, 782, 787, 778, 761, 721];
var eightY = [291, 295, 310, 315, 328, 349, 365, 379, 394, 397, 406, 411, 421, 
436, 444, 449, 403, 398, 392, 385, 391, 417];
//schenley oval route
var ovalX = [714, 720, 737, 746, 757, 764, 760, 751, 741, 720, 715];
var ovalY = [411, 415, 407, 396, 393, 389, 381, 379, 379, 395, 406];
//regular cool down route from oval
var coolX = [737, 778, 789, 794, 801, 789, 776, 733, 719, 709, 709, 713, 714, 
723, 740, 746];
var coolY = [408, 387, 387, 392, 386, 378, 374, 358, 355, 342, 328, 321, 311, 
308, 296, 274];
//other cool down route from oval called ten minute
var tenX = [724, 696, 684, 689, 688, 704, 690, 712, 707, 693, 696, 690, 694, 
724, 731, 741];
var tenY = [420, 439, 426, 416, 407, 404, 385, 379, 372, 363, 351, 326, 318, 
306, 294, 293];
//run titled southside
var southX = [745, 730, 740, 727, 673, 602, 499, 465, 418, 407, 409, 431, 477, 
486, 496, 523, 576, 602, 632, 680, 675, 682, 686, 699, 761, 782, 795, 784, 733, 
712, 694, 691, 694, 724, 731, 739];
var southY = [274, 271, 235, 233, 236, 262, 352, 354, 335, 417, 454, 460, 472, 
463, 455, 477, 437, 460, 469, 460, 443, 435, 448, 448, 400, 395, 382, 376, 357, 
350, 340, 323, 315, 304, 293, 293];

var counter = 0;// counter variable to count down differet routes shown
var backColR = 0; //background R value variable
var backColG = 0; //background G value variable
var backColB = 0; //background B value variable
var backColT = 270; //background opacity value

var colorArr = []; //empty array to contain color and placement creations
//see function fillInColorArray
var colors = ["black", "yellow"]; //colors to take


function preload() {
    mapPic = loadImage("https://i.imgur.com/zIVTSXM.jpg"); //map preload
    backPic = loadImage("https://i.imgur.com/vzuo6YG.jpg"); //background image
    //preload
}

function setup() {
    createCanvas(480, 480);
    image(backPic, 0, 0, map.width, map.height);//drawing map picture
    
    //used early on in project to find array points
    /*if(mouseIsPressed) {
     print(mouseX, mouseY); 
    }*/

    skiboStart = makeTurtle(747 * scaleX, 274 * scaleY); //draws turtles that 
    //start and end at Skibo
    ovalStart = makeTurtle(712 * scaleX, 410 * scaleY); // turtles that start at 
    //Schenley Oval 
    
    //I missed the criteria to scale the canvas to 480, so I used the scale 
    //variable to reduce the size of my points
    for(var i = 0; i < beechX.length; i++) {
        beechX[i] *= scaleX;
        beechY[i] *= scaleY;
    }
    for(var i = 0; i < pointX.length; i++) {
        pointX[i] *= scaleX;
        pointY[i] *= scaleY;
    }
    for(var i = 0; i < traderX.length; i++) {
        traderX[i] *= scaleX;
        traderY[i] *= scaleY;
    }
    for(var i = 0; i < tranquilX.length; i++) {
        tranquilX[i] *= scaleX;
        tranquilY[i] *= scaleY;
    }
    for(var i = 0; i < ovalX.length; i++) {
        ovalX[i] *= scaleX;
        ovalY[i] *= scaleY;
    }
    for(var i = 0; i < eightX.length; i++) {
        eightX[i] *= scaleX;
        eightY[i] *= scaleY;
    }
    for(var i = 0; i < coolX.length; i++) {
        coolX[i] *= scaleX;
        coolY[i] *= scaleY;
    }
    for(var i = 0; i < tenX.length; i++) {
        tenX[i] *= scaleX;
        tenY[i] *= scaleY;
    }
    for(var i = 0; i < southX.length; i++) {
        southX[i] *= scaleX;
        southY[i] *= scaleY;
    }
}

function mouseClicked() {
    counter++; //when mouse is clicked, create a counter to increment
    //every time 
    backColT = backColT - 20; //with every mouse click, the background
    //transparency gets more opaque
}


function draw() {
 image(backPic, 0, 0, map.width, map.height);//underlying image to be
 //revealed
 background(backColR, backColG, backColB, backColT); //background color
 //based on variable values

 fill(255); //prints directions on how to interact with piece ==>
 //continuous clicking reveals the different routes and visuals and black 
 //and white background
 text("Click on the canvas to reveal my running log in Pittsburgh!", 30, 
  30);

 if(mouseIsPressed) {
     print(mouseX, mouseY); //helps find position of mouse on map to draw 
     //turtle before translation
    }

    translate(-8, 50); //center the marks with these units
    
    //BEECHWOOD ROUTE: 5 MILES
    if (counter == 0 || counter >= 9) { //the start of the counter and when
    	//the mouse clicks through all slides, this will be shown
        for(var i = 0; i < beechX.length; i++) { //iterate through route 
            //arrays to get points. The array length should be the same for
        	//X and Y because I manually clicked on the screen to get place
        	//numbers
            skiboStart.setColor(color(255, 0, 255)); //magenta turtle
            skiboStart.penDown(); //start drawing
            skiboStart.goto(beechX[i], beechY[i]); //drawing beechwood route 
            //based on points in beechX and beechY array
            skiboStart.penUp();//stop drawing
            
            noStroke(); 
            fill(150, 0, 255, 80); //light, see-through, purple rectangles
            //these rectangles are drawn based on the values of the points
            //and the differences of the points on the path
            rect(beechX[i - 1], beechY[i - 1], beechX[i - 1] - beechX[i], 
             beechY[i - 1] - beechY[i]);
            rect(beechX[i], beechY[i], beechX[i] - beechX[i], 
             beechY[i - 1] - beechY[i]);
            rect(beechX[i - 1], beechY[i], beechX[i] - beechX[i - 1], 
             beechY[i] - beechY[i - 1]);
            rect(beechX[i], beechY[i], beechX[i] - beechX[i - 1], 
             beechY[i] - beechY[i - 1]);
        }
    }

    //THE POINT: 9.25 MILES
    fillInColorArr(0); //see function fillInColorArr 
    //this starts the function at place 0
    if (counter == 1 || counter >= 9) { //next shown visual from counter
    	//(all visuals are shown at the end of the list)
        for(var i = 0; i < pointX.length; i++) {
             backColB = 255; //background will be light blue
             backColG = 200;
             backColR = 100;

             skiboStart.setColor(colorArr[i]); //the color of each 
             //turtle move is based on fillInColorArr (while it 
             //iterates, a value is placed into the color function out
             //of the colorArr array)
             skiboStart.setWeight(5); //thicker line
             skiboStart.penDown();
             skiboStart.goto(pointX[i], pointY[i]);
             skiboStart.penUp();

             noFill();
             stroke(255, 255, 0); //yellow thin lines
             strokeWeight(1);
             beginShape(); //curves based off of Pittsburgh bridges
             //and the curve vertex control points are based on
             //position between selected points so that some
             //abstraction is visualized from the data
             curveVertex(pointX[i], pointY[i] + 30);
             curveVertex(pointX[i], pointY[i] + 30);
             curveVertex((pointX[i] + pointX[i - 1]) / 2, 
              (pointY[i - 1] + pointY[i]) / 4);
             curveVertex((pointX[i - 1] + pointX[i]) / 2, 
              (pointY[i - 1] + pointY[i]) / 4);
             curveVertex(pointX[i - 1], pointY[i - 1] + 30);
             curveVertex(pointX[i - 1], pointY[i - 1] + 30);
             endShape();
        }
    }

    //TRADER JOE'S: 5.5 MILES
    if(counter == 2  || counter >= 9) {
        for(var i = 0; i < traderX.length; i++) {
            backColR = 255; //light purple background
            backColG = 120;
            backColB = 200;

            skiboStart.setColor(color(200, 255, 0)); //green-yellow 
            skiboStart.setWeight(1)
            skiboStart.penDown();
            skiboStart.goto(traderX[i], traderY[i]);
            skiboStart.penUp();

            for(var j = 0; j < 5; j++) { //make 5 of this command
                 noFill();
                 strokeWeight(2); 
                 stroke(255, 200, 0); //orange bullseye design at 
                 //each turtle point
                 ellipse(traderX[i], traderY[i], 10 * j, 10 * j);
            }
        }
    }

    //TRANQUIL: 6.3 MILES
    if(counter == 3 || counter >= 9) { 
        for(var i = 0; i < tranquilX.length; i++) {
            backColB = 75; //dark blu background
            backColG = 0;
            backColR = 0;

            skiboStart.setColor(color(200, 255, 0)); //green-yellow
            skiboStart.setWeight(1);
            skiboStart.goto(tranquilX[i], tranquilY[i]);
            skiboStart.penUp();

            fill(255, 230, 0, 60); //see-through orange-yellow
            //circles drawn at each tranquil turtle point
            //one on top of the other like an eye
            ellipse(tranquilX[i], tranquilY[i], 20, 20); 
            ellipse(tranquilX[i], tranquilY[i], 8, 8);

            fill(150, 255, 100, 100); //see-through green
            noStroke();
            //these ellipses were drawn towards the top right of the turtle
            //route as a conglomeration
            ellipse(tranquilX[i] + 60, tranquilY[i] - 20, 50, 50);     
            fill(100, 255, 220, 100); //see-through blue-green
            ellipse(tranquilX[i] + 50, tranquilY[i] - 40, 40, 40); 
        }
    }

    //ONE EIGHT- WARMUP ROUTE TO SCHENLEY OVAL VIA THE BRIDAL PATH: 1.8 MILES
    if(counter == 4 || counter >= 9) {
        for(var i = 0; i < eightX.length; i++) {
         backColR = 255; //yellow background
         backColG = 255;
         backColB = 0;

            skiboStart.setColor(color(255, 0, 0)); //red turtle
            skiboStart.setWeight(1);
            skiboStart.penDown();
            skiboStart.goto(eightX[i], eightY[i]);
            skiboStart.penUp();

            fill(255, 50, 75, 20); //fill transparent red
            var maxX = max(eightX); //maximum value in x value array
            var minX = min(eightX); //minimum value in x value array
            var midX = (maxX + minX) / 2; //average of max and min value in 
            //x array

            var maxY = max(eightY); //maximum value in y array
            var minY = min(eightY); //minimum value in y array
            var midY = (maxY + minY) / 2; //avverage of max and min value in 
            //y array
            var curveX1; //first control x value point 
            var curveY1; //first control y value point
            var curveX2; //control two x value point
            var curveY2; //control two y value point

            if(eightX[i] < midX) { //if the turtle point is to the left of the 
             //"center"
             curveX1 = eightX[i] + 10; //if using bezier curve function, the 
             //first control point goes towards the middle 
             curveX2 = eightX[i] - 10; //then the second control point goes 
             //away from the center
            } else { //to the right of "center"
             curveX1 = eightX[i] - 10; //towards middle
             curveX2 = eightX[i] + 10; //away from center
            }

            if(eightY[i] < midY) { //if the turtle point is to the top of the 
             //middle of the route loop
             curveY1 = eightY[i] + 10; //the first control point goes down 
             //towards the center
             curveY2 = eightY[i] - 10; //second goes away from
            } else { //to bottom of route
             curveY1 = eightY[i] - 10; //first control point towards middle
             curveY2 = eightY[i] + 10; //away from middle
            }

            stroke(255, 100, 100, 200); //red
            strokeWeight(0.5);
            //the curves meet at a midpoint
            bezier(eightX[i], eightY[i], curveX1, curveY1, curveX2, curveY2, 
             midX, midY);
            bezier(eightX[i], eightY[i], curveX2, curveY2, curveX1, curveY1, 
             midX, midY);
        }
    }

    //OVAL LOOP = .625 MILES
    if(counter == 5 || counter >= 9) {
        for(var i = 0; i < ovalX.length; i++) {
            stroke(255, 100, 255, 70); //light magenta
            strokeWeight(40); //very thick line
            //used a line so the turtle function does not get confused 
            //and hide the movement created visually.
            //this line makes the same route as the turtle function
            line(ovalX[i], ovalY[i], ovalX[i - 1], ovalY[i - 1]);

            stroke(100, 150, 255, 120); //overlapping light blue lines
            //on top of oval lap so you can still see the purple underneath
            strokeWeight(15);
            line(ovalX[i - 1], ovalY[i - 1], ovalX[i], ovalY[i]);

            stroke(255, 200, 0); //orange turtle on top of laps
            strokeWeight(3);
            line(ovalX[i], ovalY[i], ovalX[i - 1], ovalY[i - 1]);
        }
    }

    //COOL DOWN ROUTE FROM SCHENLEY OVAL VIA PANTHER HOLLOW TRAIL: 1.3 MILES
    if(counter == 6 || counter >= 9) {
        for(var i = 0; i < coolX.length; i++) {
            ovalStart.setColor(color(0, 100, 255)); 
            ovalStart.setWeight(1);
            ovalStart.penDown();
            ovalStart.goto(coolX[i], coolY[i]);
            ovalStart.penUp();

            fill(100, 150, 255, 30);
            var maxX = max(coolX); //maximum value in x value array
            var minX = min(coolX); //minimum value in x value array
            var midX = (maxX + minX) / 2; //average of max and min value in 
            //x array

            var maxY = max(coolY); //maximum value in y array
            var minY = min(coolY); //minimum value in y array
            var midY = (maxY + minY) / 2; //avverage of max and min value in 
            //y array
            var curveX1; //first control x value point 
            var curveY1; //first control y value point
            var curveX2; //control two x value point
            var curveY2; //control two y value point

            if(coolX[i] < midX) { //if the turtle point is to the left of the 
                //"center"
                curveX1 = coolX[i] + 10; //if using bezier curve function, the 
                //first control point goes towards the middle 
                curveX2 = coolX[i] - 10; //then the second control point goes 
                //away from the center
            } else { //to the right of "center"
                 curveX1 = coolX[i] - 10; //towards middle
                 curveX2 = coolX[i] + 10; //away from center
            }

            if(coolY[i] < midY) { //if the turtle point is to the top of the 
                //middle of the route loop
                curveY1 = coolY[i] + 10; //the first control point goes down 
                //towards the center
                curveY2 = coolY[i] - 10; //second goes away from
            } else { //to bottom of route
                curveY1 = coolY[i] - 10; //first control point towards middle
                curveY2 = coolY[i] + 10; //away from middle
            }

            stroke(0, 200, 255, 200);
            strokeWeight(.5);
            bezier(coolX[i], coolY[i], curveX1, curveY1, curveX2, curveY2, midX,
             midY);
            bezier(coolX[i], coolY[i], curveX2, curveY2, curveX1, curveY1, midX, 
             midY);
        }
    }

    //TEN MINUTE COOL DOWN: 1.1 MILES
   if(counter == 7 || counter >= 9) {
       for(var i = 0; i < tenX.length; i++) {
           ovalStart.setColor(color(0, 150, 255));
           ovalStart.penDown();
           ovalStart.goto(tenX[i], tenY[i]);
           ovalStart.penUp();

           fill(20, 20, 255, 30);
           var maxX = max(tenX); //maximum value in x value array
           var minX = min(tenX); //minimum value in x value array
           var midX = (maxX + minX) / 2; //average of max and min value in 
           //x array

           var maxY = max(tenY); //maximum value in y array
           var minY = min(tenY); //minimum value in y array
           var midY = (maxY + minY) / 2; //avverage of max and min value in 
           //y array
           var curveX1; //first control x value point 
           var curveY1; //first control y value point
           var curveX2; //control two x value point
           var curveY2; //control two y value point

           if(tenX[i] < midX) { //if the turtle point is to the left of the 
               //"center"
               curveX1 = tenX[i] + 10; //if using bezier curve function, the 
               //first control point goes towards the middle 
               curveX2 = tenX[i] - 10; //then the second control point goes 
               //away from the center
            } else { //to the right of "center"
               curveX1 = tenX[i] - 10; //towards middle
               curveX2 = tenX[i] + 10; //away from center
            }

            if(tenY[i] < midY) { //if the turtle point is to the top of the 
                //middle of the route loop
                curveY1 = tenY[i] + 10; //the first control point goes down 
                //towards the center
                curveY2 = tenY[i] - 10; //second goes away from
            } else { //to bottom of route
                curveY1 = tenY[i] - 10; //first control point towards middle
                curveY2 = tenY[i] + 10; //away from middle
            }

            stroke(0, 150, 255, 200);
            strokeWeight(0.5);
            bezier(tenX[i], tenY[i], curveX1, curveY1, curveX2, curveY2, midX, 
             midY);
            bezier(tenX[i], tenY[i], curveX2, curveY2, curveX1, curveY1, midX, 
             midY);
     }
  }

  //SOUTHSIDE: 6.6 MILES
  if(counter == 8 || counter >= 9) {
      for(var i = 0; i < southX.length; i++) {
      	  backColG = 255; //green background
      	  backColR = 50;
      	  backColB = 100;

          skiboStart.setColor(color(255, 0, 255)); 
          skiboStart.penDown();
          skiboStart.goto(southX[i], southY[i]);
          skiboStart.penUp();

          stroke(255, 50, 100); //red
          fill(255, 120, 50, 50); //transparent red orange
          //lines drawn to create turtle skeleton
          line(southX[i], southY[i], southX[i] * 0.9, southY[i] + 20);
          line(southX[i] * 0.9, southY[i] + 20, southX[i - 1] * 0.9, 
          southY[i - 1] + 20); 
          line(southX[i - 1] * 0.9, southY[i - 1] + 20, southX[i] * 0.85, 
          southY[i] - 30);
          line(southX[i] * 0.85, southY[i] - 30, southX[i - 1] * 0.85, 
          southY[i - 1] - 30);
          line(southX[i] * 0.85, southY[i] - 30, 180, 330);

          noStroke();
          //triangles based off of parameters to create line skeleton
          triangle(southX[i], southY[i], southX[i] * 0.9, southY[i] + 20,
          southX[i - 1] * 0.9, southY[i - 1] + 20);
          triangle(southX[i - 1] * 0.9, southY[i - 1] + 20, 
          southX[i] * 0.85, southY[i] - 30, 180, 330)
       }
  }
}

function fillInColorArr(filledSoFar) { //recursive function to change color
	//every action of the turtle 
    if(filledSoFar == 0) { //if nothing has been drawn yet, leave the array 
        colorArr = []; 
        colorArr.push(colors[0]); //push the colors from colors array into
        //colorArr so that they can be used and start from 0 which is "black"
        var currentFillNumber = filledSoFar + 1; //counts which property has
        //recieved a color to use
        fillInColorArr(currentFillNumber); //fill in this area with the color
        //corresponding to the placement of the turtle in its start point in 
        //its array
    } else if(filledSoFar >= pointX.length) {
        return;
    } else { //if the paremeters that have been filled so far do not exceed 
    	//the length of the point array, do the same as if nothing has been
    	//drawn yet and give the parameter a color to use
        colorArr.push(colors[filledSoFar % colors.length]);
        var currentFillNumber = filledSoFar + 1;
        fillInColorArr(currentFillNumber);
    }
}

function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

mmiller5-Final Project

Instructions: Press any key to continue when text is finished scrolling.  Click on choice boxes to select choice.

sketch

//choice variables
var choiceNow = false;
var choiceSoon = false;
var lastChoice = 1;
var buttonChoice = [0, 0, 0, 0, 0];
var choice1 = ["Go Forward", "Feel Around", "Stay Still"];
var choice2 = ["Go Back", "Kick", "Fall Down"];
var choice3 = ["Scarlet", "Cerulean", "Emerald", "None"];
var doorUnlocked = false;

//text variables
var textAll = []; //array containing all text objects
var textList = [
    //0-2
    "You awake to find yourself in a dark room.",
    "You can't see anything, probably because it is dark.",
    "What are you going to do?",
    //3-5
    "You decide to move forward, not that it really matters what direction you move in because it all looks the same.",
    "This area of the room smells like apples; it makes you nauseous.",
    "Now what are you going to do?",
    //6-9
    "You decide that this area isn't as good as the last one, so you walk backwards to whence you came.",
    "As you moonwalk to your origin, the apple smell dissipates, easing your uneasiness.",
    "Now back in your starting area, you feel a calm serenity wash over your eyebrows.",
    "What are you going to do?",
    //10-13
    "You decide to wave your arms frantically, almost instantly thwacking a wall to your left.",
    "After massaging your injured hand, you run your hand across the wall and notice some buttons.",
    "There are 3 buttons, and you are stupidly confident that you know their colors even though it is pitch black.",
    "Which button do you wish to press?",
    //14-15
    "You hear a satisfying 'Click' as you press the Scarlet button.",
    "Which button do you wish to press?",
    //16-17
    "The Cerulean button gives you much resistance, but you eventually manage to become victorious and press the button.",
    "Which button do you wish to press?",
    //18-19
    "You feel an exhilerating rush of energy enter your body through your fingertip as you press the Emerald button.",
    "Which button do you wish to press?",
    //20-22
    "You decide that the buttons aren't worthy of your tender carresses and go back.",
    "You are back where you were before, it's just as dark as before.",
    "What are you going to do?",
    //23-29
    "You decide that this is probably all a dream and that the proper course of action is to do nothing.",
    "After doing nothing for so long, you become drowsy, eventually falling asleep on the floor.",
    "zzzzzzzzz",
    "...",
    "You awake to find yourself in a dark room.",
    "You can't see anything, probably because it is dark.",
    "What are you going to do?",
    //30-34
    "You decide to vent your frustrations by violently thrusting your foot forward, only for it to meet a metal object.",
    "The metal object wins, leaving your foot in a sorry state.",
    "You examine the metal object more closely and discover that it's a door, but it's locked.",
    "You recover from your defeat and contemplate your course of action.",
    "What are you going to do?",
    //35-40
    "You decide to do some pushups, but your arms are too weak and you fall to the floor.",
    "When your nose crunches against the cold ground, you feel some engravings scratch against you.",
    "Rubbing your fingers across the floor, you feel some words.",
    "'Blue', 'Green', 'Blue', 'Red', 'Green'.",
    "Wondering what these words mean, you stand back up and wipe the blood from your upper lip.",
    "What are you going to do?",
    //41-43
    "You decide to cautiously extend your foot outwards, but there is nothing there to challenge its movement.",
    "You then advance through the empty space, no metal object impeding your progress.",
    "Did you escape? Or is this just the beginning?"];
var textNum = 0;
var currentText = 0;
var count = 0;
var letterGap = 10;
var timeGap = 3; //timing between letter placements
var textTop; //top of text box
var textLimit; //length of displayed text

function setup() {
    createCanvas(480, 360);
    textSize(20);
    textTop = 2 * height / 3;
    textAlign(CENTER);
    textAssign();
}
function draw() {
    currentText = textNum;
    background(0);
    present(1, 2, choice1, 3, 2, 10, 4, 23, 9);
    present(2, 5, choice2, 6, 3, 30, 10, 35, 11);
    present(3, 9, choice1, 3, 2, 10, 4, 23, 9);
    present4();
    present5();
    present6();
    present7();
    present(8, 22, choice1, 3, 2, 10, 4, 23, 9);
    present(9, 29, choice1, 3, 2, 10, 4, 23, 9);
    if (lastChoice == 10) {
	if (doorUnlocked) {
	    lastChoice = 12;
	    textNum = 41
	} else {
	    present(10, 34, choice2, 6, 3, 30, 10, 35, 11);
	}
    }
    present(11, 40, choice2, 6, 3, 30, 10, 35, 11);
    present(12);
    unlockDoor();
}
//put each text line into an object
function textAssign() {
    for (var i = 0; i < textList.length; i ++) {
	var newText = {words: textList[i],
		       scroll: textScroll,
		       next: nextText}
	textAll.push(newText);
    }
}
//access the line of text and display it in a scroll style
function textScroll() {
    fill(255);
    strokeWeight(0);
    stroke(255);
    textSize(2 * letterGap);
    var xPos = 0;
    var yPos = 0;
    textLimit = min((count / timeGap), this.words.length);
    for (var i = 0; i < textLimit; i ++) {
	xPos += letterGap;
	//if overflow, start a new line
	if (25 + letterGap + xPos > width - 25 - letterGap) {
	    xPos = letterGap;
	    yPos += letterGap * 2;
	}
	text(this.words.charAt(i), 25 + letterGap + xPos,
	     textTop + letterGap * 2 + yPos);
    }
    count = min(count + 1, this.words.length * timeGap);
    if (count == this.words.length * timeGap & choiceSoon == true) {
	choiceNow = true;
    } else {
	choiceNow = false;
    }
}
//perform text functions
function textStep(t) {
    textAll[t].scroll();
    textAll[t].next();
    textBox();
}
//displays the text box
function textBox() {
    noFill();
    strokeWeight(3);
    stroke(255);
    rectMode(CORNERS);
    rect(25, textTop, width - 25, height - 25);
}
//make it so when you press a key, next text comes in
function nextText() {
    if (count == this.words.length * timeGap
	& keyIsPressed == true
	&& textNum != textList.length - 1
	&& choiceSoon == false) {
	textNum += 1
	count = 0;
    }
}
//display the choice options in multiple boxes
function choiceDisplay(choice) {
    for (var i = 0; i < choice.length; i ++) {
	var boxSide = (width - 25 * (choice.length + 1)) / choice.length;
	noFill();
	strokeWeight(2);
	stroke(255);
	rectMode(CORNER);
	rect(25 * (i + 1) + (boxSide * i),
	     height / 3 - boxSide / 2, boxSide, boxSide);
	fill(255);
	strokeWeight(1);
	text(choice[i], 25 * (i + 1) + (boxSide * i) + boxSide / 2, height / 3);
    }
}
//allow player to make a choice depending on click location
function choiceAction(choice) {
    var boxSide = (width - 25 * (choice.length + 1)) / choice.length;
    if (mouseIsPressed) {
	if (mouseY > height / 3 - boxSide / 2 &
	    mouseY < height / 3 + boxSide / 2) {
	    for (var i = 0; i < choice.length; i ++) {
		if (mouseX > 25 * (i + 1) + (boxSide * i) &
		    mouseX < 25 * (i + 1) + (boxSide * i) + boxSide) {
		    return i;
		}
	    }
	}
    }
}
//button panel
function present4() {
    if (lastChoice == 4) {
	textStep(currentText);
	if (currentText == 13) {
	    choiceSoon = true;
	    if (choiceNow == true) {
		choiceDisplay(choice3);
		var choice = choiceAction(choice3);
		if (choice == 0) {
		    textNum = 14;
		    lastChoice = 5;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(1);
		} else if (choice == 1) {
		    textNum = 16;
		    lastChoice = 6;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(2);
		} else if (choice == 2) {
		    textNum = 18;
		    lastChoice = 7;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(3);
		} else if (choice == 3) {
		    textNum = 20;
		    lastChoice = 8;
		    count = 0;
		}
	    }
	} else {
	    choiceSoon = false;
	}
    }
}
//scarlet button press
function present5() {
    if (lastChoice == 5) {
	textStep(currentText);
	if (currentText == 15) {
	    choiceSoon = true;
	    if (choiceNow == true) {
		choiceDisplay(choice3);
		var choice = choiceAction(choice3);
		if (choice == 0) {
		    textNum = 14;
		    lastChoice = 5;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(1);
		} else if (choice == 1) {
		    textNum = 16;
		    lastChoice = 6;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(2);
		} else if (choice == 2) {
		    textNum = 18;
		    lastChoice = 7;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(3);
		} else if (choice == 3) {
		    textNum = 20;
		    lastChoice = 8;
		    count = 0;
		}
	    }
	} else {
	    choiceSoon = false;
	}
    }
}
//cerulean button press
function present6() {
    if (lastChoice == 6) {
	textStep(currentText);
	if (currentText == 17) {
	    choiceSoon = true;
	    if (choiceNow == true) {
		choiceDisplay(choice3);
		var choice = choiceAction(choice3);
		if (choice == 0) {
		    textNum = 14;
		    lastChoice = 5;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(1);
		} else if (choice == 1) {
		    textNum = 16;
		    lastChoice = 6;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(2);
		} else if (choice == 2) {
		    textNum = 18;
		    lastChoice = 7;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(3);
		} else if (choice == 3) {
		    textNum = 20;
		    lastChoice = 8;
		    count = 0;
		}
	    }
	} else {
	    choiceSoon = false;
	}
    }
}
//emerald button press
function present7() {
    if (lastChoice == 7) {
	textStep(currentText);
	if (currentText == 19) {
	    choiceSoon = true;
	    if (choiceNow == true) {
		choiceDisplay(choice3);
		var choice = choiceAction(choice3);
		if (choice == 0) {
		    textNum = 14;
		    lastChoice = 5;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(1);
		} else if (choice == 1) {
		    textNum = 16;
		    lastChoice = 6;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(2);
		} else if (choice == 2) {
		    textNum = 18;
		    lastChoice = 7;
		    count = 0;
		    buttonChoice.shift();
		    buttonChoice.push(3);
		} else if (choice == 3) {
		    textNum = 20;
		    lastChoice = 8;
		    count = 0;
		}
	    }
	} else {
	    choiceSoon = false;
	}
    }
}

//door open exit
function present12() {
    if (lastChoice == 12) {
	choiceSoon = false;
	textStep(currentText);
    }
}

//general present function, isn't used for button presses
function present(lastC, choiceLine, choiceNum, newTextNum0, newLastC0, newTextNum1,
		 newLastC1, newTextNum2, newLastC2) {
    if (lastChoice == lastC) {
	textStep(currentText);
	if (currentText == choiceLine) {
	    choiceSoon = true;
	    if (choiceNow == true) {
		choiceDisplay(choiceNum);
		var choice = choiceAction(choiceNum);
		if (choice == 0) {
		    textNum = newTextNum0;
		    lastChoice = newLastC0;
		    count = 0;
		} else if (choice == 1) {
		    textNum = newTextNum1;
		    lastChoice = newLastC1;
		    count = 0;
		} else if (choice == 2) {
		    textNum = newTextNum2;
		    lastChoice = newLastC2;
		    count = 0;
		} else if (choice == 3) {
		    textNum = newTextNum3;
		    lastChoice = newLastC3;
		    count = 0;
		}
	    }
	} else {
	    choiceSoon = false;
	}
    }
}

function unlockDoor() {
    if (buttonChoice[0] == 2 &
	buttonChoice[1] == 3 &&
	buttonChoice[2] == 2 &&
	buttonChoice[3] == 1 &&
	buttonChoice[4] == 3) {
	doorUnlocked = true;
    }
}

This project was pretty fun to work on, but I’m actually a bit disappointed in it.  It’s a text-based adventure with a simple non-puzzle that’s really more of a proof of concept.

rgroves – Final – Section B

sketch

//vertices and edge sets of the individual graphs
var V = [];
var E = [];

//total set of vertices
var vertices = [];
var spacing = 48;

//buttons for coloring vertices
var redbutton;
var bluebutton;
var greenbutton;
var pinkbutton;
var orangebutton
var buttons = [];

var levelnumber = 1;
var mousehasentbeenclicked;

function setup() {
    createCanvas(480, 400);
    background(255);
    resetLevel();
}

function resetLevel() {
	mousehasentbeenclicked = true;
	 background(255);
    //create buttons
    redbutton = makeButton(width/6, color(209, 90, 90));
	bluebutton = makeButton(2 * width/6, color(93, 137, 196));
	greenbutton = makeButton(3 * width/6, color(199, 197, 71));
	pinkbutton = makeButton(4 * width/6, 'lightpink');
	orangebutton = makeButton(5 * width/6, 'orange');
	buttons = [redbutton, bluebutton, greenbutton, pinkbutton, orangebutton];
	for (i = 0; i < buttons.length; i++) {
		buttons[i].isoutlined = false;
		buttons[i].draw();
	}

	//draw grid of small vertices and label them from 0 to 53 in an array
    for (i = 0; i < width/spacing - 1; i++) {
    	for (j = 0; j < 300/spacing - 1; j++) {
	   		vertices[i + ((width/spacing - 1) * j)] = 
	   		makeVertex(spacing + i * spacing, spacing + j * spacing);
    	}
    }
}

//OBJECTS: VERTICES, EDGES, BUTTONS////////////////////////////////////////////

//vertices
function vertexboldDraw() {
	noStroke();
	if (this.isred == true) {
		fill(209, 90, 90);
		ellipse(this.x, this.y, 16, 16);	
	} else if (this.isblue == true) {
		fill(93, 137, 196);
		ellipse(this.x, this.y, 16, 16);	
	} else if (this.isgreen == true) {
		fill(199, 197, 71);
		ellipse(this.x, this.y, 16, 16);	
	} else if (this.ispink == true) {
		fill('lightpink');
		ellipse(this.x, this.y, 16, 16);
	} else if (this.isorange == true) {
		fill('orange');
		ellipse(this.x, this.y, 16, 16);
	} else {
		stroke(150);
		strokeWeight(1);
		fill(255);	
		ellipse(this.x, this.y, 15, 15);	
	}
}

function vertexDraw() {
	noStroke();
	fill(180);
	ellipse(this.x, this.y, 1.5, 1.5);
}

function makeVertex(px, py) {
	v = {x: px, y: py, draw: vertexDraw, bolddraw: vertexboldDraw,
		isred: false, isgreen: false, isblue: false, ispink: false,
		isorange: false};
	return v;
}

//edges
function edgeDraw(m, n) {
	if (this.iscolored == true & this.iscorrect == true) {
		strokeWeight(3);
		stroke('limegreen');
	} else if (this.iscolored == true & this.iscorrect == false) {
		strokeWeight(3);
		stroke('tomato');
	} else if (this.iscolored == false) {
		strokeWeight(.5);
		stroke(200);
	}
    line(vertices[this.m].x, vertices[this.m].y,
    vertices[this.n].x, vertices[this.n].y);
}

function makeEdge(pm, pn) {
	e = {m: pm, n: pn, iscolored: false, iscorrect: true, draw: edgeDraw};
	return e
}

//buttons
function buttonDraw() {
	rectMode(CENTER);
	if (this.isoutlined == true) {
		strokeWeight(3);
		stroke(255);
		fill(this.buttoncolor);
		rect(this.x, height - 50, 60, 20);
	} else {
		noStroke();
		fill(this.buttoncolor);
		rect(this.x, height - 50, 61.5, 21.5);
	}	
	
}

function makeButton(px, color) {
	b = {x: px, buttoncolor: color, isoutlined: false, draw: buttonDraw};
	return b;
}

//FUNCTIONS TO BE CALLED IN MOUSEPRESSED///////////////////////////////////////
function testEdge() {
	//edges are green if the vertices are different color and red if they are 
	//the same colors
	for (i = 0; i < E.length; i++) {
		if (vertices[E[i].m].isred == true & vertices[E[i].n].isred == true) {
			E[i].iscolored = true;
			E[i].iscorrect = false;
		}
		if (vertices[E[i].m].isblue == true & vertices[E[i].n].isblue == true) {
			E[i].iscolored = true;
			E[i].iscorrect = false;
		}
		if (vertices[E[i].m].isgreen == true & vertices[E[i].n].isgreen == true) {
			E[i].iscolored = true;
			E[i].iscorrect = false;
		}
		if (vertices[E[i].m].ispink == true & vertices[E[i].n].ispink == true) {
			E[i].iscolored = true;
			E[i].iscorrect = false;
		}
		if (vertices[E[i].m].isorange == true & vertices[E[i].n].isorange == true) {
			E[i].iscolored = true;
			E[i].iscorrect = false;
		}
		if ((vertices[E[i].m].isred == true || vertices[E[i].m].isblue == true ||
			vertices[E[i].m].isgreen == true || vertices[E[i].m].ispink == true
			|| vertices[E[i].m].isorange == true) & (vertices[E[i].n].isred == true 
			|| vertices[E[i].n].isblue == true || vertices[E[i].n].isgreen == true
			|| vertices[E[i].n].ispink == true || vertices[E[i].n].isorange == true)) {
			E[i].iscolored = true;
		}
		if (E[i].iscolored == true & (vertices[E[i].m].isred !== vertices[E[i].n].isred
			|| vertices[E[i].m].isblue !== vertices[E[i].n].isblue
		    || vertices[E[i].m].isgreen !== vertices[E[i].n].isgreen 
		    || vertices[E[i].m].ispink !== vertices[E[i].n].ispink
		    || vertices[E[i].m].isorange !== vertices[E[i].n].isorange)) {
			E[i].iscolored = true;
			E[i].iscorrect = true;
		}
		E[i].draw();
	}
}

function colorVertices() {
	//change colors of vertices when clicked, depending on which button has 
	//most recently been clicked
	for (i = 0; i < V.length; i++) {
		if (dist(mouseX, mouseY, vertices[V[i]].x, vertices[V[i]].y) < 10) {
			if (buttons[0].isoutlined == true & buttons[1].isoutlined == false &&
				buttons[2].isoutlined == false && buttons[3].isoutlined == false &&
				buttons[4].isoutlined == false) {
				vertices[V[i]].isred = true;
				vertices[V[i]].isblue = false;
				vertices[V[i]].isgreen = false;
				vertices[V[i]].ispink = false;
				vertices[V[i]].isorange = false;
			}
			if (buttons[0].isoutlined == false & buttons[1].isoutlined == true &&
				buttons[2].isoutlined == false && buttons[3].isoutlined == false &&
				buttons[4].isoutlined == false) {
				vertices[V[i]].isred = false;
				vertices[V[i]].isblue = true;
				vertices[V[i]].isgreen = false;
				vertices[V[i]].ispink = false;
				vertices[V[i]].isorange = false;
			}
			if (buttons[0].isoutlined == false & buttons[1].isoutlined == false &&
				buttons[2].isoutlined == true && buttons[3].isoutlined == false &&
				buttons[4].isoutlined == false) {
				vertices[V[i]].isred = false;
				vertices[V[i]].isblue = false;
				vertices[V[i]].isgreen = true;
				vertices[V[i]].ispink = false;
				vertices[V[i]].isorange = false;
			}
			if (buttons[0].isoutlined == false & buttons[1].isoutlined == false &&
				buttons[2].isoutlined == false && buttons[3].isoutlined == true &&
				buttons[4].isoutlined == false) {
				vertices[V[i]].isred = false;
				vertices[V[i]].isblue = false;
				vertices[V[i]].isgreen = false;
				vertices[V[i]].ispink = true;
				vertices[V[i]].isorange = false;
			}
			if (buttons[0].isoutlined == false & buttons[1].isoutlined == false &&
				buttons[2].isoutlined == false && buttons[3].isoutlined == false &&
				buttons[4].isoutlined == true) {
				vertices[V[i]].isred = false;
				vertices[V[i]].isblue = false;
				vertices[V[i]].isgreen = false;
				vertices[V[i]].ispink = false;
				vertices[V[i]].isorange = true;
			}
		}
	}
}

function pressButton() {
	//select color for vertex coloring
	if (mouseX >= buttons[0].x - 30 & mouseX <= buttons[0].x + 30 
		&& mouseY <= height - 40 && mouseY >= height - 60) {
			buttons[0].isoutlined = true;
			buttons[1].isoutlined = false;
			buttons[2].isoutlined = false;
			buttons[3].isoutlined = false;
			buttons[4].isoutlined = false;
			for (i = 0; i < buttons.length; i++) {
				buttons[i].draw();
			}
	}
	if (mouseX >= buttons[1].x - 30 & mouseX <= buttons[1].x + 30 
		&& mouseY <= height - 40 && mouseY >= height - 60) {
			buttons[0].isoutlined = false;
			buttons[1].isoutlined = true;
			buttons[2].isoutlined = false;
			buttons[3].isoutlined = false;
			buttons[4].isoutlined = false;
			for (i = 0; i < buttons.length; i++) {
				buttons[i].draw();
			}
	}
	if (mouseX >= buttons[2].x - 30 & mouseX <= buttons[2].x + 30 
		&& mouseY <= height - 40 && mouseY >= height - 60) {
			buttons[0].isoutlined = false;
			buttons[1].isoutlined = false;
			buttons[2].isoutlined = true;
			buttons[3].isoutlined = false;
			buttons[4].isoutlined = false;
			for (i = 0; i < buttons.length; i++) {
				buttons[i].draw();
			}
	}
	if (mouseX >= buttons[3].x - 30 & mouseX <= buttons[3].x + 30 
		&& mouseY <= height - 40 && mouseY >= height - 60) {
			buttons[0].isoutlined = false;
			buttons[1].isoutlined = false;
			buttons[2].isoutlined = false;
			buttons[3].isoutlined = true;
			buttons[4].isoutlined = false;
			for (i = 0; i < buttons.length; i++) {
				buttons[i].draw();
			}
	}
	if (mouseX >= buttons[4].x - 30 & mouseX <= buttons[4].x + 30 
		&& mouseY <= height - 40 && mouseY >= height - 60) {
			buttons[0].isoutlined = false;
			buttons[1].isoutlined = false;
			buttons[2].isoutlined = false;
			buttons[3].isoutlined = false;
			buttons[4].isoutlined = true;
			for (i = 0; i < buttons.length; i++) {
				buttons[i].draw();
			}
	}
}

//DESIGN LEVELS AND CALL THEM IN DRAW//////////////////////////////////////////
function levelOne() {
	textSize(10);
	strokeWeight(.4);
	fill('grey');
	text('Level One: Practice', 30, 10);
	E = [[25, 4], [19, 4], [25, 51], [51, 47], [47, 19], [4, 13], [25, 24], 
	[51, 41], [47, 39], [19, 20], [13, 41], [41, 20], [20, 24], [24, 39], 
	[39, 13]];
	for (i = 0; i < E.length; i++) {
		E[i] = makeEdge(E[i][0], E[i][1]);
		if (mousehasentbeenclicked) {
			E[i].draw();
		}
	}
	V = [4, 13, 19, 20, 24, 25, 39, 41, 47, 51];
	for (i = 0; i < V.length; i++) {
		vertices[V[i]].bolddraw();
	} 	
}

function levelTwo() {
	textSize(10);
	strokeWeight(.4);
	fill('grey');
	text('Level Two', 30, 10);
	E = [[25, 4], [19, 4], [25, 51], [51, 47], [47, 19], [38, 47], [47, 51], 
	[51, 42], [42, 38], [38, 51], [42, 47], [42, 19], [25, 38], [4, 38], 
	[4, 42], [19, 38], [25, 42]];
	for (i = 0; i < E.length; i++) {
		E[i] = makeEdge(E[i][0], E[i][1]);
		if (mousehasentbeenclicked) {
			E[i].draw();
		}
	}
	V = [4, 19, 25, 38, 42, 47, 51];
	for (i = 0; i < V.length; i++) {
		vertices[V[i]].bolddraw();
	} 	
}

function levelThree() {
	textSize(10);
	strokeWeight(.4);
	fill('grey');
	text('Level Three', 30, 10);
	E = [[4, 31], [31, 17], [31, 53], [31, 45], [31, 9], [12, 14], [14, 33], 
	[33, 40], [40, 29], [29, 12], [4, 29], [4, 14], [17, 12], [17, 33], [53, 14], 
	[53, 40], [45, 33], [45, 29], [9, 40], [9, 12]];
	for (i = 0; i < E.length; i++) {
		E[i] = makeEdge(E[i][0], E[i][1]);
		if (mousehasentbeenclicked) {
			E[i].draw();
		}
	}
	V = [4, 9, 12, 14, 17, 29, 33, 40, 45, 53, 31];
	for (i = 0; i < V.length; i++) {
		vertices[V[i]].bolddraw();
	} 
		
}

function levelFour() {
	textSize(10);
	strokeWeight(.4);
	fill('grey');
	text('Level Four', 30, 10);
	E = [[4, 18], [18, 45], [45, 21], [21, 4], [4, 23], [23, 53], [53, 26], 
	[26, 4], [4, 28], [4, 34], [28, 34], [18, 28], [26, 34], [18, 21], 
	[23, 26], [28, 21], [34, 23], [21, 23], [28, 34], [23, 45], [21, 53]];
	for (i = 0; i < E.length; i++) {
		E[i] = makeEdge(E[i][0], E[i][1]);
		if (mousehasentbeenclicked) {
			E[i].draw();
		}
	}
	V = [4, 18, 21, 23, 26, 28, 34, 45, 53];
	for (i = 0; i < V.length; i++) {
		vertices[V[i]].bolddraw();
	} 
}

function levelFive() {
	textSize(10);
	strokeWeight(.4);
	fill('grey');
	text('Level Five', 30, 10);
	E = [[25, 4], [19, 4], [25, 51], [51, 47], [47, 19], [4, 13], [19, 13], 
	[25, 13], [29, 13], [33, 13], [47, 13], [51, 13], [4, 29], [4, 33], 
	[19, 29], [25, 33], [29, 51], [33, 47], [29, 47], [33, 51], [25, 29], [19, 33]];
	for (i = 0; i < E.length; i++) {
		E[i] = makeEdge(E[i][0], E[i][1]);
		if (mousehasentbeenclicked) {
			E[i].draw();
		}
	}
	V = [4, 19, 25, 47, 51, 13, 33, 29];
	for (i = 0; i < V.length; i++) {
		vertices[V[i]].bolddraw();
	} 
}



function draw() {
	for (k = 0; k < vertices.length; k++) {
    	vertices[k].draw();
    }
    if (levelnumber == 1) {
    	levelOne();
    } else if (levelnumber == 2) {
    	levelTwo();
    } else if (levelnumber == 3) {
    	levelThree();
    } else if (levelnumber == 4) {
    	levelFour();
    } else if (levelnumber == 5) {
    	levelFive();
    }
}


function mousePressed() { 
	mousehasentbeenclicked = false;
	pressButton();
	colorVertices();
	testEdge();	

	var is5colored = true;
	for (i = 0; i < E.length; i ++) {
		if (E[i].iscolored == false || E[i].iscorrect == false) {
			is5colored = false;
		}
	}
	if (is5colored == true) {
		resetLevel();
		levelnumber++;
	}
	if (levelnumber == 6) {
		textSize(90);
		fill('lightpink');
		noStroke();
		text('YOU WIN', 40, height/2);
	}			
}

My final project is a simple game based on graph coloring. Click on any of the colored boxes to select a color and then click in the vertices to color them with that color. The goal is to color in the graph so that there is no edge between vertices of the same color. When you succeed it will automatically move on to the next level. There are a total of 5 levels and when you complete them all you win!

akluk-final-project

For my project I mainly based my project on whack a mole game combined with the pokemon that everyone loves, Diglet. The game lasts for 60 sec and during time the player would want to hit as many diglets as possible. Once the game ends the user can press r to restart the game. Hope you enjoy the game!

Screenshot of the game

sketch

//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Final Project

//initialize constants and variables
//number of rows of diglets in the canvas
var rows = 3;

//body height of the diglet
var diglet_h = 30;
//number of diglets in the game
var num_diglets = 11;
//array to contain the diglet objects
var diglets = [];
//temporary dummie variable to help push all the diglets 
var temp_diglet;
//number of diglets the player has hit in a single run of game/score
var num_hit;
//number of 0.5 sec passed elapsed
var time_elapsed = 0;
//duration of game 60sec
var game_time = 120;
//whether the game has ended
var ended = 0;
//hammer mode to determine if hammer is down or up
var mode; 
//start position for even rows
var startx1 = 60;
//start position for odd row
var startx2 = 120;
//spacing with each diglet
var spacing = 120;
//height spacing
var dy = 90;


function setup() {
    createCanvas(480, 360);
    //creates the diglets in the right positions
    // and pushes it into the array of diglets
    for (var i = 0; i < rows; i++) {
        //even rows
        if ((i % 2) == 0){
            for (var j = startx1; j < width; j += spacing){
                temp_diglet = new diglet(j,dy*(i+1));
                diglets.push(temp_diglet);
            }
        }
        //odd rows
        else {
            for (var j = startx2; j < width; j += spacing){
                temp_diglet = new diglet(j,dy*(i+1));
                diglets.push(temp_diglet);
            }
        }
    }
    //initialize score for player
    num_hit = 0;
    //update the diglets ever half second to determine if they pop up
    //and update timer every 0.5 sec
    setInterval(function(){
        for (var index = 0; index < num_diglets; index ++){
            diglets[index].update();
        }
        time_elapsed += 1;
    }, 500);
}

function draw() {
    background(40,180,40);
    noStroke();
    //change the display of the hammer 
    if (mouseIsPressed){
        mode = 1;
    }
    else {
        mode = 0;
    }

    //end the game when the timer has ended 
    if (time_elapsed >= game_time){
        ended = 1;
    }
    //if game has not ended, draw the holes for the diglets in the correct location
    if (ended == 0){
        for (var i = 0; i < rows; i++) {
            //odd rows
            if ((i % 2) == 0){
                for (var j = 60; j < width; j += 120){
                    drawHole(j,dy*(i+1));
                }
            }
            //even rows
            else {
                for (var j = 120; j < width; j += 120){
                    drawHole(j,dy*(i+1));
                }
            }
        }
        //draw every diglet in the array of diglets
        for (var index = 0; index < num_diglets; index ++){
            diglets[index].draw();
        }   
        //draw hammer in passive position     
        if (mode == 0) {
            fill(130,82,1);
            rect(mouseX-5,mouseY-25,10,50);
            fill(120);
            rect(mouseX-25,mouseY-35, 50,20);
        }
        //draw hammer in active position
        else {
            fill(130,82,1);
            rect(mouseX,mouseY-5,50,10);
            fill(120);
            rect(mouseX-10,mouseY-25, 20,50);
        }

        //display score and time left for the game
        fill(255);
        textSize(15);
        text("Score : " + num_hit, 400,340);
        text("Time Left : " + (game_time-time_elapsed)/2,5,340);
    }
    //game over screen
    else {
        fill(0);
        rect(0,0,width,height);
        fill(255);
        text("Game Over!", width/2 - width/10, height/2);
        text("Final Score : " + num_hit, width/2 - width/10,height/2 + height/15);
        text("Press R to restart", width/2 - width/10, height/2 + 2*height/15);
    }

}

//draw the hole sorry for much random numbers to make it look natural
function drawHole(x,y){
    fill(0);
    ellipse(x,y,80,40);
    fill(103,104,76);
    ellipse(x-40,y,22,12);
    ellipse(x+40,y,22,12);
    fill(90,77,65);
    ellipse(x-32,y+8,20,12);
    ellipse(x+28,y+8,24,14);
    fill(119,120,119);
    ellipse(x-22,y+13,20,12);
    ellipse(x+12,y+16,24,15);
    fill(100,100,100);
    ellipse(x-4,y+18,28,15);   
}


//object of diglet 
function diglet(x,y,duration){
    //base variables
    this.x = x;
    this.y = y;
    this.duration = duration;
    //draw the diglet, with eyes and body
    this.draw = function() {
        if (this.duration > 0) {
            //brown of diglet
            fill(181,147,119);
            rect(this.x-diglet_h/2,this.y-diglet_h,diglet_h,diglet_h);
            ellipse(this.x,this.y-diglet_h,diglet_h,diglet_h);
            
            fill(0);
            ellipse(this.x-diglet_h/6,this.y-diglet_h,3,6);
            ellipse(this.x+diglet_h/6,this.y-diglet_h,3,6);
            fill(255);
            ellipse(this.x-diglet_h/6,this.y-diglet_h-2,1,1);
            ellipse(this.x+diglet_h/6,this.y-diglet_h-2,1,1);
            //nose color
            fill(239,187,210);
            ellipse(this.x,this.y-diglet_h+6,diglet_h/3,5);
        }
    }
    //update whether the diglet appears
    this.update = function(){
        if (this.duration > 0){
            this.duration = this.duration - 0.5;
        }
        else {
            var temp_ratio = random(0,1);
            if (temp_ratio < 0.15){
                this.duration = random([1,2,3,4]);
            }
        }
    }
    //check if user clicked the diglet
    this.inDiglet = function(click_x,click_y){
        if (((click_x > this.x-diglet_h/2) & (click_x < this.x-diglet_h/2) && (click_y > this.y - diglet_h) && (click_y < this.y)) || (dist(click_x,click_y,this.x,this.y-diglet_h) < diglet_h)){
            if (this.duration > 0){
                this.duration = 0;
                num_hit += 1; 
            }   
        }
    }
}

//check  if when the mouse is pressed if it hits any diglet
function mousePressed() {
    for (var i = 0; i < num_diglets; i++){
        diglets[i].inDiglet(mouseX,mouseY);
    }
}

//when the game is over and you press r reset the game
function keyTyped(){
    if ((key === 'r') & (ended == 1)){
        ended = 0;
        time_elapsed = 0;
        ended = 0;
        num_hit = 0;
    }
}

jiaxinw-Final Project

Interactive Music Media Installation

This is a project using Kinect connecting with a website which was developed by P5.js.  Therefore, this project cannot be run on WordPress. We recorded the video for our project and hope it can be a good demonstration of the whole concept.

For this project, Nayeon and I worked together to create a new media installation in which people can interact with music by hitting virtual buttons to generate sounds and visual effects. People can follow the music from the background and have fun with moving their body to play music.

I learned a lot and a lot and a lot from this final project and I am so proud that it finally has been done. For this project, I was responsible for the Kinect part,  which included making sure the connection between Kinect and the website (or we can say the Javascript files) work well and also create User Interface (the virtual buttons, particle effects, and sound effects) for the website.  So, the biggest challenge for me at the beginning was figuring out how to connect Kinect and Javascript. I did a lot of research and finally decided to use the Node-Kinect2 library to achieve what I needed.

(Information about Node-Kinect library: https://github.com/wouterverweirder/kinect2)

I followed the instructions of the library, installed all the modules and packages that I needed (which took me a long time to figure out how to properly install the node.js and all kinds of modules. 😉 ). After it, I looked into the sample files carefully, analyzed the logic inside to figure out how I can access the data of Kinect skeleton. I figured out, for using this library to access data, I needed to set up a local server and point it to my local index, uploading my resources and files to the server through the node.js. At last, I need to use the command prompt to open the js file by using node.js. Whoo… to be honest, it was not easy to figure out the whole process clearly, but once I understood the logic behind it, the whole thing went more fluently.

The next step I did was designing how the interface looks like. After communication with Nayeon, we decided to create a project with a Neon art style.  I created a mood board for myself to figured out the feelings of the visual part.

my mood board

I also looked into a very inspiring and amazing project which is The V Motion Project and decided to do a circling interface for people to play with.

(For more information about V Motion Project: https://vimeo.com/45417241)

The presentation of V Motion Project

I created 6 virtual buttons on the canvas, and when people hit any of them, a particle effect will be generated along with a sound effect. By standing in front of the Kinect, people can move their hands to touch the buttons and create their own music and visual effects.

One more thing I have learned from this project is about how to access JS file outside Node.js through Node.js. The trick is you need to follow a very strict syntax to get your directory of the file and upload your resources to it.

you need to follow a special syntax to access your file

Anyway, it is so excited that I have finished this project with Nayeon! We definitely went through some difficulties and I guess this is why I feel very fulfilled when I finished creating everything! Here are some screenshots of the project!  Hope you Enjoy 🙂

Capture of final project
Capture of final project
Capture of final project

Finally here is the source code (a zip file) we created, please feel free to check it. I was responsible for the Kinect and interface (jiaxin.js) part.

Final project(Jiaxin_Nayeon)

Instruction for opening our project:

  1. Go to https://github.com/wouterverweirder/kinect2   download the Kinect node.js library.
  2. Follow the instruction to install node.js
  3. Connect your Kinect to your PC and make sure it works 🙂
  4. Extract the project zip file, and open your Command Prompt (for windows), go to the directory that you put our project folder. (use “cd + the directory “)
  5. And then use node.js to open the kinect.js file. (simply type “node kinect”)
  6. Open a browser and go to the local server : http://localhost:8000
  7. Stand in front of your Kinect, and have fun with our project!