dnam final project

Title Page to the Game

Game Download

sketch

var terrainSpeed = 0.0005; //set up terrain details for the water effects
var terrainDetail = 0.005;
var smallFishs; //group for food
var fish; //main character
var sharks; 
var horses;
var smallRock;
var bigRock;
var deadImg;
var plant;
var img;
var fishImage; //set up for loading image
var sound;
var nE = 0; //number of fish eaten
var play = false;
var dead = false;
//set up coordinates for certain aspects in order to change them throughout code
var imgX = 0; 
var imgY = 0;
var textX = 450;

function preload() {

//load up the images from assets
fishImage = loadImage("assets/fish.png");
img = loadImage("assets/titl.png");
deadImg = loadImage("assets/ded.png");
bigRock = loadImage("assets/bigrock.png");
smallRock = loadImage("assets/smallrock.png");
plant = loadImage("assets/plant.png");
sound = loadSound('assets/boop.wav');
}

function setup() {
createCanvas(1000 , 600);

fish = createSprite(width/2, height/2); //spawn goldfish in the middle
//set movement limits to goldfish
fish.maxSpeed = 6; 
fish.friction = .9;
fish.setCollider();
//add the actual image into sprite variable
fish.addImage("normal", fishImage);

//set up groups 
smallFishs = new Group();
sharks = new Group();
horses = new Group();
}

function draw() {
//set up background of the game
  background(80, 80, 220);
  fill(150, 150, 0);
  noStroke();
  rect(0, 570, 1000, 100);
  image(smallRock, 1000, 490)
  push();
  scale(2);
  image(plant, 90, 255);
  pop();
  image(bigRock, 600, 480);
  image(smallRock, -250, 450);
  
//set up conditions for starting screen
if (play == false){
  image(img, imgX, imgY);
  
} else {
  drawWaves();

  fish.overlap(smallFishs, eatFish); //set up overlap for goldfish and food fish
  sharks.overlap(fish, sharkEat);
  
  //set up rotation speed / movement speed for gold fish
  if(keyDown(LEFT_ARROW)) {
    fish.rotation -= 2;
  }
  if(keyDown(RIGHT_ARROW)) {
    fish.rotation += 2;
  }
  if(keyDown(UP_ARROW)) {
    fish.addSpeed(.45, fish.rotation);
  }
  
  //come over on the other side if fish goes too far left/right
  if (fish.position.x > 1000) {
    fish.position.x = 0;
  } else if (fish.position.x < 0) {
    fish.position.x = 1000;
  }
  
  //come over on the other side if fish goes too far top/bottom
  if (fish.position.y > 600) {
    fish.position.y = 0;
  } else if(fish.position.y < 0){
    fish.position.y = 600;
  }
  
  //constantly create small fish randomly around the canvas
  if(random(0, 100) < 10) {
  var pn = random(360);
  var px = (width/2 + 1000) * cos(radians(pn));
  var py = (height/2 + 1000) * sin(radians(pn));
  createSmallFish(3, px, py);
  }
  
  //create sharks randomly but rarely
  if(random(0, 100) < 1) {
  var bn = random(300);
  var bx = (width/2 + 1000) * cos(radians(bn));
  var by = (height/2 + 1000) * sin(radians(bn));
  createShark(3, bx, by);
  }

  //constantly spawn seahorses, but rarely
  if(frameCount%70==0 & horses.length < 20) {
    createHorses(random(0,width), random(0,height));
  }
  for(var i = 0; i < horses.length; i++) {
      var sea = horses[i]; //create variable for seahorses
      sea.scale = map(sea.life, 220, 0, 1, 0); //lives for limited frames, changes sizes according to time
      sea.displace(fish); //push away and block goldfish's path
}
  drawSprites();
  text("Fishy Points: " + nE, textX, 50); //text showing current game points 
  }
}

function createSmallFish(x, y) { //function that builds small fish
  var smol = createSprite(x, y);
  var smolfish  = loadImage("assets/smallfish.png");
  smol.addImage(smolfish);
  smol.setSpeed(1, random(360));
  smol.rotationSpeed = .1;
  smol.setCollider("rectangle", 0, 0, 0, 0);
  smallFishs.add(smol);
  return smol;
}

function createShark(x, y) { //function that builds sharks
  var big = createSprite(-x, y);
  var bigShark = loadImage("assets/shark.png");
  big.addImage(bigShark);
  big.setSpeed(.5, random(360));
  big.rotationSpeed = .05
  big.setCollider("rectangle", 0, 0, 100, 10);
  sharks.add(big);
  return big;
}

function createHorses(x, y) { //function that builds seahorses with an animation that shrinks size
  var sea = createSprite(x, y);
  sea.addAnimation("horses", "assets/seahor.png");
  sea.life = 220;
  sea.rotationSpeed = .08
  sea.setCollider("rectangle", 0, 0, 0, 0);
  horses.add(sea);
}

function eatFish(fish, smallFishs) { //function to remove the small fish when overlapping as well as
  //adding on to fish eaten counter
  sound.play();
  nE += 1;
  smallFishs.remove();
}

function sharkEat(sharks, fish) {
  dead = true;
  play = false;

  if (dead == true) {
    imgX += 1000;
    imgY += 1000;
    textX += 1000;
    image(deadImg, 0, 0);
    fill(186, 217, 180);
    textSize(52.72);
    text("" + nE, 550, 321);
    noLoop();
  }
}

function keyPressed(){
  if (keyCode === 88){
    play = true;
  }
}

function drawWaves(){
  
  //wave 1
  fill(144,175,197, 60);
  beginShape();
  for (var x = 0; x < width; x++) {
      var t = (x * 0.003) + (millis() * terrainSpeed * 2);
      var y = map(noise(t), 0,1, 0, height * 0.1);
      vertex(x, y+ 1);
  }
  vertex(width,height);
  vertex(0,height);
  endShape();

  //wave 2
  fill(51,107,135, 60);
  beginShape();
  for (var x = 0; x < width; x++) {
      var t = (x * 0.003) + (millis() * terrainSpeed * 2);
      var y = map(noise(t), 0,1, 0, height * 0.1);
      vertex(x, y+50);
  }
  vertex(width,height);
  vertex(0,height);
  endShape();

  //wave 3
  fill(144,175,197, 60);
  beginShape();
  for (var x = 0; x < width; x++) {
      var t = (x * 0.003) + (millis() * terrainSpeed * 2);
      var y = map(noise(t), 0,1, 0, height * 0.1);
      vertex(x, y+65);
      if(noise(t) > 0.2){
        fill(144, 175, 197, 80);
      }
      else {
        fill(144,175,197,120);
      }
  }
  vertex(width,height);
  vertex(0,height);
  endShape();

  //wave 4
  fill(51,107,135, 60);
  beginShape();
  for (var x = 0; x < width; x++) {
      var t = (x * 0.003) + (millis() * terrainSpeed * 2);
      var y = map(noise(t), 0,1, 0, height * 0.1);
      vertex(x, y+100);
  }
  vertex(width,height);
  vertex(0,height);
  endShape();
}

The game is played by using the left / right arrow keys to change the rotation of the fish, and using the up arrow to move forward. Try to get as many points as possible by eating the smaller fish, while avoiding the angry sharks that will end the game if they touch you. The searhorses will stop your movement, so try to move around them.

Basing off how old styled games were formed, I wanted to make a game that has an unlimited ‘reward’ while having a losing condition. Using knowledge earned from the class, I was able to display and create the game I wanted to.

jwchou-final project-E

For my project, I decided to stay with the theme I had developed throughout the semester with plane-based projects.

The objective of the game is to fly the plane onto the runway while avoiding mountains and lightning. Instructions for running the game are included.

I had a really hard time with this project. My original concept was perhaps more interesting but I had an extremely hard time executing it, so I pivoted my project to this secondary concept at the last minute. However, I had a lot of fun creating it, as well as working on the styling and themes of the splash screens in particular. I hope you enjoy it!

sketch 52

//Jackie Chou
//jwchou@andrew.cmu.edu
//Section E
//Final Project

//stores image variables
var explosion;
var lost;
var crash;
var win;
var beginScreen;
var lightning;
var mountain;
var img;

//variable to determine if the game has started
var gameStarted = false;

//position and speed variables for the plane
var xPos = 240;
var yPos = 0;
var xSpeed = 0;
var ySpeed = 0;

//arrays to store the obstacles in
var mountains = [];
var lightnings = [];


function setup() {
    createCanvas(480, 480);
    //load background and obstacle images
    img = loadImage("https://i.imgur.com/x3rvhGU.png");
    lightning = loadImage("https://i.imgur.com/v6p1ANv.png");
    mountain = loadImage("https://i.imgur.com/tLB1n6D.png");
    explosion = loadImage("https://i.imgur.com/8J62X6Z.png");

    //load splash screens
    lost = loadImage("https://i.imgur.com/znFRmOW.png");
    crash = loadImage("https://i.imgur.com/TXv7bto.png");
    win = loadImage("https://i.imgur.com/T0qvSdh.png");
    beginScreen = loadImage("https://i.imgur.com/J34UN7I.png");
    //pushes random coordinates into the obstacle arrays
    for (i = 0; i < 8; i++) {
        lightnings.push(random(0, width));
        lightnings.push(random(80, 350));
        mountains.push(random(0, width));
        mountains.push(random(80, 350))
    }   
}

function draw() {
    imageMode(CENTER);
    //draws background image
    image(img, 240, 240);
    //initializes plane if the game has begun
    if (gameStarted == true){
        ySpeed = 0.5;
    }
    //controls plane's direction
    yPos += ySpeed; 
    xPos += xSpeed;
    //calls function to draw obstacles
    drawObstacles();
    //displays splash screen before the game starts
    if (gameStarted == false) {
        image(beginScreen, width/2, height/2);
    }
    //drawing the airplane
    fill(240);
    strokeWeight(0.5);
    //wings
    ellipse(xPos, yPos, 70, 11); 
    ellipse(xPos, yPos - 20, 35, 8);
    //horz stabilizer
    fill(108, 190, 225);
    ellipse(xPos, yPos, 17, 45); 
    //fuselage
    ellipse(xPos + 17, yPos + 5, 6, 15); 
    //left engine
    ellipse(xPos - 17, yPos + 5, 6, 15); 
    //right engine
    fill(0);
    ellipse(xPos - 17, yPos + 10, 10, 2); 
    //right propeler
    ellipse(xPos + 17, yPos + 10, 10, 2); 
    //left propeller
    fill(240);
    ellipse(xPos, yPos - 25, 5, 17); 
    //tail
    fill(0);
    beginShape(); 
    //cockpit
    vertex(xPos - 5, yPos + 10);
    vertex(xPos, yPos + 17);
    vertex(xPos + 5, yPos + 10);
    vertex(xPos + 5, yPos + 5);
    vertex(xPos, yPos + 10);
    vertex(xPos - 5, yPos + 5);
    vertex(xPos - 5,yPos +  10);
    endShape(); 
    //checks to see if the plane has collided into lightning
    for (i = 0; i < lightnings.length; i += 2) {
        if (dist(xPos, yPos, lightnings[i], lightnings[i+1]) <= 35) {
            gameOver();
        }   
    }
    //checks to see if the plane has collided in mountains
    for (i = 0; i < mountains.length; i += 2) {
        if (dist(xPos + 3, yPos, mountains[i], mountains[i+1]) <= 38) {
            gameOver();
        }   
    }
    //calls landing function if plane crosses top edge of runway
    if (dist(xPos, yPos, 235, 440) <= 15) {
        xSpeed = 0;
        ySpeed = 0;
        landed();
    }
    //calls lost screen function if plane leaves canvas (x)
    if (xPos <= 10 || xPos >= 470) {
        gotLost();
    }
    //calls lost screen function if plane leaves canvas (y)
    if (yPos >= 470) {
        gotLost();
    }
}

//draws the obstacles using randomized values from the arrays
function drawObstacles() {
    for (i = 0; i < lightnings.length; i += 2) {
        image(lightning, lightnings[i], lightnings[i+1]);
        //image(mountain, random(0, width), random(80, 350));
    }
    for (i = 0; i < mountains.length; i += 2) {
        image(mountain, mountains[i], mountains[i+1]);
    }
}

//controls the direction of the plane via arrow keys
function keyPressed() {
    if (keyCode === RIGHT_ARROW) {
        xSpeed = 0.65;
    }
    if (keyCode === LEFT_ARROW) {
        xSpeed = -0.65;
    }
    if (keyCode === DOWN_ARROW) {
        xSpeed = 0;
    }
}

//starts the game
function mousePressed() {
    gameStarted = true;
}

//game over function, displays splash screen
function gameOver() {
    image(explosion, xPos, yPos - 3);
    image(crash, width/2, height/2);
    noLoop();
}

//plane lost function
function gotLost() {
    image(lost, width/2, height/2);
    noLoop();
}

//plane landed function
function landed() {
    image(win, width/2, height/2);
    noLoop();
}

mstropka Final Project E (FIXED)

sketch

//Name: Max Stropkay
//Andrew ID: mstropka@andrew.cmu.edu
//Section: E
//Final Project

//decalare variables for font, and audio file
var avenir;
var littlewing;

//array to store vehicle objects
var vehicles = [];

//diameter of circles
var diameter;

//store the value of the amplitude of the audio file
var amplitude;

//array to store the strings that make up the lyrics
//of the song
var lyrics = ['little wing', 'well','shes','walking','through',
  'the','clouds','with a', 'circus', 'mind', 'thats','running', 'round',
  'butterflies', 'zebras', 'moonbeams', 'fairytales',
  'thats all', 'she ever', 'thinks about', 'riding with', 'the', 'wind', 'when',
  'Im sad', 'she comes', 'to me', 'with a', 'thousand', 'smiles', 'she',
  'gives to', 'me', 'free','its alright', 'she said', 'its alright', 'take',
  'anything', 'you', 'want', 'from me', 'anything'];

//array to store the times at which the lyrics
//should appear on screen
var times = [34000, 500, 500, 3000, 500, 500, 2000, 200, 300, 3000, 500,
  500, 3000, 1500, 1500, 2000, 3000, 3000, 300, 300, 300, 2000, 4000,
  500, 500, 3000, 500, 500, 2000, 200, 300, 3000, 500,
  500, 3000, 1500, 1500, 2000, 3000, 3000, 300, 300, 2000, 300, 18000];

var word = -1;

//load soundfile and font
function preload() {
  littlewing = loadSound('https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/Jimi-Hendrix-Little-Wing.mp3')
  avenir = loadFont("https://s3.us-east-2.amazonaws.com/maxstropkayfinalproject/AvenirNextLTPro-Demi.otf");
}

function setup() {
  createCanvas(1200, 480);
  //play audio file,set volume
  littlewing.play();
  littlewing.setVolume(0.5);
  //set value of amplitude to the amplitude of audio
  amplitude = new p5.Amplitude(.04);
  updateLyrics();

}

function draw() {
  background(51);

  //for every vehicle run behaviors, update, and show
  for (var i = 0; i < vehicles.length; i++){
    var v = vehicles[i];
    v.behaviors();
    v.update();
    v.show();
  }

  //set diameter to be determined by the amplitude
  var level = amplitude.getLevel();
  var volume = map(level, 0, 1, 0, 200);
  diameter = volume;
}

//define Vehicle object
  function Vehicle(x, y) {
    this.pos = createVector(random(0, width), random(0, height));
    this.target = createVector(x, y);
    this.vel = p5.Vector.random2D();
    this.acc = createVector();
    this.r = 10;
    this.color = 255;
    this.maxspeed = 10;
    this.maxforce = 0.5;
  }

  Vehicle.prototype.behaviors = function(f) {
    var arrive = this.arrive(this.target);
    this.applyForce(arrive);
  }

  Vehicle.prototype.applyForce = function(f) {
    this.acc.add(f);
  }
  //move vehicles based on attraction to the
  //target location
  Vehicle.prototype.update = function() {
    this.pos.add(this.vel);
    this.vel.add(this.acc);
    this.acc.mult(0);
    this.r = diameter + 10*(random(0,1));
    this.color = color(diameter*random(0, 100), diameter*random(0, 5), diameter*random(0, 10));
  }
  //draw ellipses at x,y coordinates of objects
  Vehicle.prototype.show = function() {
    noStroke();
    fill(this.color);
    ellipse(this.pos.x, this.pos.y, this.r, this.r);
  }
  //change speed of object as it gets closer to
  //its target location
  Vehicle.prototype.arrive = function(target) {
    var desired = p5.Vector.sub(target, this.pos);
    var d = desired.mag();
    var speed = this.maxspeed;
    if (d < 100){
      var speed = map(d, 0, 100, 0, this.maxspeed);
    }
    desired.setMag(speed);
    var steer = p5.Vector.sub(desired, this.vel);
    steer.limit(this.maxforce);
    return steer;

  }
  //move object toward its desired position
  Vehicle.prototype.seek = function(target) {
    var desired = p5.Vector.sub(target, this.pos);
    desired.setMag(this.maxspeed);
    var steer = p5.Vector.sub(desired, this.vel);
    steer.limit(this.maxforce);
    return steer;

  }

//display the next word in the array lyrics
//at the time from the time array
function updateLyrics(){
  vehicles = [];
  word = (word + 1) /*% lyrics.length*/;
  print(word);
  textAlign(CENTER);
  textFont("Avenir")
  var points = avenir.textToPoints(lyrics[word], 70, 300, 192);
  //console.log(points)

  for (var i = 0; i < points.length; i++){
    var pt = points[i];
    var vehicle = new Vehicle(pt.x, pt.y);
    vehicles.push(vehicle);
    // stroke(0,255,0);
    // strokeWeight(4);
    // point(pt.x, pt.y);
}
print(times[word]);
setTimeout(updateLyrics,times[word]);

}

For my final project, I made a program that generates dots that change size and color based on the volume of the music thats being played in the background. The dots then fly to form the lyrics in the song. Syncing up the timing of the lyrics and the music was harder and more time consuming than I anticipated, so it only is synced for the first verse.

Attached is the zip file that contains the audio and the font that can be run on a local server.

mstropka_Final Project_E

To run, first open terminal and copy and paste in this line of code

python -m SimpleHTTPServer 8000

This will run a local server. Then type into the URL in your browser

localhost:8000

Then navigate to wherever you downloaded the file and click to run it.

 

 

ctv Final Project

You are able to type in the box, click it to expand, and move the text box up and down!

sketch

var CONTAINERS;
var img;
var img2;
var img3;

function preload(){
    img = loadImage("https://i.imgur.com/SiATbai.png");
    img2 = loadImage("https://i.imgur.com/g9q8qO8.png");
    img3 = loadImage("https://i.imgur.com/zFUnlLi.png");
}

function setup() {
    createCanvas(800, 800);
    CONTAINERS = new aContainer();
}

function draw(){
    background('#165fa8');
    CONTAINERS.display();
}

//////Design and functionality of the text container
function aContainer() {
//////Properties for the individual container
  var state = 0;
  var txt = "";
  this.pos = 0;
  this.h = 100;
  this.color = color('#e2f0fb');
  this.shadow = 1;
  this.r = 20;
  this.txtSize = 34;

//////Save Button Dimensions
      var buttonX = 80;
      var buttonY = 40;
      var buttonX2 = 200;
      var buttonX3 = 500;
      var buttonW = 100;
      var buttonH = 40;

//////Execute the shapes and text when this is called,
//////Calls properties in the section right above
  this.display = function() {
        if(this.pos <= 0){this.pos = 0}
        if(this.pos >= 5){this.pos = 5}
        fill(this.color);
        strokeWeight(0);
        rect(80, this.pos*100+120, 640, this.h, this.r);
        fill(60);
        textSize(this.txtSize);
        textFont("Avenir");
        text(txt, 110, this.pos*100+180);
        fill(240);
        rect(buttonX, buttonY, buttonW, buttonH, 20);
        image(img, buttonX+buttonW/2-17.5, buttonY+2.5, 35, 35);
        rect(buttonX2, buttonY, buttonW, buttonH, 20);
        image(img2, buttonX2+buttonW/2-17.5, buttonY+2.5, 35, 35);
        rect(buttonX3, buttonY, buttonW, buttonH, 20);
        image(img3, buttonX3+buttonW/2-17.5, buttonY+2.5, 35, 35);
  }

//////Function is called when mouse is pressed
//////Only executes if cursor is over the container
  this.pressed = function() {
      if (mouseX > 80 & 
          mouseX < 720 && 
          mouseY > this.pos*100+120 && 
          mouseY < this.pos*100+this.h+120) {
          if(state%2 == 0){
              this.h = 500;
              state++;
          } else if(state%2 == 1){
              this.h = 100;
              state++;      
          }
     }
  }
//////Add the typed key to the string variable 'txt'
  this.keys = function(){
//////If text goes beyond specified width, put text on new line
      txt = txt + key;
      txtWid = textWidth(txt)%500;
      if(txtWid>475){
          txt+= "\n"
      }
//////If the enter key is pressed, put text on new line
      if(keyCode == 13){
          txt += "\n";
      }
//////Ability to delete a letter that is typed
        if(keyCode == 8 & txt.length>0){
            txt = txt.substring(0, txt.length - 2);
        }
  }
///////Adds abbility to press save button
  this.downButton = function(){
      if (mouseX > buttonX & 
          mouseX < buttonX + buttonW && 
          mouseY > buttonY && 
          mouseY < buttonY + buttonH) {
            this.pos++;
     } else if (mouseX > buttonX2 & 
          mouseX < buttonX2 + buttonW && 
          mouseY > buttonY && 
          mouseY < buttonY + buttonH) {
            this.pos--;
     }
  }
//////Make the text box larger
    this.expand = function(){
        if(this.h == 100){
        }
    }
}

function mousePressed(){
    CONTAINERS.pressed();  
    CONTAINERS.downButton();
}

function keyPressed() {
    CONTAINERS.keys();
}

 

 

elizabew-final project

Click on either of the two choices that are available to continue through the story.

(Try the closet route!)

sketch

//calls beginning function to start the game over
var scene = new beginning();

//holds background images
var bg = [];

var bgURL = [
  //outside image
  "https://i.imgur.com/NhThk6g.jpg",
  //lake reflection image
  "https://i.imgur.com/GA10Vet.jpg",
  //image of both lake and forest
  "https://i.imgur.com/c6C6zEC.jpg",
  //cat image
  "https://i.imgur.com/4zrzVTj.jpg",
  //true ending image
  "https://i.imgur.com/LADTQJI.jpg"];

function setup() {
  createCanvas(480, 450);
}

function preload(){
  // load images from URL
  for (i = 0; i < bgURL.length; i++){
    bg.push(loadImage(bgURL[i]));
  }
}

//LIST OF SCENES
function beginning() {
  this.sentence = "You wake up surrounded by complete darkness." +
  " Your body aches and you hear the faint sound of growling behind you." +
  " You pull your red hood around yourself to keep warm." +
  " You feel around and find two doors." +
  " One with a round knob and one of with a square knob.";
  this.left = new sit1();
  this.right = new sitA();
  this.lefttext = "go through the round knobbed door";
  this.righttext = "go through the square knobbed door";
  this.fillcolor = "black";
}

//Round knobbed door
function sit1() {
  this.sentence = "You immediately begin to sprint out the door." +
  " The fresh air hits your face like cold knives. Outside." +
  " You look behind you to hear the growling rumble louder." +
  " She's waking up too.";
  this.left = new sit2();
  this.right = new death("You wait and see what happens." +
  " The beast begins to wake up and it immediately sees you" +
  " She's angry and you know exactly why." +
  " She leaps towards you in a familiar fashion," +
  " mouth wide open and ready to bite down...");
  this.lefttext = "RUN!!!!";
  this.righttext = "Wait and see what happens";
  this.fillcolor = "";
  this.b = "outside";
}

function sit2() {
  this.sentence = "You run away before the beast could notice you leaving." +
  " You see a forest and a lake in the distance";
  this.left = new sitOne();
  this.right = new sit3();
  this.lefttext = "Run towards the forest";
  this.righttext = "Run towards the lake";
  this.fillcolor = "";
  this.b = "treeAndLake"
}

function sit3() {
  this.sentence = "As you run towards the lake," +
  " you stop by the edge of the water," +
  " mesmorized by your own unrecognizable reflection...";
  this.left = new death("You can't help but continue staring at yourself." +
  " Bright blue eyes and a long red cape embracing your frail body." +
  " You hear growling beghind you... GIVE...IT...BACK.... ");
  this.right = new sitThree();
  this.lefttext = "Keep staring at your own reflection";
  this.righttext = "Pull your eyes away and continue running";
  this.fillcolor = "";
  this.b = "reflection"
}

function sitOne(){
  this.sentence = "Start running faster and faster through the forest," +
  " trees flashing past you." +
  " You hear the growling not too far behind...";
  this.left = new death("You climbed up the tree as fast as you could." +
  " Right as you grabbed a second branch," +
  " you feel your hood getting tugged, pulling you down with it...");
  this.right = new sitTwo();
  this.lefttext = "Climb up a tree";
  this.righttext = "Hide in the bushes";
  this.fillcolor = "flashing green";
}

function sitTwo(){
  this.sentence = "You jump into a nearby bush and wait..." +
  " the sound of a frustrated growling felt close," +
  " but it seems to have disappeared now.";
  this.left = new sitThree();
  this.right = new sit3();
  this.lefttext = "Keep running!";
  this.righttext = "Run back towards the lake";
  this.fillcolor = "";
  this.b = "outside";
}

function sitThree(){
  this.sentence = "You decide to keep running." +
  " As you run you trip over a soft rock." +
  " Wait, that's a cat!";
  this.left = new sitFour();
  this.right = new sitFour();
  this.lefttext = "Pet the cat";
  this.righttext = "Scratch the cat's belly";
  this.fillcolor = "";
  this.b = "cat";
}

function sitFour(){
  this.sentence = "The cat purrs and rolls around on the ground." +
  " After a few minutes it gets up.";
  this.left = new sitneutralending();
  this.right = new sitneutralending();
  this.lefttext = "Follow the cat";
  this.righttext = "Why wouldn't you follow this cat?";
  this.fillcolor = "";
  this.b = "cat";
}

//Neutral ending
function sitneutralending(){
  this.sentence = "(Neutral ending) You follow the cat into a small den." +
  " I guess this is a nicer ending."
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "";
  this.b = "outside";
}

//--------------------
//Square knobbed door
function sitA() {
  this.sentence = "You open the door and find yourself looking into a closet." +
  " You run in and shut the door as quietly as you can." +
  " She's awake now too.";
  this.left = new sitB();
  this.right = new death("You decided to scream on the top of your lungs." +
  " Immediately and without warning, the beast breaks through the closet" +
  " door. Did you have a death wish?");
  this.lefttext = "Stay quiet and hope she leaves";
  this.righttext = "SCREAM!!!";
  this.fillcolor = "black";
}

//Closet scene
function sitB() {
  this.sentence = "You decide to sit quietly in the closet." +
  " After what seemed like hours, the growling disappeared...";
  this.left = new sitC();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "Walk out";
  this.fillcolor = "black";
}

function sitC() {
  this.sentence = "You felt uneasy and decided to stay in the closet." +
  " You lean back onto the back of the closet and surprisingly," +
  " you fell into a hole that leads outside!";
  this.left = new sitD();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "Crawl outside";
  this.fillcolor = "black";
}

function sitD(){
  this.sentence = "You STILL decide to stay in the closet for some reason." +
  " Maybe you're still feeling uneasy..." +
  " Time continues to pass as it usually does."+
  " Are you even going to continue on this journey?";
  this.left = new sitE();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "CRAWL OUTSIDE";
  this.fillcolor = "black";
}

function sitE(){
  this.sentence = "You still stay in the closet. This is not like the narnia" +
  " wardrobe. There is nothing special about this closet." +
  " Why do you want to stay in here so badly?";
  this.left = new sitF();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "Crawl. Outside. Now.";
  this.fillcolor = "black";
}

function sitF(){
  this.sentence = "Okay, you've committed, we'll stay in this dumb closet."+
  " I even took away the 'crawl outside' button. I hope you're happy with yourself.";
  this.left = new sitG();
  this.right = new sitG();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitG(){
  this.sentence = "I bet you're happy about this endless loop,"+
  " Even if you change your mind you won't get it back, you're gonna have to" +
  " refresh this whole game manually.";
  this.left = new sitH();
  this.right = new sitH();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitH(){
  this.sentence = "...";
  this.left = new sitI();
  this.right = new sitI();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitI(){
  this.sentence = "..........";
  this.left = new sitJ();
  this.right = new sitJ();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitJ(){
  this.sentence = "..................";
  this.left = new sitK();
  this.right = new sitK();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitK(){
  this.sentence = "Okay, I'm just going to push you outside. Shoo!";
  this.left = new sit1A();
  this.right = new sit1A();
  this.lefttext = "OUTSIDE";
  this.righttext = "GO. OUTSIDE.";
  this.fillcolor = "black";
}

//To grandmothers house we go!
function sit1A(){
  this.sentence = "You walk outside to see the beast far off in the distance," +
  " obviously looking for you. But you have other plans...";
  this.left = new death("You dance(?) towards the beast flailing about,"+
  " probably hoping to get eaten. (I bet you were the same person wanting to" +
  " stay in that closet...)");
  this.right = new sit1B();
  this.lefttext = "Ignore your plans and dance towards the beast";
  this.righttext = "Head towards the smoke in the nearby forest";
  this.fillcolor = "";
  this.b = "outside";
}

function sit1B(){
  this.sentence = "You run through the forest, to grandmother's house." +
  " She'll protect you from the beast. You hear the beast" +
  " catching up to you, desperate to get what you've stolen back..." +
  " You notice that there is a large pit nearby";
  this.left = new sit1C();
  this.right = new goodishending();
  this.lefttext = "Continue running towards grandmother's house";
  this.righttext = "Wait to push the wolf into the pit";
  this.fillcolor = "flashing green";
}

function sit1C(){
  this.sentence = "You finally reach the door of the house" +
  " The beast is not far behing you. 'GRANDMOTHER' you scream, let me in!" +
  " Hurry!!";
  this.left = new trueending();
  this.right = new death("You decide to keep running, but the beast gets to you." +
  " And you were so close too!");
  this.lefttext = "Wait for grandmother to open the door";
  this.righttext = "Keep running!";
  this.fillcolor = "";
  this.b = "outside";
}

//True ending
function trueending(){
  this.sentence = "(True Ending) Soon after, the door opens." +
  " It's almost impossible to hide your grin..." +
  " You look back at the girl in wolfs skin that was chasing you," +
  " desperate to get her hood back." +
  " 'My, what big teeth you have, little riding hood'!";
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "";
  this.b = "trueEnd";
}

//Death scene when the beast gets you
function death(sentence) {
  this.sentence = sentence;
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "red";
}

//Good ending where you kill the beast
function goodishending(){
  this.sentence = "(Good Ending) You push the wolf into the pit. Hooray!" +
  " Now nothing is in your way...";
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "";
  this.b = "outside";
}

function draw() {

  //Determining background color
  if (scene.fillcolor == "red"){
    background(171,6,11);
  }
  else if (scene.fillcolor == "blue"){
    background(0, 6, 34);
  }
  else if (scene.fillcolor == "flashing green"){
    frameRate(8);
    var r = random(0, 8);
    var g = random(0, 60);
    var b = random(0, 5);
    background(r, g, b);
  }
  else if (scene.fillcolor == "green"){
    background(2, 26, 8);
  }
  else if (scene.fillcolor == "black"){
    background(0);
  }
  else {
    background(0);
  }

  //Creates background images
  if (scene.b == "outside"){
    image(bg[0], 0, 0, 480, 450);
  }
  if (scene.b == "reflection"){
    image(bg[1], 0, 0, 480, 450);
  }
  if (scene.b == "treeAndLake"){
    image(bg[2], 0, 0, 480, 450);
  }
  if (scene.b == "cat"){
    image(bg[3], 0, 0, 480, 450);
  }
  if (scene.b == "trueEnd"){
    image(bg[4], 0, 0, 480, 450);
  }


  //Story text details
  fill(200);
  textSize(12);
  text(scene.sentence, 50, 270, 380, 80);
  //left text decision
  text(scene.lefttext, 50, 380, 100);
  //right text decision
  text(scene.righttext, 300, 380, 100);

  //Reset button text
  if (scene.lefttext == "") {
    text("click here to start over", 180, 370);
  }


}

//Creating "buttons" for choices and for reset
function mouseClicked(){

  //Reset button
  if (scene.lefttext == "") {
    if (mouseX > 180 & mouseX < 300 && mouseY > 360 && mouseY < 380){
       //resets game
       scene = new beginning();
    }
  }

 else{
   //left button decision
   if (mouseX > 50 & mouseX < 130 && mouseY > 370 && mouseY < 420){
     scene = scene.left;
   }
   //right button decision
   if (mouseX > 300 & mouseX < 440 && mouseY > 370 && mouseY < 420){
     scene = scene.right;
   }
 }

}

I decided to create a choose-your-own-adventure game! My initial idea was to focus on having no visuals—using only text and sound to guide the user through the story—but ultimately ended up using both visuals and text together, and just text on its own.

The story was difficult to write in its own right and I don’t claim that it is that good, but the point of this game is that most of the endings the user runs into will build on the story of the game. I decided to focus mainly on using objects (since that was the most difficult part of this class for me and I wanted to make sure I ended this class with the knowledge of how to use them).

gyueunp – Final Project

Final Project

/*
* GyuEun Park
* 15-104 E
* gyueunp@andrew.cmu.edu
* Final Project
*/

var dots = []; //array of dots in beginning scene
var gravity;
var stars = []; //array of stars in ending scene
var speed;
var ismoving = true;

function setup() {
    createCanvas(600, 600);
    background(14, 94, 96);

    //turtle for the center of the transition scene 
    var turtle = makeTurtle(width - 115, height - 455);
    turtle.penDown();
    turtle.setColor(0);
    for (var i = 0; i < 1300; i++) {
        turtle.forward(10);
        turtle.right(141.5);
        turtle.forward(420);
        if (i % 20 === 0) {
            turtle.forward(70);
        }
    }
    if (ismoving){
        //dots jump up relatively high due to gravity
        gravity = createVector(0, 0.2);
        fill(16, 198, 216, 100);
        stroke(186, 198, 216, 200);
        strokeWeight(4);
    }
    else {
        //array of stars up to 2000
    for (var i = 0; i < 2000; i++) {
    stars[i] = new Star();
    }
  }
}

function draw() {
    if (ismoving) {
        //drawing jumping dots in the initial scene
        background(1, 11, 28, 50);
        if (random(1) < 0.2) {
            dots.push(new Dots());
        }
        //push through the array of dots, update and show them
        for (var i = 0; i < dots.length; i++) {
            dots[i].update();
            dots[i].show();
        }
    }
    else {
        background(1, 11, 28, 10);
        //the lower the cursor, the slower the star movement 
        speed = map(mouseY, 10, width / 2, 0, 5);
        //translate so that stars moving out from center, not top left 
        translate(width / 2, height / 2);
        for (var i = 0; i < stars.length; i++) {
            //update and show stars that are in motion
            stars[i].update();
            stars[i].show();
        }
    }
}


//dot constructor function
function Dots() {
    this.dots = new Particle(random(width), height);
    this.update = function() {
        this.dots.applyForce(gravity);
        this.dots.update();
    }
    this.show = function() {
        this.dots.show();
    }
}



//particle constructor function
function Particle(x,y) {
    this.pos = createVector(x,y);
    this.vel = createVector(0, random(-15, -5));
    this.acc = createVector(0, 0);

    this.applyForce = function(force){
        //add force to acceleration, force accumulation
        this.acc.add(force);
    }

    this.update = function() {
        //take the acceleration and adds it to the velocity
        this.vel.add(this.acc);
        //take the velocity and adds it to the position
        this.pos.add(this.vel);
        //multiply acc to 0 so that acc starts with 0 
        this.acc.mult(0);
    }

    this.show = function() {
        point(this.pos.x, this.pos.y);
    }
}

//star details in the transitioned scene
function Star() {
  this.x = random(-width, width);
  this.y = random(-height, height);
  this.z = random(width);
  this.pz = this.z;

  this.update = function() {
    this.z = this.z - speed;
    if (this.z < 1) {
      this.z = width;
      this.x = random(-width, width);
      this.y = random(-height, height);
      this.pz = this.z;
    }
  }

  this.show = function() {
    fill(16, 198, 216, random(200));
    noStroke();

    //the locations of the stars, dispersed across the canvas
    var sx = map(this.x / this.z, 0, 4, 0, width);
    var sy = map(this.y / this.z, 0, 3, 0, height);

    //when closer bigger, when farther smaller in size
    var r = map(this.z, 0, width, 16, 0);
    ellipse(sx, sy, r, r);

  }
}

function mousePressed(){
    ismoving = !(ismoving);
    setup();
}

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;}

Instructions: Click anywhere or move your cursor around to make alterations.

Brief summary: Jumping Dots, Turtle, and Turquoise Starfield.

For my final project, I took the advantage of making my canvas a space in which the viewers could momentarily be immersed in. As I believe that the  strength of interactive artworks is their ability to allow the audiences to create unexpected changes, I allowed the environment of my work to be altered by the viewers. Despite the changeable environment, however, I also focused on achieving a sense of visual consistency through the usage of coherent colorations and forms.

Conflicting factors coexist in my work; the space is chaotic yet orderly, inviting yet daunting, random yet systematic. Coexistences such as these were merged in creating this single work. I hope you enjoy momentarily being immersed in this space I created!

I also filmed projections of my work to experience its amplified effects outside of my screen.

and here are screenshots of various possible outcomes:

Here is a video of a slight alteration of the piece. I liked how it looked (and reminded me of Christmas and our imminent winter break!), so I decided to include it.

Final Project Thomas Wrabetz / Anna Boyle

sketch

//Anna Boyle and Thomas Wrabetz
//Main functions

//Thomas' code
function setup() {
    createCanvas(480, 480);
    rectMode( CENTER );
    player = makePlayer( width / 2, height / 2 );
    level = makeLevel();
    var sec=second();
}

function draw() {
    background(200);
    player.draw();
    player.step();
    level.draw();

//Anna's code
    fill(0);
    txt=width/2
    fill(255);
    noStroke();
    if (drawBubble==1){
//triangle for speech bubble
    triangle(width/2-20, txtH+20, bubbleX, bubbleY, width/2+20, txtH+20)
//if the player is on the top half, make the bubble on the bottom half
    if (player.y<height/2){
      txtH=440;
      rect(width/2, 470, width, bubbleHeight);
//adjust the line height when there is only one line
      singleLineHeight=465;
//if the player is on the bottom half, make the bubble on the top half
    }if (player.y>=height/2){
      txtH=30;
      rect(width/2, 20, width, bubbleHeight);
//adjust the line height when there is only one line
      singleLineHeight=30;
  }
    fill(0);
//makes the quote
    textSize(17);
    textAlign(CENTER);
    printQuote( whichQuote );
  }
    rectMode(CORNER);
//draws the inspiration meter red bar
    fill(188, 64, 64);
    rect(width-20, 0, 20, height);
//draws the inspiration meter's variable green bar
    fill(64, 188, 64);
    rect(width-20, height-inspiroMeter, 20, height);
    rectMode(CENTER);
//if the player gets enough quotes, they will win and see this screen
    if (inspiroMeter>480){
      fill(255);
      rect(width/2, height/2, width, height)
      fill(0);
      textSize(32)
      text("CONGRATULATIONS!", width/2, height/2-25);
      text("YOU ARE INSPIRED", width/2, height/2+25);
      noLoop();
    }
}

//Thomas Wrabetz
//Section C
//twrabetz@andrew.cmu.edu
//Player object

//-----PLAYER OBJECT-----//

var PSIZE = 30;
var PCOLOR = [ 25, 150, 25, 255 ];
var PSPEED = 3;
var keyArray = [];

//Updates the player's position based on keyboard input
function stepPlayer()
{
    //Variables to track the player's movement in each direction
    var yStep = 0;
    var xStep = 0;
    if( keyIsPressed )
    {
        for( var i = 0; i < keyArray.length; i++ )
        {
            switch( keyArray[i] )
            {
                case 'W':
                    yStep -= PSPEED;
                    break;
                case 'S':
                    yStep += PSPEED;
                    break;
                case 'A':
                    xStep -= PSPEED;
                    break;
                case 'D':
                    xStep += PSPEED;
                    break;
            }
        }
        //Adjust speed for diagonal movement
        if( xStep != 0 & yStep != 0 )
        {
            xStep *= 0.7071
            yStep *= 0.7071
        }
        //Check if the player will collide with a wall in the x-direction
        //and move the player if not
        if( !level.collisionSearch( this.x + xStep, this.y, PSIZE ) )
        {
            //If the player is too close to the edges of the screen,
            //move the level instead of the player
            if( ( this.x < width * 4/5 || xStep < 0 ) 
                && ( this.x > width * 1/5 || xStep > 0 ) ) this.x += xStep;
            else level.xOffset -= xStep;
        }
        //Check if the player will collide with a wall in the y-direction
        //and move the player if not
        if( !level.collisionSearch( this.x, this.y + yStep, PSIZE ) )
        {
            //If the player is too close to the edges of the screen,
            //move the level instead of the player
            if( ( this.y < height * 4/5 || yStep < 0 ) 
                & ( this.y > height * 1/5 || yStep > 0 ) ) this.y += yStep;
            else level.yOffset -= yStep;
        }
        //If the player collides with a figure, update the bubble
        var figure = level.figureCollisionSearch( this.x + xStep, 
                                                  this.y + yStep, PSIZE );
        if( figure != -1 )
        {
            if( !drawBubble )
            {
                drawBubble = true;
                //Only update to a new quote if this is a different figure
                if( bubbleID != level.figures[ figure ].ID )
                {
                    bubbleID = level.figures[ figure ].ID;
                    updateBubble();
                }
            }
            bubbleX = level.figures[ figure ].x + level.xOffset;
            bubbleY = level.figures[ figure ].y + level.yOffset;
        }
        else if( drawBubble )
            drawBubble = false;
        level.step();
    }
}

//Draw the player
function drawPlayer()
{
    fill( PCOLOR );
    rect( this.x, this.y, PSIZE, PSIZE );
}

function makePlayer( px, py )
{
    player = { x: px, y: py, draw: drawPlayer, step: stepPlayer };
    return player;
}

//-----KEY TRACKING-----//

//Each key pressed is stored in the key array
function keyPressed()
{
    keyArray.push( key );
}

//Keys are removed from the key array when released
function keyReleased()
{
    for( var i = 0; i < keyArray.length; i++ )
    {
        if( keyArray[i] == key ) keyArray.splice( i, 1 );
    }
}

//Thomas Wrabetz
//Section C
//twrabetz@andrew.cmu.edu
//Walls and level and figures

//-----INSPIRATIONAL FIGURE OBJECT-----//

figureColorArray = [ "Red", "Blue", "Green", "Yellow",
                     "Purple", "Orange", "Brown" ];
//Counter to give the figures unique IDs
figureIDCounter = 0;
//Counter that keeps track of how many open spaces have been created
figureCounter = 0;
//Each time figureCounter reaches FIGUREFREQ, a new figure is created
FIGUREFREQ = 10;
//Size of a figure
FIGUREWIDTH = 30;

function makeFigure( xPos, yPos )
{
    figure = { x: xPos, y: yPos, figureColor: random(figureColorArray),
               ID: figureIDCounter };
    figureIDCounter++;
    return figure;
}


//-----WALL OBJECT-----//

//Size of a wall
var WALLWIDTH = 80;
var WALLCOLOR = [ 116, 18, 229, 255 ];
var WALLCOLORDARK = [ 39, 7, 76, 255 ];

function makeWall( wx, wy )
{
    var wall = { x: wx, y: wy, pattern: makePattern() };
    return wall;
}

//-----LEVEL OBJECT-----//

//Add a row to the level. The parameters indicate which side
function levelAddRow( xRef, yRef )
{
    //Variables to track whether the new row is an empty row
    //and whether it has intersected an existing corridor
    var before = false;
    var after = false;
    var passed = false;
    var justPassed = false;
    //Left Side
    if( xRef == 1 ) 
    {
        //Clear out old row on opposite side
        this.walls.unshift( [] );
        this.walls.splice( this.walls.length - 1, 1 );
        //Decide whether the new row is empty or a turning corridor
        if( random() < 0.17 ) before = true;
        else if( random() < 0.204 ) after = true;
        else if( random() < 0.2572 )
        {
            before = true;
            after = true;
        }
        //There can't be two empty rows next to each other
        for( var i = 0; i < this.walls[1].length-2; i++ )
        {
            if( this.walls[1][i] == 0 & this.walls[1][i+1] == 0 )
            {
                before = false;
                after = false;
            }
        }
        //Generate the row
        for( var i = 0; i < this.walls[1].length; i++ )
        {
            //Check if the row intersects a corridor
            if( this.walls[1][i] == 0 )
            {
                passed = true;
                justPassed = true;
            }
            //Generate a wall unless this row is empty or blocking a corridor
            if( ( this.walls[1][i] == 0 & i != 0 && this.walls[1][i-1] != 0 &&
                  i != this.walls[1].length - 1 && this.walls[1][i+1] != 0 ) ||
                ( before && ( !passed || justPassed ) ) || ( after && passed ))
            {
                this.walls[0][i] = 0;
                if( figureCounter == FIGUREFREQ - 1 ) 
                    this.figures.push( makeFigure( -1 * WALLWIDTH,
                                       (i - 1) * WALLWIDTH ) );
                figureCounter = (figureCounter + 1) % FIGUREFREQ;
            }
            else this.walls[0][i] = makeWall( -1 * WALLWIDTH, 
                                              (i - 1) * WALLWIDTH );
            justPassed = false;
        }
    }
    //Right Side
    if( xRef == -1 ) 
    {
        //Clear out old row on opposite side
        this.walls.push( [] );
        this.walls.shift( 1 );
        //Decide whether the new row is empty or a turning corridor
        if( random() < 0.17 ) before = true;
        else if( random() < 0.204 ) after = true;
        else if( random() < 0.2572 )
        {
            before = true;
            after = true;
        }
        //There can't be two empty rows next to each other
        for( var i = 0; i < this.walls[1].length-2; i++ )
        {
            if( this.walls[this.walls.length-2][i] == 0 
                & this.walls[this.walls.length-2][i+1] == 0 )
            {
                before = false;
                after = false;
            }
        }
        //Generate the row
        for( var i = 0; i < this.walls[this.walls.length-2].length; i++ )
        {
            //Check if the row intersects a corridor
            if( this.walls[this.walls.length-2][i] == 0 )
            {
                passed = true;
                justPassed = true;
            }
            //Generate a wall unless this row is empty or blocking a corridor
            if( ( this.walls[this.walls.length-2][i] == 0 & i != 0 &&
                this.walls[this.walls.length-2][i-1] != 0 && 
                i != this.walls[this.walls.length-2].length - 1 &&
                this.walls[this.walls.length-2][i+1] != 0 ) ||
                ( before && (!passed || justPassed) ) || ( after && passed ) )
            {
                this.walls[this.walls.length-1][i] = 0;
                if( figureCounter == FIGUREFREQ - 1 ) 
                    this.figures.push( makeFigure( (this.walls.length-2) 
                                                   * WALLWIDTH, 
                                                   (i-1) * WALLWIDTH ) );
                figureCounter = (figureCounter + 1) % FIGUREFREQ;
            }
            else this.walls[this.walls.length-1][i] = 
                 makeWall( (this.walls.length-2) 
                           * WALLWIDTH, (i-1) * WALLWIDTH );
            justPassed = false;
        }
    }
    //Top
    if( yRef == 1 )
    {
        //Clear out old row on opposite side
        for( i = 0; i < this.walls.length; i++ )
        {
            this.walls[i].unshift( -1 );
            this.walls[i].splice( this.walls[i].length - 1, 1 );
        }
        //Decide whether the new row is empty or a turning corridor
        if( random() < 0.17 ) before = true;
        else if( random() < 0.204 ) after = true;
        else if( random() < 0.2572 )
        {
            before = true;
            after = true;
        }
        //There can't be two empty rows next to each other
        for( var i = 0; i < this.walls.length-2; i++ )
        {
            if( this.walls[i][1] == 0 & this.walls[i+1][1] == 0 )
            {
                before = false;
                after = false;
            }
        }
        //Generate the row
        for( var i = 0; i < this.walls.length; i++ )
        {
            //Check if the row intersects a corridor
            if( this.walls[i][1] == 0 )
            {
                passed = true;
                justPassed = true;
            }
            //Generate a wall unless this row is empty or blocking a corridor
            if( ( this.walls[i][1] == 0 & i != 0 && this.walls[i-1][1] != 0 
                  && i != this.walls.length - 1 
                  && this.walls[i+1][1] != 0 ) 
                  || (before && (!passed || justPassed)) || (after && passed))
            {
                this.walls[i][0] = 0;
                if( figureCounter == FIGUREFREQ - 1 ) 
                    this.figures.push( makeFigure( (i-1) * WALLWIDTH,
                                       -1 * WALLWIDTH ) );
                figureCounter = (figureCounter + 1) % FIGUREFREQ;
            }
            else 
                this.walls[i][0] = makeWall((i-1) * WALLWIDTH, -1 * WALLWIDTH);
            justPassed = false;
        }
    }
    //Bottom
    if( yRef == -1 )
    {
        //Clear out old row on opposite side
        for( i = 0; i < this.walls.length; i++ )
        {
            this.walls[i].push( -1 );
            this.walls[i].shift( 1 );
        }
        //Decide whether the new row is empty or a turning corridor
        if( random() < 0.17 ) before = true;
        else if( random() < 0.204 ) after = true;
        else if( random() < 0.2572 )
        {
            before = true;
            after = true;
        }
        //There can't be two empty rows next to each other
        for( var i = 0; i < this.walls.length-2; i++ )
        {
            if( this.walls[i][this.walls.length-2] == 0 
                & this.walls[i+1][this.walls.length-2] == 0 )
            {
                before = false;
                after = false;
            }
        }
        //Generate the row
        for( var i = 0; i < this.walls.length; i++ )
        {
            //Check if the row intersects a corridor
            if( this.walls[i][this.walls[0].length-2] == 0 )
            {
                passed = true;
                justPassed = true;
            }
            //Generate a wall unless this row is empty or blocking a corridor
            if( ( this.walls[i][this.walls[0].length-2] == 0 & i != 0 
                  && this.walls[i-1][this.walls[0].length-2] != 0 
                  && i != this.walls.length - 1 
                  && this.walls[i+1][this.walls[0].length-2] != 0 ) 
                  || (before && (!passed || justPassed)) || (after && passed)) 
            {
                this.walls[i][this.walls[0].length-1] = 0;
                if( figureCounter == FIGUREFREQ - 1 ) 
                    this.figures.push( makeFigure( (i-1) * WALLWIDTH,
                                      (this.walls[0].length-2) * WALLWIDTH ) );
                figureCounter = (figureCounter + 1) % FIGUREFREQ;
            }
            else 
                this.walls[i][this.walls[0].length-1] = 
                makeWall( (i-1) * WALLWIDTH,
                          (this.walls[0].length-2) * WALLWIDTH );
            justPassed = false;
        }
    }
}

//Update the level, moving objects inside and adding new rows if needed
function levelStep()
{
    //If the offset for the walls is greater than the width of a wall,
    //Shift the array of walls and add a new row
    if( abs( this.xOffset ) >= WALLWIDTH )
    {
        //Incorporate offset into walls' basic x-positions
        for( var j = 0; j < this.walls.length; j++ )
        {
            for( var k = 0; k < this.walls[j].length; k++ )
            {
                if( this.xOffset > 0 )
                {
                    this.walls[j][k].x += WALLWIDTH;
                }
                if( this.xOffset < 0 )
                {
                    this.walls[j][k].x -= WALLWIDTH;
                }
            }
        }
        //Incorporate offset into figures' basic x-positions
        for( var j = 0; j < this.figures.length; j++ )
        {
            if( this.xOffset > 0 )
            {
                this.figures[j].x += WALLWIDTH;
            }
            if( this.xOffset < 0 )
            {
                this.figures[j].x -= WALLWIDTH;
            }
            //Remove figures that are off the screen
            if( this.figures[j].x > width + FIGUREWIDTH / 2 
                || this.figures[j].x < 0 - FIGUREWIDTH / 2 )
            {
                this.figures.splice( j, 1 );
                j--;
            }
        }
        //Reset the offset and add a new row
        if( this.xOffset > 0 )
        {
            this.xOffset -= WALLWIDTH;
            this.addRow( 1, 0 );
        }
        if( this.xOffset < 0 )
        {
            this.xOffset += WALLWIDTH;
            this.addRow( -1, 0 );
        }
    }
    if( abs( this.yOffset ) >= WALLWIDTH )
    {
        //Incorporate offset into walls' basic y-positions
        for( var j = 0; j < this.walls.length; j++ )
        {
            for( var k = 0; k < this.walls[j].length; k++ )
            {
                if( this.yOffset > 0 )
                {
                    this.walls[j][k].y += WALLWIDTH;
                }
                if( this.yOffset < 0 )
                {
                    this.walls[j][k].y -= WALLWIDTH;
                }
            }
        }
        //Incorporate offset into figures' basic y-positions
        for( var j = 0; j < this.figures.length; j++ )
        {
            if( this.yOffset > 0 )
            {
                this.figures[j].y += WALLWIDTH;
            }
            if( this.yOffset < 0 )
            {
                this.figures[j].y -= WALLWIDTH;
            }
            //Remove figures that are off the screen
            if( this.figures[j].y > height + FIGUREWIDTH / 2 
                || this.figures[j].y < 0 - FIGUREWIDTH / 2 )
            {
                this.figures.splice( j, 1 );
                j--;
            }
        }
        //Reset the offset and add a new row
        if( this.yOffset > 0 )
        {
            this.yOffset -= WALLWIDTH;
            this.addRow( 0, 1 );
        }
        if( this.yOffset < 0 )
        {
            this.yOffset += WALLWIDTH;
            this.addRow( 0, -1 );
        }
    }
}

//Checks if a square at x,y with size size would collide with the wall
//at index a,b of the array of walls
function levelWallCollision( x, y, size, a, b )
{
    var wall = this.walls[a][b];
    if( wall == 0 ) return false;
    return abs( x - ( wall.x + this.xOffset ) ) < size / 2 + WALLWIDTH / 2 
           & abs( y - ( wall.y + this.yOffset ) ) < size / 2 + WALLWIDTH / 2;
}

//Check collision for all the walls
function levelCollisionSearch( x, y, size )
{
    for( i = 0; i < this.walls.length; i++ )
    {
        for( j = 0; j < this.walls[i].length; j++ )
        {
            if( this.wallCollision( x, y, size, i, j ) ) return true;
        }
    }
    return false;
}

//Draw the wall at index a,b of the wall array
function levelDrawWall( a, b )
{
    var wall = this.walls[a][b];
    if( wall == 0 ) return;
    push();
    stroke( WALLCOLORDARK );
    fill( WALLCOLOR );
    rect( wall.x + this.xOffset, wall.y + this.yOffset, WALLWIDTH, WALLWIDTH );
    wall.pattern.draw( wall.x + this.xOffset, wall.y + this.yOffset );
    pop();
}

//Checks if a square at x,y with size size would collide with a figure
//at index a of the figure array
function levelFigureCollision( x, y, size, a )
{
    if( a >= this.figures.length ) return false;
    var figure = this.figures[a];
    return abs( x - ( figure.x + this.xOffset ) ) < size / 2 + FIGUREWIDTH / 2
                & abs( y - ( figure.y + this.yOffset ) ) 
                   < size / 2 + FIGUREWIDTH / 2;
}

//Check collision for all the figures. If found, returns the index of
//the colliding figure in the figure array. If not, returns -1.
function levelFigureCollisionSearch( x, y, size )
{
    for( i = 0; i < this.figures.length; i++ )
    {
        if( this.figureCollision( x, y, size, i ) ) return i;
    }
    return -1;
}

//Draw the figure at index a of the figure array
function levelDrawFigure( a )
{
    var figure = this.figures[a];
    if( figure == 0 ) return;
    push();
    stroke( 0 );
    fill( figure.figureColor );
    ellipse( figure.x + this.xOffset, figure.y + this.yOffset,
             FIGUREWIDTH, FIGUREWIDTH );
    pop();
}

//Draw all the walls and figures
function levelDraw()
{
    for( i = 0; i < this.walls.length; i++ )
    {
        for( j = 0; j < this.walls[i].length; j++ )
        {
            this.drawWall( i, j );
        }
    }
    for( i = 0; i < this.figures.length; i++ )
    {
        this.drawFigure( i );
    }
}

//Make a level, which contains arrays of walls and figures as well as a shared
//x and y offet which applies to every object in the level
function makeLevel()
{
    var wallsArray = [];
    var figuresArray = [];
    for( i = 0; (i - 1) * WALLWIDTH <= width + WALLWIDTH; i++ )
    {
        wallsArray.push( [] );
        for( j = 0; (j - 1) * WALLWIDTH <= height + WALLWIDTH; j++ )
        {
            if( i == 4 || j == 4 ) wallsArray[i].push( 0 );
            else 
                wallsArray[i].push( makeWall( (i - 1) * WALLWIDTH,
                                    (j - 1) * WALLWIDTH ) );
        }
    }
    level = { walls: wallsArray, figures: figuresArray, xOffset: 0, yOffset: 0,
              draw: levelDraw, drawWall: levelDrawWall,
              wallCollision: levelWallCollision,
              collisionSearch: levelCollisionSearch,
              step: levelStep, addRow: levelAddRow,
              drawFigure: levelDrawFigure, 
              figureCollision: levelFigureCollision,
              figureCollisionSearch: levelFigureCollisionSearch };
    return level;
}

//Thomas Wrabetz
//Section C
//twrabetz@andrew.cmu.edu
//Pattern object for wall blocks

var DOTSIZE = 3;
var colors = [ [66,134,234,255], [23,216,213,255],
               [23,216,236,255], [68,216,23,255], [228,242,42,255] ];

function makePattern() {
    var angle;
    var newPattern={c: random(colors), arms: int( random( 4 ) ) + 2, 
                    a: random(2*PI), draw: drawPattern, dotPositionArray: [] };
    for( var i = 0; i < newPattern.arms; i++ )
    {
        for( var j = 0; j < WALLWIDTH / 2 - 5; j+= DOTSIZE * 2 )
        {
            angle = newPattern.a + i * (2 * PI / newPattern.arms);
            newPattern.dotPositionArray.push( j * cos( angle ) + 
                     ( sin( j ) * 20 * cos( angle + PI / 2 ) ) );
            newPattern.dotPositionArray.push( j * sin( angle ) + 
                     ( sin( j ) * 20 * sin( angle + PI / 2 ) ) );
        }
    }
    return newPattern;
}

function drawPattern( x, y ){
    fill(this.c)
    push();
    noStroke();
    var currentX;
    var currentY;
    for( var i = 0; i < this.dotPositionArray.length - 1; i+= 2 )
    {
            ellipse( x + this.dotPositionArray[i], y + this.dotPositionArray[i+1],
                     DOTSIZE, DOTSIZE );
    }
    pop();
}

//Anna Boyle
//Section D
//aboyle@andrew.cmu.edu
//Quote generator

var abstractNouns = ["Rebellion", "Curiosity", "Jealousy", "Friendship",
"Family", "Evil", "Life", "Hope", "Grace", "Love", "Faith", "Opportunity",
"Dedication", "Insanity", "Fortune", "Luck", "Hatred", "Knowledge", "Pain",
 "Heaven"];
var inspireNouns = ["rainbow", "cloud", "light", "star", "candle", "child",
"dream", "building", "hero", "breeze", "eye", "moon", "snowflake", "apple",
"tree", "flower", "butterfly", "mirror", "door", "heart"];
var inspireNounsPlural = ["rainbows", "clouds", "lights", "stars", "candles",
"children", "kisses", "buildings", "hands", "brothers", "sisters", 
"snowflakes", "dreams", "apples", "trees", "flowers", "butterflies", "mirrors",
"doors", "hearts"];
var strangeNouns=["peach cobbler", "deodorant", "used tissue", "conch shell",
"toaster", "pasta strainer", "blade of grass", "grandma's house", "unicycle",
"weed whacker", "shampoo bottle", "corpse", "snickerdoodle",
"ten gallon hat", "toupee", "colony of termites", "mother-in-law",
"sexy firemen calendar", "underground bunker", "angry baboon"];
var strangeNounsPlural = ["alien invasions", "clowns", "podiatrists",
"belly dancers", "cacti", "voodoo dolls", "raspberries", "dust bunnies",
"distant relatives", "kentucky fried chicken", "rotten eggs", "nudists",
"nunchuks", "toenail clippings", "rocket scientists", "green beans", "nuns",
"croissants", "drunk ballerinas", "shoelaces" ];
var inspireVerbs= ["flies", "moves", "shines", "waits", "stands", "goes",
"sleeps", "thinks", "cries", "laughs", "yells", "watches", "jumps"];
var inspireVerbsObj = ["hold", "hug", "love", "hate", "grab", "accept",
"support", "look at", "want", "sacrifice", "kiss", "pray for", "abandon"];
var inspireVerbsGerund= ["flying", "moving", "doing", "waiting", "standing",
"going", "saying", "thinking", "crying", "laughing", "yelling", "watching",
"jumping"];
var inspireVerbsObjGerund = ["holding", "hugging", "loving", "hating",
"grabbing", "accepting", "supporting", "seeing", "wanting", "finding",
"kissing", "praying for", "abandoning"];
var strangeVerbs=["dances", "dies", "melts", "yodels", "sneezes", "does yoga",
"crawls", "beatboxes", "undresses", "vomits", "whistles", "rollerblades",
"explodes"];
var strangeVerbsObj=["stab", "fight", "smack", "bury", "kick", "exorcise",
"kidnap", "high five", "sniff", "smuggle", "tickle", "cuddle", "nibble"];
var strangeVerbsGerund=["dancing", "dying", "melting", "yodeling", "sneezing",
"doing yoga","crawling", "sleeping", "undressing", "vomiting", "whistling",
"rollerblading", "exploding"];
var strangeVerbsObjGerund=["stabbing", "fighting", "smacking", "burying",
"kicking", "exorcising", "kidnapping", "high fiving", "sniffing", "smuggling",
"tickling", "cuddling", "nibbling"];
var locationWords=["behind", "in front of", "next to", "inside of", "below",
"on top of", "above", "under", "among", "beside", "over", "far away from",
"underneath"];
var comparison=["darker", "sadder", "bigger", "smaller", "harder", "softer",
"better", "worse", "faster", "slower", "stronger", "weaker", "happier", 
"drunker", "older", "younger", "smarter", "dumber", "hotter", "colder"];
var personQuote=["Albert Einstein", "Mahatma Gandhi", "Oprah Winfrey",
"George Washington", "Nelson Mandela", "Jesus Christ", "Benjamin Franklin",
"Plato", "Mother Teresa", "My mom", "Beyonce", "Martin Luther King Jr.",
"Santa Claus"]

//variable for the quote templates
var whichQuote;

/*nCh=nineteen choices, tCh=twelve choices
There are multiple variables to prevent parts of speech with same amount of
choices don't get constantly paired with each other */

var nCh1;
var nCh2;
var nCh3;
var nCh4;
var tCh1;
var tCh2;
var tCh3;
var tCh4;

//Variables related to drawing the speech bubble
var txt;
var txtH;
var bubbleHeight;
var singleLineHeight;
var bubbleX = 0;
var bubbleY = 0;
var drawBubble = false;
var bubbleID = -1;
var inspiroMeter=0;

function updateBubble(){
//randomizes which number in the array will be chosen for the parts of speech
    nCh1=int(random(20));
    nCh2=int(random(20));
    nCh3=int(random(20));
    nCh4=int(random(20));
    tCh1=int(random(13));
    tCh2=int(random(13));
    tCh3=int(random(13));
    tCh4=int(random(13));
//randomzies which quote template will be chosen
    whichQuote=int(random(14));
    inspiroMeter=inspiroMeter+20;

}

//Chooses which quote template will be chosen based on the random number
//between 0 and 13

function printQuote( num )
{

    switch(num)
  {
      case 0:
      worthTwo();
      break;
    case 1:
      tryToBe();
      break;
    case 2:
      whenYouHave();
      break;
    case 3:
      judgeEach();
      break;
    case 4:
      ifYouMiss();
      break;
    case 5:
      theBest();
      break;
    case 6:
      duringOurMoments();
      break;
    case 7:
      letUs();
      break;
    case 8:
      palesInComparison();
      break;
    case 9:
      haveSeen();
      break;
    case 10:
      inSeason();
      break;
    case 11:
      combination();
      break;
    case 12:
      onlyICan();
      break;
    case 13:
      jokeQuote();
     break;
  }
}

//Below are all the quote template functions
//bubbleHeight changes the size of bubble when there are different amounts of text

function tryToBe(){
    text("Try to be a "+inspireNouns[nCh1]+" in someone's "
    +strangeNouns[nCh2], txt, singleLineHeight);
    bubbleHeight=75;
}

function worthTwo(){
    text("One "+inspireNouns[nCh1]+" is worth two "+
    strangeNounsPlural[nCh2], txt, singleLineHeight);
    bubbleHeight=75;
}

function whenYouHave(){
    text("When you have a "+strangeNouns[nCh1]+", you've got to ", txt, txtH);
    text(inspireVerbsObj[tCh1]+" it and never "+strangeVerbsObj[tCh2]+
    " it", txt, txtH+25);
    bubbleHeight=130;
}

function judgeEach(){
    text("Don't judge each day by the "+inspireNounsPlural[nCh1],
    txt, txtH);
    text(" you "+inspireVerbsObj[tCh1]+", but by the "+strangeNounsPlural[nCh1]
    +" you "+strangeVerbsObj[tCh1], txt, txtH+25);
    bubbleHeight=130;
}

function ifYouMiss(){
    text("Shoot for the "+inspireNouns[nCh1]+", and if you miss", txt, txtH);
    text(" you will still be "+locationWords[tCh1]+" the "
    +strangeNounsPlural[nCh2], txt, txtH+25);
    bubbleHeight=130;
}

function theBest(){
    text("The best preparation for tomorrow is", txt, txtH);
    text(strangeVerbsObjGerund[tCh1]+" your "+
    strangeNouns[nCh1]+" today", txt, txtH+25);
    bubbleHeight=130;
}

function duringOurMoments(){
    text("It is during our "+comparison[nCh1]+" moments that we must", txt, txtH);
    text("focus to "+strangeVerbsObj[tCh1]+" the "+
    strangeNounsPlural[nCh2], txt, txtH+25);
    bubbleHeight=130;
}

function letUs(){
    text("Let us sacrifice our "+inspireNounsPlural[nCh1]
    +" so that", txt, txtH);
    text("our children can "+strangeVerbsObj[tCh1]+" a "+
    comparison[nCh2]+" "+strangeNouns[nCh3], txt, txtH+25);
    bubbleHeight=130;
}

function palesInComparison(){
    text("What "+inspireVerbs[tCh1]+" behind you and what "+
    inspireVerbs[tCh2]+" in front of you,", txt, txtH);
    text("pales in comparison to what "+strangeVerbs[tCh3]+" "+
    locationWords[tCh4]+" you", txt, txtH+25)
    bubbleHeight=130;
}

function haveSeen(){
    text("If I have seen further than others, it is", txt, txtH);
    text("by "+strangeVerbsGerund[tCh1]+" "+locationWords[tCh2]+" "
    +strangeNounsPlural[nCh1], txt, txtH+25)
    bubbleHeight=130;
}

function inSeason(){
    text(abstractNouns[nCh1]+" is a fruit in season at all times,", txt, txtH);
    text("and within reach of every "+strangeNouns[nCh2], txt, txtH+25);
    bubbleHeight=130;

}
function combination(){
    text(abstractNouns[nCh1]+" and "+strangeNounsPlural[nCh2]+
    " are a powerful combination", txt, singleLineHeight);
    bubbleHeight=75;
}


function onlyICan(){
    text("Only you can "+strangeVerbsObj[tCh1]+" your "+strangeNouns[nCh1]+".",
    txt, txtH);
    text("No one else can do it for you.", txt, txtH+25);
    bubbleHeight=130;
}

function jokeQuote(){
    text("This project definitely deserves an A", txt, txtH);
    text("-- "+personQuote[tCh1], txt+15, txtH+25);
    bubbleHeight=130;
}

For our final project, we made an Inspirational Quote Maze. The player moves a small square around in a randomly generated maze using the WASD keys. The dots in the maze tell the player inspirational quotes when they collide. For every quote the character receives, they gain a couple points in their “InspiroMeter.” Once they hear enough quotes, the game is over and they are congratulated for being inspired.
            Thomas mainly worked in the wall, player, and patterns files. He made the player movements and randomly generated the maze and the dots found within. He made it so the player can’t receive a different quote from the same dot twice in a row. He also created patterns to make the blocks look more exciting. 
            Anna mainly worked in the main and quotes files. She decided on the quote templates, made arrays filled with parts of speech, and randomized both of them for unique quotes. She made the speech bubble that appears when a character is talking. She also made the “InspiroMeter” and made the game end after a certain number of quotes. 
            Overall, we think that our project turned out well and we are proud of our efforts!

rfarn and ziningy1- final project

Audio embedded, please turn up volume. Vimeo recording also included at bottom.

In our final project, we made a music video and explored the relationship between geometric motion and rhythm. We divided the video into four sections of movements, interacting with the rhythm and mood of the music.

Motion section 1: Morphing blob

Motion section 2: Droplets

Motion section 3: Interacting Balls

 

Motion section 4: Splitting /Pulsing Balls

sketch

//stores music
var song;

//intro blob variables
var dx1;
var dy1;
var v0x;
var v0y;
var v1x;
var v1y;
var v2x;
var v2y;
var v3x;
var v3y;
var v4x;
var v4y;
var v5x;
var v5y;
var vcolor = 100;
var vopac = 255; 

//circle droplet variables
var diam1 = 30;
var diam2 = 30;
var diam3 = 30;
var diam4 = 30;
var opac = 200;
var drate = 6;

//interacting balls variables
var IBdiam = 30;
var IBxpos1 = 20;
var IBypos1 = 20;
var IBxpos2 = 20;
var IBypos2 = 20;
var IBxpos3 = 20;
var IBypos3 = 20;
var IBxpos4 = 20;
var IBypos4 = 20;
var IBxpos5 = 20;
var IBypos5 = 20;
var triangleOpac = 255;

//red bars variables
var bwidth1 =  15; 
var bheight = 15;
var bwidth2 = 15;
var barOpac = 255;
var bspeed = 4;
var rectx1 = 200;
var rectx2 = 230;

//splitting balls variables
var SBypos = -15;
var SBxpos1 = 300;
var SBxpos2 = 300;
var ball3y = 200;
var ball4y = 200; 


function preload() {
    song = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/music.mp3");
    song.setVolume(0.5);
}

function setup() {
    createCanvas(600, 400);
    frameRate(10);
    song.play();

    //set values to intro blob vertexes
    v0x = width/2 - 70;
    v0y = height/2;
    v1x = width/2;
    v1y = height/2 - 70;
    v2x = width/2 + 70 ;
    v2y = height/2 ;
    v3x = width/2;
    v3y = height/2 + 70;
    v4x = width/2 - 70;
    v4y = height/2;
    v5x = width/2;
    v5y = height/2 - 70;
    v6x = width/2 + 70;
    v6y = height/2;
}

function draw() {
        angleMode(DEGREES);
        background(150);
        noStroke();

        fill(vcolor);
        vcolor += 2;
        drawintroDrop(); //larger intro blob
        fill(130, 130, 130, vopac);
        push();
        scale(0.4);
        translate(2 * width/3 + 20, 2 * height/3);
        drawintroDrop(); //smaller intro blob
        pop();
        vopac -= 10;
    
        drawDroplets();
        drawInteractballs();
        pulsingBalls();
}

function interactingBalls(op, xpos, ypos) { //make interacting ball
    fill(132, 190, 160, op);
    ellipse(xpos, ypos, 30, 30);     
}

function makeDrop(r, g, b, x, y, diam) { //make droplet
    fill(r,g,b,opac);
    ellipse(x, y, diam, diam);
}

function drawintroDrop(){ //intro blob 
    angleMode(DEGREES);
    beginShape();
    curveVertex(v0x, v0y);
    v0x -= 2;
    v0y += 4;
    curveVertex(v1x, v1y);
    v1x -= 2;
    v1y += 6;
    curveVertex(v2x, v2y);
    v2x -= 8;
    v2y -= 4;
    curveVertex(v3x,v3y);
    v3x += 2;
    v3y -= 4;
    curveVertex(v4x,v4y);
    v4x += 8;
    v4y += 4;
    curveVertex(v5x, v5y);
    v5x -= 2;
    v5y += 6;
    curveVertex(v6x, v6y);
    v6x -= 2; 
    v6y += 4;
    endShape();
} 

function drawDroplets(){ //circle droplets
    if(frameCount > 52){ //first droplet
        makeDrop(108,163,140,width/4, height/4, diam1);
        diam1 += drate;
        opac -= 3;
    }

    if(frameCount > 62){ //second droplet
        makeDrop(108,123,140,width/2, height/2 + 60, diam2);
        diam2 += drate;
    }

    if(frameCount > 73){ //third droplet
        makeDrop(178,160,140,width - 100, height - 100, diam3);
        diam3 += drate;
    }

    if(frameCount > 88){ //fourth droplet
        makeDrop(200,163,140,width - 140, height - 270, diam4);
        diam4 += drate;
    }

    if(frameCount > 120 & frameCount % 3 == 0 ){ //flashing background
        fill(252, 252, 240);
        rect(0, 0, width, height);
    }
}

function drawInteractballs(){ //interacting balls
    if(frameCount > 120 & frameCount < 172 ){ //red triangle
        fill(210, 65, 65, triangleOpac);
        triangle(30, 45, 30, 135, 165,135);
    }

    //balls movement
    if(frameCount > 120){ //ball one
        interactingBalls(250, IBxpos1, IBypos1);
        IBxpos1 += 6;
        IBypos1 += 4;
        if(IBxpos1 > 165 + IBdiam/3){
            IBxpos1 -= 3;
            IBypos1 += 10;
        } 
        if(IBypos1 > 350 - IBdiam/2 || frameCount > 161){
            IBxpos1 -= 1;
            IBypos1 -= 20;
        }
        if(frameCount > 185){
            IBypos1 += 12;
        }
        if(frameCount > 211){
            IBypos1 -= 12;
        }
        if(frameCount > 237){
            IBypos1 += 18;
        }
    }

    if(frameCount>126.5){ //ball two
        interactingBalls(180, IBxpos2, IBypos2);
        IBxpos2 += 6;
        IBypos2 += 4;
        if(IBxpos2 > 165 + IBdiam/3){
            IBxpos2 -= 3;
            IBypos2 += 10;
        }
        if(IBypos2 > 350 - IBdiam/2 || frameCount > 167.5){
            IBxpos2 -= 1;
            IBypos2 -= 20;        
        }
        if(frameCount > 191.5){
            IBypos2 += 12;
        }
        if(frameCount > 217.5){
            IBypos2 -= 12;
        }
        if(frameCount > 244.5){
            IBypos2 += 18;
        }
    }

    if(frameCount > 133){ //ball three
        interactingBalls(130, IBxpos3, IBypos3);
        IBxpos3 += 6;
        IBypos3 += 4;
        if(IBxpos3 > 165 + IBdiam/3){
            IBxpos3 -= 3;
            IBypos3 += 10;
            triangleOpac -= 17; //triangle opacity decreases when third ball falls
        }
        if(IBypos3 > 350 - IBdiam/2 || frameCount > 174){
            IBxpos3 -= 1;
            IBypos3 -= 20;
        }
        if(frameCount > 198){
            IBypos3 += 12;
        }
        if(frameCount > 224){
            IBypos3 -= 12;
        }
        if(frameCount > 251){
            IBypos3 += 18;
        }
    }

    if(frameCount>139.5){ //ball four
        interactingBalls(80, IBxpos4, IBypos4);
        IBxpos4 += 6;
        IBypos4 += 4;
        if(IBxpos4 > 165 + IBdiam/3){
            IBxpos4 -= 3;
            IBypos4 += 10;
        }
        if(IBypos4 > 350 - IBdiam/2 || frameCount > 180.5){
            IBxpos4 -= 1;
            IBypos4 -= 20;
        }
        if(frameCount > 204.5){
            IBypos4 += 12;
        }
        if(frameCount > 230.5){
            IBypos4 -= 12;
        }
        if(frameCount > 257.5){
            IBypos4 += 18;
        }
    }

    if(frameCount>146.5){ //ball five
        interactingBalls(40, IBxpos5, IBypos5);
        IBxpos5 += 6;
        IBypos5 += 4;
        if(IBxpos5 > 165 + IBdiam/3){
            IBxpos5 -= 3;
            IBypos5 += 10;
        }
        if(IBypos5 > 350 - IBdiam/2 || frameCount > 186.5){
            IBxpos5 -= 1;
            IBypos5 -= 20;
        }
        if(frameCount > 211){
            IBypos5 += 12;
        }
        if(frameCount > 237){
            IBypos5 -= 12;
            barOpac -= 7; //red bars opacity decreases on fifth balls second to last bounce
        }
        if(frameCount > 264){
            IBypos5 += 18;
        }
    }

    //red bars
    if(frameCount > 159){ //bottom bar
        fill(210, 65, 65, barOpac);
        rect(rectx1,345,bwidth1,bheight);
        bwidth1+= bspeed;
    }

    if(frameCount > 175){ //top bar
        fill(210, 65, 65, barOpac);
        rect(rectx2,155,bwidth2,bheight);
        bwidth2 += bspeed;
    }

    if(bwidth1 > 350  || frameCount > 212){ //bars moving right
        rectx1 += 7;
        rectx2 += 2;
    }
}

function pulsingBalls(){ //splitting and pulsing balls
    //constraining variables
    var SBy1 = constrain(SBypos, -IBdiam/2, height/2);
    var SBx1 = constrain(SBxpos1, width/3 - 25, width);
    var SBx2 = constrain(SBxpos2, 0, width * (2/3) + 25);
    
    if(frameCount > 287){ //first circle moving
        fill(132, 190, 160);
        SBypos += 10;
        ellipse(SBx1, SBy1, IBdiam, IBdiam);
        ellipse(SBx2, SBy1, IBdiam, IBdiam);
        if(SBy1 > 160 & SBy1 < 200){ //diam increases
            IBdiam += 5;
        }
        if(SBy1 == 200){ //split to two circles
            SBxpos1 -= 5;
            SBxpos2 += 5;
            if(frameCount>330){ //split to six circles
                var SBy2 = constrain(ball3y, height/4, height/2);
                var SBy3 = constrain(ball4y, height/2, height * (3/4));
                ellipse(SBx1, SBy2, IBdiam, IBdiam); 
                ellipse(SBx1, SBy3, IBdiam, IBdiam);
                ellipse(SBx2, SBy2, IBdiam, IBdiam); 
                ellipse(SBx2, SBy3, IBdiam, IBdiam);
                ball3y -= 10; 
                ball4y += 10;
                if(SBy2 > 130 & SBy2 < 170){ //diam increases
                    IBdiam += 3; 
                }
            }
        }
    }

    //pulsing balls 
    if(frameCount > 350 & frameCount % 2 == 0){
        IBdiam += 16;
    }

    if(frameCount > 360 & frameCount % 3 == 0){
        IBdiam -= 20;
    }
}

 

 

aerubin-Final Project

KEY – NOTE NAME

A STRING:
1 – A
2 – B
3 – C#
4 – D
5 – E

D STRING:
Q – D
W – E
E – F#
R – G
T – A

G STRING:
A – G
S – A
D – B
F – C
G – D

C STRING:
Z – C
X – D
C – E
V – F
B – G

My final project is a playable viola that creates art in the background based on the notes played and length of the notes played. I drew the viola utilizing arcs, triangles, lines, and other 2D shapes. Then I added sounds to the notes played and ellipses that move with the music.

Each note is connected to a key, that when pressed, plays a note and a visual representation of the sound as a green dot showing the placement of the note on the fingerboard. In addition, there are 20 uniquely colored balls hiding behind the viola that are connected to 20 notes that can be played with the keyboard. Each ball will move at its individual vertical and horizontal velocities when the key is pressed. When the key is lifted, the sound will stop and ball will stop in place. When the performer is finished playing, it will leave a pattern of balls in the background. With the end of each unique composition, the background will look unique, linking each unique piece of music with a unique piece of art.

Functioning Code Showing Moving Ellipses

Note: WordPress does not display the audio correctly, so here is a zip file with the audio files and functioning code. In order to run this code, you access it in the terminal and type “python -m SimpleHTTPServer” and the code will run properly. Above is a screenshot of the completely functioning code.

aerubin_Final_Project

Make sure to turn the volume up!

Angela Rubin – Final Project

//Angela Rubin
//Section C
//aerubin@andrew.cmu.edu
//Final Project

//Initial Placement of Balls in Background
var x = 300;
var y = 175;
//Speed of Balls in both x and y directions
var dx = -1;
var dy = 2;

var x1 = 300;
var y1 = 175;
var dx1 = 2;
var dy1 = 1;

var x2 = 300;
var y2 = 175;
var dx2 = -1;
var dy2 = 1;

var x3 = 300;
var y3 = 175;
var dx3 = 2;
var dy3 = -2;

var x4 = 300;
var y4 = 175;
var dx4 = 2;
var dy4 = 3;

var x5 = 300;
var y5 = 175;
var dx5 = -3;
var dy5 = 2;

var x6 = 300;
var y6 = 175;
var dx6 = 3;
var dy6 = -3;

var x7 = 300;
var y7 = 175;
var dx7 = -3;
var dy7 = 4;

var x8 = 300;
var y8 = 175;
var dx8 = 4;
var dy8 = 3;

var x9 = 300;
var y9 = 175;
var dx9 = -4;
var dy9 = 4;

var x10 = 300;
var y10 = 175;
var dx10 = -1;
var dy10 = -2;

var x11 = 300;
var y11 = 175;
var dx11 = -2;
var dy11 = -1;

var x12 = 300;
var y12 = 175;
var dx12 = -2;
var dy12 = -2;

var x13 = 300;
var y13 = 175;
var dx13 = -2;
var dy13 = -3;

var x14 = 300;
var y14 = 175;
var dx14 = -3;
var dy14 = -2;

var x15 = 300;
var y15 = 175;
var dx15 = -3;
var dy15 = -4;

var x16 = 300;
var y16 = 175;
var dx16 = -4;
var dy16 = -3;

var x17 = 300;
var y17 = 175;
var dx17 = -1;
var dy17 = 2;

var x18 = 300;
var y18 = 175;
var dx18 = -2;
var dy18 = 3;

var x19 = 300;
var y19 = 175;
var dx19 = 3;
var dy19 = -2;

//Sound Names
var EonAString;
var DonAString;
var ConAString;
var BonAString;
var AonString;
var AonString2;
var GonDString;
var FonDString;
var EonDString;
var DonString;
var DonString2;
var ConGString;
var BonGString;
var AonGString;
var GonString;
var GonString2;
var FonCString;
var EonCString;
var DonCString;
var ConString;

//Background Pattern Variables
var diameter = 15; // diameter of the circles
var horizSpace = diameter; // horizontal spacing of the circles
var verSpace; // vertical spacing of the circles

function setup() {
    createCanvas(450, 350);
    verSpace = horizSpace * sqrt(0.75);   
}


function preload() {
    //Preloads each sound for each note
    EonAString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/E-A_String.m4a");
    DonAString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/D-A_String.m4a");
    ConAString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/C-A_String.m4a");
    BonAString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/B-A_String.m4a");
    AonString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/A-String.m4a");
    AonString2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/A-String2.m4a");
    GonDString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/G-D_String.m4a");
    FonDString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/F-D_String.m4a");
    EonDString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/E-D_String.m4a");
    DonString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/D-String.m4a");
    DonString2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/D-String2.m4a");
    ConGString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/C-G_String.m4a");
    BonGString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/B-G_String.m4a");
    AonGString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/A-G_String.m4a");
    GonString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/G-String.m4a");
    GonString2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/G-String2.m4a");
    FonCString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/F-C_String.m4a");
    EonCString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/E-C_String.m4a");
    DonCString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/D-C_String.m4a");
    ConString = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/C-String.m4a");
}

function draw() {
    background(255);

    noStroke();
    for(var i = 0; i < 30; i++) {
        if (i%2==1) {var c = -1;}
        if (i%2==0) {c = 0;}
        for(var n = 0; n < 35+c; n++) {
            fill(i*10, n*10, 255-(i*4));
            ellipse(horizSpace*n+(-7.5*c), verSpace*i, diameter, diameter);
        }
    }

    //Drawing the Balls in Background
    fill(248, 179, 147);
    ellipse(x, y, 50, 50);

    fill(239, 117, 129);
    ellipse(x1, y1, 50, 50);

    fill(191, 109, 135);
    ellipse(x2, y2, 50, 50);

    fill(109, 93, 128);
    ellipse(x3, y3, 50, 50);

    fill(53, 94, 128);
    ellipse(x4, y4, 50, 50);

    fill(156, 196, 176);
    ellipse(x5, y5, 50, 50);

    fill(176, 221, 202);
    ellipse(x6, y6, 50, 50);

    fill(218, 237, 197);
    ellipse(x7, y7, 50, 50);

    fill(246, 166, 168);
    ellipse(x8, y8, 50, 50);

    fill(150, 89, 91);
    ellipse(x9, y9, 50, 50);

    fill(163, 128, 129);
    ellipse(x10, y10, 50, 50);

    fill(170, 210, 189);
    ellipse(x11, y11, 50, 50);

    fill(218, 255, 253);
    ellipse(x12, y12, 50, 50);

    fill(208, 163, 171);
    ellipse(x13, y13, 50, 50);

    fill(247, 193, 172);
    ellipse(x14, y14, 50, 50);

    fill(72, 158, 151);
    ellipse(x15, y15, 50, 50);

    fill(235, 180, 166);
    ellipse(x16, y16, 50, 50);

    fill(211, 200, 215);
    ellipse(x17, y17, 50, 50);

    fill(250, 162, 134);
    ellipse(x18, y18, 50, 50);

    fill(179, 179, 163);
    ellipse(x19, y19, 50, 50);

    //Viola Function to Draw Viola
    makeViola();

    //Color of Dots on Fingerboard
    fill(0, 255, 0);
    noStroke();

    //B Natural, A String, KEY = 2
    if (keyIsDown(50)) {
        BonAString.play();
        ellipse(86, (height/2)-6.7, 4, 4);
        y+=dy;
        x+=dx;
        if(y>height-25 || y<25) {
            dy=-dy;
        }
        if(x>width-25 || x<25) {
            dx=-dx;
        }
    }
    else {BonAString.stop();}

    //C#, A String, KEY = 3
    if (keyIsDown(51)) {
        ConAString.play();
        ellipse(105, (height/2)-7, 4, 4);
        y1+=dy1;
        x1+=dx1;
        if(y1>height-25 || y1<25) {
            dy1=-dy1;
        }
        if(x1>width-25 || x1<25) {
            dx1=-dx1;
        }
    }
    else {ConAString.stop();}

    //D Natural, A String, KEY = 4
    if (keyIsDown(52)) {
        DonAString.play();
        ellipse(114, (height/2)-7.3, 4, 4);
        y2+=dy2;
        x2+=dx2;
        if(y2>height-25 || y2<25) {
            dy2=-dy2;
        }
        if(x2>width-25 || x2<25) {
            dx2=-dx2;
        }
    }
    else {DonAString.stop();}

    //E Natural, A String, KEY = 5
    if (keyIsDown(53)) {
        EonAString.play();
        ellipse(130, (height/2)-7.8, 4, 4);
        y3+=dy3;
        x3+=dx3;
        if(y3>height-25 || y3<25) {
            dy3=-dy3;
        }
        if(x3>width-25 || x3<25) {
            dx3=-dx3;
        }
    }
    else {EonAString.stop();}

    //E Natural, D String, KEY = W
    if (keyIsDown(87)) {
        EonDString.play();
        ellipse(86, (height/2)-2.2, 4, 4);
        y4+=dy4;
        x4+=dx4;
        if(y4>height-25 || y4<25) {
            dy4=-dy4;
        }
        if(x4>width-25 || x4<25) {
            dx4=-dx4;
        }
    }
    else {EonDString.stop();}

    //F#, D String, KEY = E
    if (keyIsDown(69)) {
        FonDString.play();
        ellipse(105, (height/2)-2.3, 4, 4);
        y5+=dy5;
        x5+=dx5;
        if(y5>height-25 || y5<25) {
            dy5=-dy5;
        }
        if(x5>width-25 || x5<25) {
            dx5=-dx5;
        }
    }
    else {FonDString.stop();}

    //G Natural, D String, KEY = R
    if (keyIsDown(82)) {
        GonDString.play();
        ellipse(114, (height/2)-2.5, 4, 4);
        y6+=dy6;
        x6+=dx6;
        if(y6>height-25 || y6<25) {
            dy6=-dy6;
        }
        if(x6>width-25 || x6<25) {
            dx6=-dx6;
        }
    }
    else {GonDString.stop();}

    //A Natural, D String, KEY = T
    if (keyIsDown(84)) {
        AonString.play();
        ellipse(130, (height/2)-2.9, 4, 4);
        y7+=dy7;
        x7+=dx7;
        if(y7>height-25 || y7<25) {
            dy7=-dy7;
        }
        if(x7>width-25 || x7<25) {
            dx7=-dx7;
        }
    }
    else {AonString.stop();}

    //A Natural, A String, KEY = 1
    if (keyIsDown(49)) {
        AonString2.play();
        y16+=dy16;
        x16+=dx16;
        if(y16>height-25 || y16<25) {
            dy16=-dy16;
        }
        if(x16>width-25 || x16<25) {
            dx16=-dx16;
        }
    }
    else {AonString2.stop();}


    //A Natural, G String, KEY = S
    if (keyIsDown(83)) {
        AonGString.play();
        ellipse(86, (height/2)+2.2, 4, 4);
        y8+=dy8;
        x8+=dx8;
        if(y8>height-25 || y8<25) {
            dy8=-dy8;
        }
        if(x8>width-25 || x8<25) {
            dx8=-dx8;
        }
    }
    else {AonGString.stop();}


    //B Natural, G String, KEY = D
    if (keyIsDown(68)) {
        BonGString.play();
        ellipse(105, (height/2)+2.3, 4, 4);
        y9+=dy9;
        x9+=dx9;
        if(y9>height-25 || y9<25) {
            dy9=-dy9;
        }
        if(x9>width-25 || x9<25) {
            dx9=-dx9;
        }
    }
    else {BonGString.stop();}

    //C Natural, G String, KEY = F
    if (keyIsDown(70)) {
        ConGString.play();
        ellipse(114, (height/2)+2.5, 4, 4);
        y10+=dy10;
        x10+=dx10;
        if(y10>height-25 || y10<25) {
            dy10=-dy10;
        }
        if(x10>width-25 || x10<25) {
            dx10=-dx10;
        }
    }
    else {ConGString.stop();}

    //D Natural, G String, KEY = G
    if (keyIsDown(71)) {
        DonString.play();
        ellipse(130, (height/2)+2.9, 4, 4);
        y11+=dy11;
        x11+=dx11;
        if(y11>height-25 || y11<25) {
            dy11=-dy11;
        }
        if(x11>width-25 || x11<25) {
            dx11=-dx11;
        }
    }
    else {DonString.stop();}

    //D Natural, D String, KEY = Q
    if (keyIsDown(81)) {
        DonString2.play();
        y17+=dy17;
        x17+=dx17;
        if(y17>height-25 || y17<25) {
            dy17=-dy17;
        }
        if(x17>width-25 || x17<25) {
            dx17=-dx17;
        }
    }
    else {DonString2.stop();}

    //D Natural, C String, KEY = X
    if (keyIsDown(88)) {
        DonCString.play();
        ellipse(86, (height/2)+6.3, 4, 4);
        y12+=dy12;
        x12+=dx12;
        if(y12>height-25 || y12<25) {
            dy12=-dy12;
        }
        if(x12>width-25 || x12<25) {
            dx12=-dx12;
        }
    }
    else {DonCString.stop();}

    //E Natural, C String, KEY = C
    if (keyIsDown(67)) {
        EonCString.play();
        ellipse(105, (height/2)+6.7, 4, 4);
        y13+=dy13;
        x13+=dx13;
        if(y13>height-25 || y13<25) {
            dy13=-dy13;
        }
        if(x13>width-25 || x13<25) {
            dx13=-dx13;
        }
    }
    else {EonCString.stop();}

    //F Natural, C String, KEY = V
    if (keyIsDown(86)) {
        FonCString.play();
        ellipse(114, (height/2)+7, 4, 4);
        y14+=dy14;
        x14+=dx14;
        if(y14>height-25 || y14<25) {
            dy14=-dy14;
        }
        if(x14>width-25 || x14<25) {
            dx14=-dx14;
        }
    }
    else {FonCString.stop();}
    
    //G Natural, C String, KEY = B
    if (keyIsDown(66)) {
        GonString.play();
        ellipse(130, (height/2)+7.5, 4, 4);
        y15+=dy15;
        x15+=dx15;
        if(y15>height-25 || y15<25) {
            dy15=-dy15;
        }
        if(x15>width-25 || x15<25) {
            dx15=-dx15;
        }
    }
    else {GonString.stop();}

    //G Natural, G String, KEY = A
    if (keyIsDown(65)) {
        GonString2.play();
        y18+=dy18;
        x18+=dx18;
        if(y18>height-25 || y18<25) {
            dy18=-dy18;
        }
        if(x18>width-25 || x18<25) {
            dx18=-dx18;
        }
    }
    else {GonString2.stop();}

    //C Natural, C String, KEY = Z
    if (keyIsDown(90)) {
        ConString.play();
        y19+=dy19;
        x19+=dx19;
        if(y19>height-25 || y19<25) {
            dy19=-dy19;
        }
        if(x19>width-25 || x19<25) {
            dx19=-dx19;
        }
    }
    else {ConString.stop();}
}

function makeViola() {
    stroke(255);
    strokeWeight(.4);

    push();
    noStroke();
    strokeWeight(1);
    fill(187, 74, 28);
    //Upper Bout
    arc(205, (height/2)+.5, 100, 120, 1.5, 4.81, CHORD);
    //Lower Bout
    arc(358, (height/2)+.5, 110, 125, 4.6, 8, CHORD);

    quad(210, (height/2)-59, 208, (height/2)+60.5, 255, (height/2)+52, 255, (height/2)-52);

    noFill();
    strokeWeight(4);
    stroke(187, 74, 28);
    //little curve
    arc(254, (height/2)-55, 11, 10, -.2, 2);
    arc(254, (height/2)+55, 11, 10, 4.3, 6.2);

    //Waist of Viola
    arc(285, (height/2)-55, 50, 30, -.2, 3);
    arc(285, (height/2)+55, 50, 30, 3, 6.6);

    //lower bout
    arc(328.5, (height/2)-62, 48, 14, .12, 2.9);
    arc(329, (height/2)+64, 48, 14, 3.3, 6.1);

    fill(187, 74, 28);
    //filling in sparce areas
    quad(252, (height/2)-48, 252, (height/2)+48, 260, (height/2)+51, 260, (height/2)-51);
    quad(260, (height/2)-45, 260, (height/2)+47, 280, (height/2)+38, 280, (height/2)-36);
    quad(279, (height/2)-38, 279, (height/2)+38, 307, (height/2)+44, 306, (height/2)-43);
    quad(305, (height/2)-44, 306, (height/2)+46, 313, (height/2)+52, 313, (height/2)-52);
    quad(312, (height/2)-53, 312, (height/2)+55, 333, (height/2)+53, 333, (height/2)-52);
    quad(332, (height/2)-53, 332, (height/2)+53, 352, (height/2)+58, 352, (height/2)-58);

    //Black Outline of Body
    strokeWeight(1);
    stroke(0);
    noFill();
    arc(205, (height/2)+.5, 100-7, 120-7, 1.5, 4.81);
    arc(358, (height/2)+.5, 110-7, 125-7, 4.6, 8);
    line(209, (height/2)-59+3, 254, (height/2)-52+3);
    line(209, (height/2)+59-3, 254, (height/2)+52-3);
    arc(254, (height/2)-55+1.6, 11, 10, -.2, 1.7);
    arc(254, (height/2)+55, 11, 10, 4.5, 6.2);
    arc(285, (height/2)-54, 50, 30, -.2, 3.1);
    arc(285, (height/2)+54, 50, 30, 3, 6.6);
    arc(328.5, (height/2)-62, 52, 15, .17, 2.88);
    arc(329.5, (height/2)+64-.5, 49, 16, 3.3, 6.05);
    pop();

    //finger board
    fill(0);
    quad(80-10, (height/2)-10, 80-10, (height/2)+10, 250+26, (height/2)+18, 250+26, (height/2)-18);

    //Pegs
    stroke(0);
    quad(38, (height/2)+9, 38+5-1, (height/2)+9, 38+5-1, (height/2)-17, 38, (height/2)-17);
    quad(38+8, (height/2)+9+8, 38+5+8-1, (height/2)+9+8, 38+5+8-1, (height/2)-17+8, 38+8, (height/2)-17+8);
    quad(38+16, (height/2)+9+1, 38+5+16-1, (height/2)+9+1, 38+5+16-1, (height/2)-17+1, 38+16, (height/2)-17+1);
    quad(38+24, (height/2)+9+7, 38+5+24-1, (height/2)+9+7, 38+5+24-1, (height/2)-17+7, 38+24, (height/2)-17+7);

    //Peg Ends
    fill(0);
    arc(40, (height/2)-20+1, 12, 12, 2.5, 6.9, CHORD);
    arc(40+16, (height/2)-20, 12, 12, 2.5, 6.9, CHORD);
    arc(40+8, (height/2)+20-1, 12, 12, 4+3-1.3, 3+.85, CHORD);
    arc(40+24, (height/2)+20, 12, 12, 4+3-1.3, 3+.85, CHORD);

    //Peg Dots
    ellipse(40, (height/2)-26, 2, 2);
    ellipse(40+16, (height/2)-26-1, 2, 2);
    ellipse(40+8, (height/2)+26, 2, 2);
    ellipse(40+24, (height/2)+26+1, 2, 2);

    //Peg Triangles
    triangle(36, (height/2)-13.5, 44, (height/2)-13.5, 40, (height/2)-23);
    triangle(36+16, (height/2)-13.5-1, 44+16, (height/2)-13.5-1, 40+16, (height/2)-23-1);
    triangle(36+8, (height/2)+13.5, 44+8, (height/2)+13.5, 40+8, (height/2)+23);
    triangle(36+24, (height/2)+13.5+1, 44+24, (height/2)+13.5+1, 40+24, (height/2)+23+1);

    stroke(255);
    //peg box
    fill(187, 74, 28);
    quad(70, (height/2)-10, 70, (height/2)+10, 30, (height/2)+7, 30, (height/2)-7);
    stroke(252, 185, 91);

    //Black Section of Peg Box
    fill(0);
    quad(35, (height/2)-3.5, 35, (height/2)+3.5, 70, (height/2)+6.5, 70, (height/2)-6.5);
    line(35, (height/2)-3.5, 70, (height/2)-6.5);
    line(35, (height/2)+3.5, 70, (height/2)+6.5);

    push();
    //String colors in peg box
    stroke(250, 127, 164); //pink
    line(37.5, (height/2)-3, 42.5, (height/2)-3);
    line(37.5, (height/2)-1.5, 42.5, (height/2)-1.5);
    line(37.5, (height/2), 42.5, (height/2));

    stroke(180, 101, 40); //brown
    line(37.5+8, (height/2)-3+3, 42.5+8, (height/2)-3+3);
    line(37.5+8, (height/2)-1.5+3, 42.5+8, (height/2)-1.5+3);
    line(37.5+8, (height/2)+3, 42.5+8, (height/2)+3);

    stroke(255, 0, 0); //red
    line(37.5+16, (height/2)-3-1, 42.5+16, (height/2)-3-1);
    line(37.5+16, (height/2)-1.5-1, 42.5+16, (height/2)-1.5-1);
    line(37.5+16, (height/2)-1, 42.5+16, (height/2)-1);

    stroke(216, 154, 253); //purple
    line(37.5+8+16, (height/2)-3+3+1, 42.5+8+16, (height/2)-3+3+1);
    line(37.5+8+16, (height/2)-1.5+3+1, 42.5+8+16, (height/2)-1.5+3+1);
    line(37.5+8+16, (height/2)+3+1, 42.5+8+16, (height/2)+3+1);
    pop();

    fill(187, 74, 28);
    //Inner Most Scroll Piece
    quad(15, (height/2)-18+1, 15, (height/2), 43-18-3.5, (height/2), 43-18-3.5, (height/2)-18+1);
    quad(15, (height/2)+18-1, 15, (height/2), 43-18-3.5, (height/2), 43-18-3.5, (height/2)+18-1);

    //Middle Scroll Piece
    quad(13-2, (height/2)-13+1, 13-2, (height/2), 43-18+2, (height/2), 43-18+2, (height/2)-16+1);
    quad(13-2, (height/2)+13-1, 13-2, (height/2), 43-18+2, (height/2), 43-18+2, (height/2)+16-1);
    
    //Outer Most Scroll Piece
    quad(14-9, (height/2)-6, 14-9, height/2, 43-10, height/2, 43-10, (height/2)-11);
    quad(14-9, (height/2)+6, 14-9, height/2, 43-10, height/2, 43-10, (height/2)+11);

    //Bridge
    stroke(223, 210, 194);
    strokeWeight(3);
    line(311, (height/2)-16, 311, (height/2)+16);
    stroke(30);
    strokeWeight(1);
    //Tail piece
    fill(0);
    triangle(345, (height/2)-18, 345, (height/2)+18, 410, (height/2));

    //Chin rest
    push();
    rotate(radians(19));
    ellipse(437, (height/2)-118, 40, 60);
    pop();

    push();
    stroke(251, 198, 212);
    strokeWeight(2.5);
    line(86, (height/2)-9.5, 86, (height/2)+9.5);
    line(105, (height/2)-10, 105, (height/2)+10);
    line(114, (height/2)-10.5, 114, (height/2)+10.5);
    line(130, (height/2)-11, 130, (height/2)+11);
    pop();

    //Strings
    stroke(240);
    strokeWeight(.7);
    line(58, (height/2)-4.5, 70, (height/2)-6); //Upper A String
    line(70, (height/2)-6, 311, (height/2)-14); //A String
    line(43, (height/2)-2, 311, (height/2)-5); //D String
    line(51, (height/2)+2, 311, (height/2)+4); //G String
    line(70, (height/2)+5.7, 311, (height/2)+13); //C String
    line(66, (height/2)+4.5, 70, (height/2)+5.5); //Upper C String

    line(311, (height/2)-14, 348, (height/2)-11); //Lower A String
    line(311, (height/2)-5, 348, (height/2)-4); //Lower D String
    line(311, (height/2)+4, 348, (height/2)+3.5); //Lower G String
    line(311, (height/2)+13, 348, (height/2)+11); //Lower C String

    stroke(255, 0, 0); //Red String Ends
    strokeWeight(1.3);
    line(330, (height/2)-12.6, 348, (height/2)-11);
    stroke(11, 85, 25); //Green String Ends
    line(330, (height/2)-4.5, 348, (height/2)-4);
    line(330, (height/2)+3.8, 348, (height/2)+3.5);
    line(330, (height/2)+12, 348, (height/2)+11);

    //Fine Tuner
    strokeWeight(1);
    stroke(255, 206, 79);
    fill(255, 220, 123);
    ellipse(349, (height/2)-11, 4, 4);

    stroke(0);
    strokeWeight(3);
    noFill();
    //Upper F Hole
    arc(296, (height/2)-25, 30, 12, 2.7, 4);
    line(291, (height/2)-31, 315, (height/2)-34.6);
    arc(310, (height/2)-40, 30, 12, 5.7, 7);
    
    //Lower F Hole
    arc(296, (height/2)+25.5, 30, 12, 2.3, 3.65);
    line(291, (height/2)+31, 315, (height/2)+34.6);
    arc(310, (height/2)+40.6, 30, 12, 5.5, 6.8);

    //little lines on F Holes
    strokeWeight(.8);
    line(305, (height/2)-30, 304, (height/2)-35);
    line(305, (height/2)+31, 304, (height/2)+36);

    //Dots on F Holes
    fill(0);
    ellipse(287, (height/2)-21.5, 4.3, 4.3);
    ellipse(287.2, (height/2)+21.9, 4.3, 4.3);

    ellipse(316.5, (height/2)-43.5, 5, 5);
    ellipse(317, (height/2)+44, 5, 5);
}

BrandonHyun-FinalProject-SectionB

Website for actually trying the program online

 

 

 

code for Final Project

ZIP File for Final Project for 15104

The purpose of this project is to gain different interpretations about the current events by giving the users the opportunity to draw or write about the issues that are presented to them. The content that gets presented is related to current events and political status. Furthermore, I would like to develop this project so that this website can exist in the online world with different interpretations and with opinions that can reside and see different opinions visually. This would be an anonymous participation by the public so we can get honest reviews about the political atmosphere around us and what people are thinking about.