Jacky Tian’s Final Project

For this final project, I created a “Catch & and Run” game. As a player, you need to use your mouse to control the position of a thief. Your goal is to collect coins in order to earn score.

Instructions:

  1. Use you mouse to control the position of the thief.
  2. Move the thief onto the coin in order to collect it and earn score.
  3. After the coin is collected, the next one will spawn randomly elsewhere.
  4. Avoid the cops when moving towards the coins, if you get caught, it’s GG.
  5. Good luck and have fun!

sketch

//Final Project
//Yinjie Tian
//yinjiet@andrew.cmu.edu
//Section D

var theif;
var cop;
var copX = [];
var copY = [];
var dx = [];
var dy = [];
var coinX = 300;
var coinY = 300;
var coin;
var count = 0;
var carX;
var carX2;
var carY;
var carY2;
var carSpeed;
var showText = false;

function preload(){
  thief = loadImage("https://i.imgur.com/lcp6pIM.png");
  cop = loadImage("https://i.imgur.com/ndxH6Uh.png");
  coin = loadImage("https://i.imgur.com/fKFvpra.png");

}

function setup(){
 	createCanvas(600, 480);
 	imageMode(CENTER);
//creating two cars moving in opposite direction
 	carX = 200;
 	carX2 = 350;
 	carY = 0;
 	carY2 = height - 60;
 	carSpeed = random(1,5);
// Randomly select cops' starting location and speed
  for (var i = 1; i < 15; i++) { 
    copX[i] = random(30, width - 30);
    copY[i] = random(40, height - 40);
    dx[i] = random(-2, 5);
    dy[i] = random(-2, 5);
  }
}

function draw(){
	background("grey");
//street background
	fill("white");
	noStroke();
	rect(0,0,100,150);
	rect(0,330,100,150);
	rect(500,0,100,150);
	rect(500,330,100,150)
//crosswalks
	rect(110, 50, 20, 100);
	rect(150, 50, 20, 100);
	rect(190, 50, 20, 100);
	rect(230, 50, 20, 100);
	rect(270, 50, 20, 100);
	rect(310, 50, 20, 100);
	rect(350, 50, 20, 100);
	rect(390, 50, 20, 100);
	rect(430, 50, 20, 100);
	rect(470, 50, 20, 100);
	
	rect(110, 330, 20, 100);
	rect(150, 330, 20, 100);
	rect(190, 330, 20, 100);
	rect(230, 330, 20, 100);
	rect(270, 330, 20, 100);
	rect(310, 330, 20, 100);
	rect(350, 330, 20, 100);
	rect(390, 330, 20, 100);
	rect(430, 330, 20, 100);
	rect(470, 330, 20, 100);

//cars moving
	fill("red");
	rect(carX, carY, 40, 60);
	carY += carSpeed;
	if(carY > height){
		carY = -60;
	}
	fill("blue");
	rect(carX2, carY2, 40, 60);
	carY2 -= carSpeed;
	if(carY2 < -60){
		carY2 = height;
	}
// Make the cops move randomly in the canvas
 	for (var i = 1; i < 8 ; i ++){
  	image(cop, copX[i], copY[i]);
  
    copX[i] += dx[i];
    copY[i] += dy[i];

// bounce back if cops hit boundary
    if (copX[i] + 30 > width || copX[i] - 30 < 0){
      dx[i] =- dx[i];
      }
    if (copY[i] + 40 > height || copY[i] - 40 < 0){
      dy[i] =- dy[i];
      }
// if theif got caught
	 if (copX[i] > mouseX - 15  & copX[i] < mouseX + 15){
     	if (copY[i] > mouseY - 20 && copY[i] < mouseY + 20){
     		endGame();
      }      
    }
// if theif got hit by car1
	 if (carX > mouseX - 15  & copX < mouseX + 15){
     	if (carY > mouseY - 20 && carY < mouseY + 20){
     		endGame();
      }      
    }
// if theif got hit by car2
if (carX2 > mouseX - 15  & carX2 < mouseX + 15){
     	if (carY2 > mouseY - 20 && carY2 < mouseY + 20){
     		endGame();
      }      
    }
  }
   
// create theif
	image(thief, mouseX, mouseY);
	
// randomly placing coin 
	image(coin, coinX, coinY);

// scoreboard
	textSize(20);
	fill("white");	
  	text("SCORE: " + str(count), 260, 30);

// if theif gets the coin  	
	if (coinStolen()){
		coinPlace();			
  		count +=10;
	}
}

function coinPlace(){
	coinX = random(30, width - 30);
	coinY = random(30, height - 30);
}

function coinStolen(){
	var d = dist(mouseX, mouseY, coinX, coinY);
	if(d < 20){
		return true;
	}
	else {
		return false;
	}
}


function endGame(){	
	showText = true;
	fill("pink");
	textSize(50);
	textStyle(BOLD);
  	textFont('New Roman');
	text("GGWP! Please Refresh", 50, height/2);
	noLoop();
}

Shannon Ha – Final Project

sketch

//Shannon Ha
//sha2@andrew.cmu.edu
//Section D
// Final Project
var soundLogos = [];
var amplitude; //initialize amplitude
var level; //initialize amp level
var rotatePath = 0;
var h;
var dY; // dot x position
var dX; // dot y position

function preload(){ //load sounds
    soundLogos[1] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Apple-1-2.wav');
    soundLogos[2] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Apple-2-text-2.wav');
    soundLogos[4] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Intel-p2.wav');
    soundLogos[5] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Microsoft-2-1.wav');
    soundLogos[6] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Microsoft-3-1.wav');
    soundLogos[7] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Netflix-1.wav')
    soundLogos[8] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Nokia-1.wav');
    soundLogos[9] = loadSound('https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/Skype-1.wav');
}

function setup() {
  createCanvas(300, 300);
  amplitude = new p5.Amplitude(); // p5.js sound library for amplitude
}

function draw() {
  background(0);
  push();
  translate(width / 2, height / 2); // centers the epicycloid
  drawEpicy();
  pop();
  drawThreeDots();
  drawIntelEllipse();
  drawMicroGrid()
}

function keyPressed(){ // assigns the number keys to respective sound files and animations.
    if (key == '1'){
        soundLogos[1].play();
        drawEpicy();

    } else if (key == '2'){
        soundLogos[2].play();
        dY = height / 2; // makes starting position of dot center of canvas
        dX = width / 2; // makes starting position of dot center of canvas
        drawThreeDots();

    } else if (key == '3'){
        soundLogos[4].play();
        drawIntelEllipse();

    } else if (key == '4'){
        soundLogos[5].play();
        drawMicroGrid();

    } else if (key == '5'){
        soundLogos[6].play();

    } else if (key == '6'){
        soundLogos[7].play();

    } else if (key == '7'){
        soundLogos[8].play();

    } else if (key == '8'){
        soundLogos[9].play();
        }
    }

//animation for apple
function drawEpicy() {
    var a = 60; // variable that controls the size and curvature of shape
    var b = a / 2; // variable that controls the size and curvature of shape
    level = amplitude.getLevel(); //takes the value of measured amp level.
    h = map(level, 0, 3, 20, 900); // maps amplitude to appropriate value
    var ph = h / 2; // links mapped amp value as a variable that controls shape.
    fill(h * 5, h * 10, 200); //fills color according to measured amp.
    noStroke();
    beginShape();
  for (var i = 0; i < 100; i ++) { // for loop to draw vertex for epicycloid
      var t = map(i, 0, 100, 0, TWO_PI); // radian value.
      x = (a + b) * cos(t) - h * cos(ph + t * (a + b) / b);
      y = (a + b) * sin(t) - h * sin(ph + t * (a + b) / b);
        vertex(x, y); //curve line
         }
  endShape();
}

//animation for text
function drawThreeDots(){ //draws the three dots that fall
    fill(255);
    noStroke();
    print(h);
    ellipse(dX - 50, dY, 25, 25);
    ellipse(dX, dY * 1.2, 25, 25);
    ellipse(dX + 50, dY * 1.5, 25, 25);
    dY += 10; // vertical falling
}

function drawIntelEllipse(){
    level = amplitude.getLevel();
    let h = map(level, 1, 8, 5, 50);
    for (var i = 0; i < 15 ; i++){
  		var diam = rotatePath - 30 * i; // creates the spin out effect of the ellipse

      if (diam > 0){ //pushes each new ellipse to show
        noFill();
  		stroke(0, 113, 197); //intel blue
        strokeWeight(2);
        ellipseMode(CENTER)
        push();
        translate(width/8 - 90, height/4 - 10); //position of starting ellipse
        rotate(cos(2.0));// rotation angle
        ellipse(200, 200, diam / h, 40 / h); // the size of the ellipse is affected by amp.
      }
    }
    rotatePath = rotatePath + 2; // controls the speed of the spin out effect.
  }

function drawMicroGrid(){ // suppose to imitate the microsoft grid
    level = amplitude.getLevel();
    let h = map(level, 1, 8, 20, 200);
    noStroke();
    rectMode(CENTER);
    for (var y = 50; y < height + 50; y += 100) { // nested for loop for tiling
       for (var x = 50; x < width + 50; x += 100) {
           fill(x, y + 100, h * 5); // color is affected by amp
           rect(x , y, h * 3, h * 3); // size is affected by amp
       }
   }
}

How does it work:

Press all the number keys from 1 to 8 and watch the patterns move and change to familiar sound logos!

(For some reason there are problems when Safari is used to view my project so please use Chrome or Firefox!)

In my proposal, I wanted to do some sort of sound visualization either in a form of a game or something similar to patatap. Sticking to my proposal, I used some iconic sounds that can be recognized through our day to day usage of technology. I realized how easy it is to overlook the importance of how these sounds inform our usage of technology so I ended up creating a sonic art piece that creates patterns according to the amplitude measured through the sound files.

My final project does not quite achieve the level of fidelity I originally intended my sonic art to have as the visuals are a bit too noisy and I want it to have a simple yet sophisticated look. I spent quite a bit of time trying to figure out how to use sound libraries in p5.js and mapping the amplitude to each of the various patterns, so I had a bit of difficulty debugging the whole code.

Ian Kaneko – Final Project

ikaneko 15-104 final project

Unfortunately I ran into trouble while trying to embed my project. Linked above is a zip file that contains my project and the sound files necessary to run it. Clicking the link should begin a download of the zip file. After extracting the file the project should be available just by running the index found in the template-all folder.

For my final project I created a set of wind chimes that the user can interact with. The user can swipe their mouse through the chimes, moving them and causing them to sound when they collide with each other. When the mouse hits a chime it will move in the direction that the mouse was moving with force proportional to how fast the mouse was moving as well. The chimes will also transfer momentum when they collide with each other. The pitches from left to right are C, D, E, G, A, C, and D. The sounds are sampled from a glockenspiel which sounds very similar to wind chimes. (If you swipe really hard and some chimes go off-screen don’t worry, they come back!)

The starting position of the chimes
Chimes after being swiped around

Min Ji Kim Kim & Kristine Kim – Final Project


sketch

Kristine and I created 2 interactive stories from the Bible since Christianity is something that we really value. We decided to create this as a method to teach children about the Bible while also letting them have fun.

Kristine worked on the “Feeding the 5000” story while I worked on the “Noah’s Ark” story. We met together throughout the week to make sure our two programs connected and worked smoothly which took the most time. I also took charge of securing of online images and creating the image arrays since I was working on the more image heavy portion and Kristine in turn worked on the menu screen and the character movement as well. We divided the work very evenly and made sure to consult with each other if we had problems or didn’t know how to do something.

The only thing you might need to know to play our game is to make sure to  completely go to the end of the path to the end of canvas width, since it goes to the next screen automatically once the character gets to the end.

We had so much fun creating this project!

// Kristine Kim & Min Ji Kim Kim
// Section D & A
// younsook & mkimkim
// Final Project

// -------------------------------- VARIABLES --------------------------------

// GENERAL
var texts = [];
var people = [];
var peopleImages = [];
var character;

// MENU
var screen = "menu"; //screen always set to menu when first opened
var Bible;
var leftFrame;
var rightFrame;

//FEEDING THE 5000
var food = [];
var foodImages = [];
var disciple;
var crowd1;
var crowd2;
var crowd3;

// NOAH'S ARK
var ark;
var rain = [];
var animalImages = [];
var animals = [];
var offsetX; // offsets for mouse drag later
var offsetY;

// --------------------------- PRELOAD IMAGES ----------------------------------

function preload() {
    var foodLinks = [];
    foodLinks[0] = 'https://i.imgur.com/I2GtIHI.png'; // fish
    foodLinks[1] = 'https://i.imgur.com/37fSZcK.png'; // bread
    foodLinks[2] = 'https://i.imgur.com/U5WevzT.png'; // basket
    for (var i = 0; i < foodLinks.length; i++) { // push urls into array
        foodImages[i] = loadImage(foodLinks[i]);
    }

    var animalLinks = [];
    animalLinks[0] = 'https://i.imgur.com/CBoFToW.png'; // giraffe
    animalLinks[1] = 'https://i.imgur.com/mOTcpZg.png'; // koala
    animalLinks[2] = 'https://i.imgur.com/cIjfUHk.png'; // monkey
    animalLinks[3] = 'https://i.imgur.com/ucc7kcb.png'; // elephant
    animalLinks[4] = 'https://i.imgur.com/n3MKNo5.png'; // lion
    animalLinks[5] = 'https://i.imgur.com/fcfIkPJ.png'; // bird
    animalLinks[6] = 'https://i.imgur.com/XhSjml7.png'; // turtle
    animalLinks[7] = 'https://i.imgur.com/bq0OgoB.png'; // zebra
    for (var i = 0; i < animalLinks.length; i++) { // push urls into array
        animalImages[i] = loadImage(animalLinks[i]);
    }

    var textLinks = [];
    textLinks[0] = 'https://i.imgur.com/JB4gpam.png'; // Andrew Intro
    textLinks[1] = 'https://i.imgur.com/CTLxAP2.png'; // Andrew End
    textLinks[2] = 'https://i.imgur.com/XIGb2J9.png'; // Noah Intro
    textLinks[3] = 'https://i.imgur.com/uEHleCT.png'; // Noah End
    textLinks[4] = 'https://i.imgur.com/ouDdHh0.png'; // Feed Instructions
    textLinks[5] = 'https://i.imgur.com/84dBAhN.png'; // Ark Instructions
    for (var i = 0; i < textLinks.length; i++) { // push urls into array
        texts[i] = loadImage(textLinks[i]);
    }

    var peopleLinks = [];
    peopleLinks[0] = 'https://i.imgur.com/jZVql8t.png'; // Noah
    peopleLinks[1] = 'https://i.imgur.com/EDZROu3.png'; // Andrew
    peopleLinks[2] = 'https://i.imgur.com/moPXqEi.png'; // Jesus
    for (var i = 0; i < peopleLinks.length; i++) { // push urls into array
        peopleImages[i] = loadImage(peopleLinks[i]);
    }

    Bible = loadImage('https://i.imgur.com/VKVcQg5.png');
    leftFrame = loadImage('https://i.imgur.com/XyGYYj0.jpg');
    rightFrame = loadImage('https://i.imgur.com/jpBO0LB.jpg');
    character = loadImage('https://i.imgur.com/BiTQr7u.png');
    ark = loadImage('https://i.imgur.com/kqvTedI.png');
    crowd1 = loadImage('https://i.imgur.com/Gz2HLDi.png');
    crowd2 = loadImage('https://i.imgur.com/l4SCJCo.png');
    crowd3 = loadImage('https://i.imgur.com/JON4rd1.png');
}

// -----------------------------------------------------------------------------

function setup() {
    createCanvas(600, 600);
    strokeJoin(MITER); // turtle code stroke join & cap settings
    strokeCap(PROJECT);
    for(var i = 0; i < 300; i++) {
        rain.push(drop()); // load raindrops into array (for Noah's ark story)
    }
}

// DRAWING SCREENS
function draw() {
    if(screen == "menu") {
        menuScreen();
    }
    else if (screen == "feedIntro") {
        feedIntroScreen();
    }
    else if (screen == "feed") {
        feedScreen();
    }
    else if (screen == "feedEnd") {
        feedEndScreen();
    }
    else if (screen == "arkIntro") {
        arkIntroScreen();
    }
    else if (screen == "ark") {
        arkScreen();
    }
    else if (screen == "arkEnd") {
        arkEndScreen();
    }
}

// ---------------------------------- MENU -------------------------------------

function menuScreen() {
    background("#0F7B96");
    
    //table
    noStroke();
    fill("#553C2A");
    rect(0, height - 120, width, 120);
    
    //book
    image(Bible, 80, 320);
    
    //draw & change frame color if selected
    //left frame
    fill(0);
    if(mouseX < 270 & mouseX > 40 && mouseY > 140 && mouseY < 320) {
        fill("#AEA4FA");
    }
    rect(40, 150, 230, 180);
    image(leftFrame, 50, 160);

    //right frame
    fill(0);
    if(mouseX < 560 & mouseX > 330 && mouseY > 140 && mouseY < 320) {
        fill("#5DED79");
    }
    rect(330, 150, 230, 180);
    image(rightFrame, 340, 160);
    
    //text
    fill(255);
    textAlign(CENTER);
    textFont("Trebuchet MS", 25);
    text("Select a Bible story", width / 2, 60);
    textSize(20);
    text("Jesus feeds the 5000", 155, 130);
    text("Noah's Ark", 450, 130);
}

// SELECT A STORY
function mouseClicked() {
    if (screen == "menu") {
        if(mouseX < 270 & mouseX > 40 && mouseY > 140 && mouseY < 320) {
            screen = "feedIntro"; // click on left frame
        }
        if(mouseX < 560 & mouseX > 330 && mouseY > 140 && mouseY < 320) {
            screen = "arkIntro"; // click on right frame
        }
    }

    if (screen == "feedEnd" || screen == "arkEnd") {
        if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
            screen = "menu"; // click on "menu" to go back to menu
        }
    }

    if (screen == "feedIntro") {
        if (mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
            screen = "feed"; // click "go help ->" to go to main story
        }
    }

    if (screen == "arkIntro") {
        if (mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
            screen = "ark"; // click "go help ->" to go to main story
        }
    }
}

// --------------------------- JESUS FEEDS THE 5000 ----------------------------

//STORY  INTRODUCTION
function feedIntroScreen() {
    background(255);
    //display Andrew, basket, text, and button to go to main story
    image(peopleImages[1], 50, height / 4);
    image(foodImages[2], 230, 350);
    image(texts[0], 250, 120);
    goHelpButton();
}

// MAIN STORY SCREEN
function feedScreen() {
    background("#a9c75f");
    maze1();
    createMainChar(); //display character 
    image(peopleImages[2], 330, 280); //display Jesus
    for (var i = 0; i < food.length; i++) { //draw food inside the array
        food[i].draw();
    }

    //display basket at mouse location 
    var scaleWidth = foodImages[2].width * 0.4; //scale basket image 
    var scaleHeight = foodImages[2].height * 0.4;
    var bkx = scaleWidth / 2; // offset from left corner
    var bky = scaleHeight / 2;
    image(foodImages[2], mouseX - bkx, mouseY - bky, scaleWidth, scaleHeight);

    //display instructions and crowds
    image(texts[4], 0, 530);
    image(crowd1, 230, 380);
    image(crowd2, 310, 5);
    image(crowd3, 350, 40);

    //when character reaches the end of the maze, reset character position
    //clear food array and go to end screen
    if (people[0].x > width) {
        people[0].x = 10;
        people[0].y = 410;
        food = [];
        screen = "feedEnd";
    }
}

//CODE FOR FOOD IMAGES
// create an object for food images 
function makeFood(x, y, type) {
    var foods = {x: x,
                y: y,
                type: type,
                draw: foodDraw}
    return foods;
}

function foodDraw() {
    if (this.type === 'fish') { //draw bread at mouse location
        image(foodImages[0], this.x, this.y);
    }
    else if (this.type === 'bread') { //draw fish at mouse location
        image(foodImages[1], this.x, this.y);
    }
}

// interaction keys to make fish and bread on canvas at mouse location
function keyPressed() {
    if(screen == "feed") { // create fish = press f
        if (keyCode == 70) {
            var fx = foodImages[0].width / 2; // offset from left corner
            var fy = foodImages[0].height / 2;
            newFood = makeFood(mouseX - fx, mouseY - fy, 'fish');
            food.push(newFood);
        }
        if (keyCode == 66) { // create bread = press b
            var bx = foodImages[1].width / 2; // offset from left corner
            var by = foodImages[1].height / 2;
            newFood = makeFood(mouseX - bx, mouseY - by, 'bread');
            food.push(newFood);
        }
    }
}

// create maze path using turtle graphics
function maze1() {
    var ttl1 = makeTurtle(20, 480);
        ttl1.setColor(color("#a6927b"));
        ttl1.setWeight(40);
        ttl1.forward(150);
        ttl1.left(90);
        ttl1.forward(100);
        ttl1.left(90);
        ttl1.forward(100);
        ttl1.right(90);
        ttl1.forward(280);
        ttl1.right(90);
        ttl1.forward(240);
        ttl1.right(90);
        ttl1.forward(80);
        ttl1.right(90);
        ttl1.forward(120);
        ttl1.left(90);
        ttl1.forward(100);
        ttl1.left(90);
        ttl1.forward(250);
        ttl1.right(90);
        ttl1.forward(200);
        ttl1.left(90);
        ttl1.forward(120);
        ttl1.left(90);
        ttl1.forward(70);
        ttl1.right(90);
        ttl1.forward(20);
    //stage for Jesus
    fill("#a6927b");
    rect(280, 250, 100, 100);
}

// STORY ENDING SCREEN 
function feedEndScreen() {
    background(169, 146, 119);
    //display Andrew, text and menu button
    image(peopleImages[1], 50, height / 4);
    image(texts[1], 250, 100);
    menuButton(); // go back to "menu" button
}

// ------------------------------ NOAH'S ARK -----------------------------------

// STORY INTRODUCTION
function arkIntroScreen() {
    background(255);
    //display Noah, text, ark and button to go to main story
    image(peopleImages[0], 50, height / 4);
    image(texts[2], 250, 130);
    image(ark, 250, 250);
    goHelpButton(); // button to go to main screen
}

// MAIN STORY SCREEN
function arkScreen() {
    // display background gradient
    var turquoise = color(16, 157, 172); 
    var navy = color(1,84,134);
    gradient(turquoise, navy);

    //display maze, ark, character and instructions
    maze2();
    image(ark, 370, 80);
    createMainChar();
    image(texts[5], 0, 550);

    // display animals
    for (var i = 0; i < animalImages.length; i++) {
        animals.push(makeAnimal(animalImages[i])); //push images into array
        animals[i].draw(); //draw animals
        // if the animal is moved, adjust that image location
        if (animals[i].moving) {
            animals[i].x = mouseX + offsetX;
            animals[i].y = mouseY + offsetY;
        }
    }

    // make it rain when pressing "r"
    if (keyIsDown(82)) {
        for (var r = 0; r < rain.length; r++) {
            rain[r].display();
            rain[r].falling();
        }
    }
    //when character reaches the end of the maze, reset character position,
    //clear animals array and go to end screen
    if (people[0].x > width) {
        people[0].x = 10;
        people[0].y = 410;
        animals = [];
        screen = "arkEnd";
    }
}

// to render background gradient for main story
function gradient(c1, c2) {
    noFill();
    noStroke();
    for (var x = 0; x < width; x++) {
        var mapColor = map(x, 0, width, 0, 2);
        var c = lerpColor(c1, c2, mapColor);
        stroke(c);
        line(x, 0, x, height);
    }
}

// create maze path using turtle graphics
function maze2() {
    var ttl2 = makeTurtle(20, 480);
        ttl2.setColor(color("#AF9879"));
        ttl2.setWeight(40);
        ttl2.forward(80);
        ttl2.left(90);
        ttl2.forward(400);
        ttl2.right(90);
        ttl2.forward(180);
        ttl2.right(90);
        ttl2.forward(150);
        ttl2.right(90);
        ttl2.forward(100);
        ttl2.left(90);
        ttl2.forward(120);
        ttl2.left(90);
        ttl2.forward(180);
        ttl2.right(90);
        ttl2.forward(170);
        ttl2.left(90);
        ttl2.forward(120);
        ttl2.left(90);
        ttl2.forward(300);
        ttl2.right(90);
        ttl2.forward(100);
}

// CODE FOR ANIMALS
// to click and drag animal image
function mousePressed() {
    for (var i = 0; i < animalImages.length; i++) {
        if (animals[i] == undefined) { // terminate if animals[i] is undefined
            return;
        }
        // check if mouse is on the animal image
        if (mouseX > animals[i].x & mouseX < animals[i].x + animalImages[i].width && 
            mouseY > animals[i].y && mouseY < animals[i].y + animalImages[i].height) {
            animals[i].moving = true;
            // if yes, track location of the mouse click to the corner of animal image
            offsetX = animals[i].x - mouseX;
            offsetY = animals[i].y - mouseY;
        }
    }
}

function mouseReleased() {
    //stop dragging animal
    for (var i = 0; i < animalImages.length; i++) {
        if (animals[i] != undefined) { //check if animals[i] is defined
            animals[i].moving = false;
        }
    }
}

// create an object for animal images
function makeAnimal(image) {
    var animal = {img: image,
                    x: random(10, 550),
                    y: random(10, 490),
                    moving: false,
                    draw: drawAnimal}
    return animal;
}

function drawAnimal() {
    image(this.img, this.x, this.y);
}

// CODE FOR RAIN
// create rain drop object
function drop() {
    var drop = {x: random(0, width),
                y: random(-5, height),
                len: random(5, 20),
                thick: random(1, 3),
                vel: random(5, 15),
                display: dropDisplay,
                falling: dropFalling}
    return drop;
}

// display rain drop
function dropDisplay() {
    noStroke();
    fill(255, 90);
    ellipse(this.x, this.y, this.thick, this.len);
}

// make raindrop fall
function dropFalling() {
    this.y += this.vel;
    if (this.y > height) {
        this.y = -this.len;
    }
}

//STORY END SCREEN
function arkEndScreen() {
    background(178, 153, 116);
    //display Noah, text and menu button
    image(peopleImages[0], 50, height / 4);
    image(texts[3], 250, 130);
    menuButton(); // go back to "menu" button

}

// -------------------------- CHARACTER & MOVEMENT -----------------------------

function createMainChar () {
    //create the character object
    people.push(makeCharacter());
    people[0].draw();

    //MOVE CHARACTER BY PRESSING ARROW KEYS
    if (keyIsPressed) {
        if (keyCode === UP_ARROW) {
            people[0].y -= 2;
        }
        else if (keyCode === DOWN_ARROW) {
            people[0].y += 2;
        }
        else if (keyCode === LEFT_ARROW) {
            people[0].x -= 2;
        }
        else if (keyCode === RIGHT_ARROW) {
            people[0].x += 2;
        }
    }
}

function makeCharacter() {
    var char = { x: 10, y: 410, draw: drawCharacter }
    return char;
}

function drawCharacter() {
    image(character, this.x, this.y);
}

// ----------------------------- EXTRA BUTTONS ---------------------------------

// create button to go back to menu after story ends
function menuButton() {
    textSize(20);
    fill(0)
    if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
        fill('#27AEE3'); // change color if mouse is hovering over
    }
    text('menu', 550, 550);
}

// create button to go to main story
function goHelpButton() {
    textSize(20);
    fill(0);
    if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
        fill('#27AEE3'); // change color if mouse is hovering over
    }
    text('go help -> ', 550, 550);
}

// ------------------------- TURTLE CODE FOR MAZES -----------------------------

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

Cathy Dong – Final Project

sketch

/* Cathy Dong
   Section D
   yinhuid@andrew.cmu.edu
   Project 12 - Final Project
*/

// load image as color base
var baseImg;
var proportion = 0.24;
//cover text space setting
var space1 = 50;
var space2 = 32;
//block dimension (cover page)
var bw = 100;
var bh = 25;
//page number: cover + levels
var page = 0;

// draw rect fill color variable
var fillColor = 255;


var cSpace1 = 10;
var colorSize = 30;

// variables for drawRect()
var c = [];
var rectX = [];
var rectY = [];

// variables for drawLines()
var w = [];
var lineL = [];
var lineR = [];
var lineU = [];
var lineD = [];


// preload cover de stijl base image
function preload() {
    var img = "https://i.imgur.com/pJRSO5b.jpg";
    baseImg = loadImage(img);
}

function setup() {
    createCanvas(480, 480);
    background(0);
}

function draw() {
    // decide page
    pageSetting();

    //cover when page = 0;
    if (page == 0) {
        // make cover image, set to scale
        scale(proportion);
        image(baseImg,0,0);
        filter(THRESHOLD);
        // set scale back to 1:1 for text draw
        scale(1 / proportion);
        coverBlocks();
        coverText();
    }
    //level 1 when page == 1
    else if (page == 1) {
        clear();
        background(210);
        baseCanvas();
        commandKey();
        baseGrids(5);
        changeColor();
        drawRect(5);
        if (key !== "r" & key !== "R") {
            drawLine(5);
        }4
    }

    // level 2 when page == 2
    else if (page == 2) {
        clear();
        background(210);
        baseCanvas();
        commandKey();
        baseGrids(7);
        changeColor();
        drawRect(7);
        drawRect(7);
        if (key !== "r" || "R") {
            drawLine(7);
        }
    }

    // level 3 when page == 3
    else if (page == 3) {
        clear();
        background(210);
        baseCanvas();
        commandKey();
        baseGrids(15);
        changeColor();
        drawRect(15);
        drawRect(15);
        if (key !== "r" || "R") {
            drawLine(15);
        }
    }
}

// jump to page through cover levels
function pageSetting() {
    if (page == 0) {
        // select page 1
        if ((mouseIsPressed) 
            & (mouseY > height / 2 + space2) && (mouseY < height / 2 + space2 + bh)
            && (mouseX > width / 2 - 50) && (mouseX < width / 2 - 50 + bw)) {
            page  = 1;
        }
        // select page 2
        else if ((mouseIsPressed) 
            & (mouseY > height / 2 + space2 * 2) && (mouseY < height / 2 + space2 * 2 + bh)
            && (mouseX > width / 2 - 50) && (mouseX < width / 2 - 50 + bw)) {
                page  = 2;
        }
        // select page 3
        else if ((mouseIsPressed) 
            & (mouseY > height / 2 + space2 * 3) && (mouseY < height / 2 + space2 * 3 + bh)
            && (mouseX > width / 2 - 50) && (mouseX < width / 2 - 50 + bw)) {
                page  = 3;
        }
    }
}


// white blocks below option texts for texts to read better
function coverBlocks () {
    fill(255);
    noStroke();
    for (var i = 1; i < 4; i++) {
        rect(width / 2 - 50, height / 2 + space2 * i , bw, bh);
    }
}

// cover texts: title & levels
function coverText() {
    textStyle(BOLD);
    //title base setting
    noStroke();
    textAlign(CENTER);
    textSize(80);
    // title shadow
    fill(0);
    text("De Stijl", width / 2 + 5, height / 2 +-3);
    // title text
    fill(255);
    text("De Stijl", width / 2, height / 2);


    //options
    fill(0);
    noStroke();
    textSize(15);
    text("LEVEL 1", width / 2, height / 2 + space1);
    text("LEVEL 2", width / 2, height / 2 + space1 + space2);
    text("LEVEL 3", width / 2, height / 2 + space1 + space2 * 2);
}

// pick rectangle colors
function changeColor() {
    var keyX = width - 45;
    var cy = width / 2;
    if (mouseIsPressed) {
        if ((mouseX > keyX) & (mouseX < keyX + colorSize)) {
            // blue block
            if ((mouseY > cy + cSpace1) && (mouseY < cy + cSpace1 + colorSize)){
                fillColor = "blue";
            }
            // red block
            if ((mouseY > cy + cSpace1 * 2 + colorSize) 
                & (mouseY < cy + cSpace1 * 2 + colorSize * 2)) {
                fillColor = "red";
            }
            // yellow block
            if ((mouseY > cy + cSpace1 * 3 + colorSize * 2)
                & (mouseY < cy + cSpace1 * 3 + colorSize * 3)) {
                fillColor = "yellow";
            }
            // white block
            else if ((mouseY > cy + cSpace1 * 4 + colorSize * 3)
                & (mouseY < cy + cSpace1 * 4  +colorSize * 4)) {
                fillColor = "white";
            }
        }
    }
}


// white base draw canvas
function baseCanvas() {
    strokeWeight(5);
    stroke(0);
    fill(255);
    rect(10, 10, width - 70, height - 70);
}

//option grid lines
function baseGrids(level) {
    // grid lines
    noFill();
    strokeWeight(0.2);
    stroke("gray");

    // use loop to draw grids
    for (var i = 0; i < level; i++) {
        for (var j = 0; j < level; j++) {
            var gw = width - 70;
            var gh = height - 70;
            rect(10 + gw / level * i, 10 + gh / level * j, gw / level, gh / level);            
        }
    }
}

// color fill command key draw on the side
function commandKey() {
    var cx = width - 50;
    var cy = width / 2;
    var keyX = width - 45;
    // base setting
    textAlign(LEFT);
    textSize(10);
    textStyle(BOLD);
    fill(0);
    noStroke();
    text("COLORS", cx, cy);

    // keys blocks
    noStroke();
    fill("blue");
    rect(keyX, cy + cSpace1, colorSize, colorSize);
    fill("red");
    rect(keyX, cy + cSpace1 * 2 + colorSize, colorSize, colorSize);
    fill("yellow");
    rect(keyX, cy + cSpace1 * 3 + colorSize * 2, colorSize, colorSize);
    fill("white");
    rect(keyX, cy + cSpace1 * 4 + colorSize * 3, colorSize, colorSize);
}

// draw colored rectangles based on grid
function drawRect(level){
    var gw = width - 70;
    var gh = height - 70;
    // add x, y, colorFill to lists when mouse clicked and hold key "r" or "R"
    if (keyIsPressed) {
        if (key == "r" || key == "R") {
            // check if mouse clicked in which grid
            for (var m = 0; m < level; m++) {
                for (var n = 0; n < level; n++) {
                    // grid axis location
                    var left = 10 + gw / level * m;
                    var up = 10 + gh / level * n;
                    var right = left + gw / level;
                    var down = up + gh / level;
                    // mouse click location to find the grid
                    if (mouseIsPressed) {
                        if ((mouseX > left) & (mouseX < right) && (mouseY > up) && (mouseY < down)) {
                            // push fillColor, x, y into lists for later draw use
                            c.push(fillColor);
                            rectX.push(left);
                            rectY.push(up);
                        }
                    }
                }
            } 
        }
    }
    // loop through lists to draw rect
    for (var x = 0; x < c.length; x++) {
        fill(c[x]);
        noStroke();
        rect(rectX[x], rectY[x], gw / level, gh / level);
    }
}

function drawLine(level) {
    var gw = width - 70;
    var gh = height - 70;
    // precision torlerence
    var tolerence = 3;
    // loop through every grid
    for (var m = 0; m < level; m++) {
        for (var n = 0 ; n < level; n++) {
            var left = 10 + gw / level * m;
            var up = 10 + gh / level * n;
            var right = left + gw / level;
            var down = up + gh / level;

            // hold key to get the line weight
            if (keyIsPressed) {
                var currentKey = key;
            }
            // check mouseX and mouseY to determine if to draw a line
            if (mouseIsPressed) {
                // vertical lines into lists
                if (mouseY > up + tolerence & mouseY < down - tolerence) {
                    if (mouseX > left - tolerence && mouseX < left + tolerence) {
                        lineL.push(left);
                        lineR.push(left);
                        lineU.push(up);
                        lineD.push(up + gh / level);
                        w.push(currentKey);
                    }
                }
                // horizontal lines into lists
                if (mouseX > left + tolerence & mouseX < right - tolerence) {
                    if (mouseY > up - tolerence && mouseY < up + tolerence) {
                        lineL.push(left);
                        lineR.push(left + gw / level);
                        lineU.push(up);
                        lineD.push(up);
                        w.push(currentKey);
                    }
                }
            }
        }
    }
    // draw lines based on lists
    for (var x = 0; x < lineL.length; x ++) {
        strokeWeight(w[x]);
        noFill();
        stroke(0);
        line(lineL[x], lineU[x], lineR[x], lineD[x]);
    }
}

This project is to create a de stijl drawing of your own. By clicking on level 1-3, you will get 5×5, 7×7 or 15×15 grids.

Hold key “1” to “9” and click on the the grid edge to draw lines with the exact line weight. (selection precision tolerance is 3 pixels)

Click on the color keys on the lower left corner to select color. Holding “r” or “R” and clicking on the grid will draw rectangles that are the size of the grid. When drawing rectangles, lines will be hidden. Show lines by pressing on any other keys.

Gretchen Kupferschmid & Sarah Choi – Final Project: Pittsburgh Ambience

final project: pittsburgh ambience

Our project’s canvas is too big for wordpress, so we are uploading the zip file and instructions to acess it. 

Click the link to the google drive to find the zip file. Download the zip file to find the sketch.js file “finalproject.js”  as well as the html file “finalproject.html” and the sound files. Because the project is outside of wordpress and there is a sound aspect, the project needs to be opened on the local host from your server, so the instructions must be followed bellow…

  1.  Open a Terminal in OS X or a command window (cmd) in Windows.
  2. Change your current directory to the directory you want to serve: Type cd path-to-your-directory (ex. cd Desktop/104final )
  3. Type in Terminal:
    python -m SimpleHTTPServerOr if you are using Python 3, type:
    python -m http.server
  4. Visit the URL http://localhost:8000 in your browser to test your sketch.

How it works:

Using your mouse, scroll through the four different neighborhoods presented in illustrations. 

Click on the music button to hear the song we chose to represent the ambience of the area and click on the pause button to stop the song.

Click on the different buttons for the cafes and restaurants shown to see a photo of the location, a description, and a link to the website. 

For our final project, we wanted to portray the distinct atmospheres of different neighborhoods in Pittsburgh. As two students who weren’t familiar with Pittsburgh before Carnegie Mellon, we took the initiative to venture out and explore the different areas and what Pittsburgh has to offer. As people who are interested in immersing and inspiring ourselves through our surroundings, we wanted to introduce our favorite places to other students. Because music is also a very big part of our everyday lives, we wanted to complete the Pittsburgh ambiance by selecting specific songs that we felt captured in each area the best. 

We really enjoyed the interactive visual aspect of this project. In the beginning, we brainstormed ways to depict our shared interests and goals through a project, and we felt that this achieved exactly what we envisioned. Making 2D objects into an interactive platform, we saw the potential to incorporate layers of our project into future uses. Our favorite part of the project was probably the music and design aspect of it. We had a lot of fun planning and collaborating together.  Below, we have attached a video and screenshots of each different area included in our project.

CJ Walsh – Final Project

sketch

// CJ Walsh
// cjwalsh@andrew.cmu.edu
// Section D
// Final Project

// creating variables for turtles
var trl;
var trl2;
var trl3;
var trl4;
var trl5;

function setup() {
 createCanvas(600, 600);
 frameRate(4); // giving a speed to the movement of the lines
 
}

function draw() {
	background(0);

	
	// drawing the three lines and looping them 
	for (var y = 20; y < height + 10; y += 50) {
		for (var x = 10; x < width + 10; x += 50) {

			
			trl = makeTurtle(x, y -5);
			trl.setColor('red');
			trl.forward(random(2, 15)); // random lengths to create texture
			trl.penUp(); // pulling pen up to move without mark making 
			trl.forward(10);
			trl.penDown();
			trl.forward(random(4, 10));

			
			trl2 = makeTurtle(x, y);
			trl2.setColor('red');
			trl2.forward(random(2, 20));
			trl2.penUp();
			trl2.forward(10);
			trl2.penDown();
			trl2.forward(random(4, 10));

			trl3 = makeTurtle(x, y + 5);
			trl3.setColor('red');
			trl3.forward(random(2, 20));
			trl3.penUp();
			trl3.forward(10);
			trl3.penDown();
			trl3.forward(random(4, 10));


			
		}
	}
	
	//noLoop();

}

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

For my project I wanted to create a series of generated textiles using loops and turtles. Each piece is an experiment with shape, repetition, color, placement and movement. Three are static pieces and three have movement. I really enjoyed creating each one, and they range in work time and difficulty of production. Even though some of them seem simple, each is carefully considered and planned out to get the effect that I wanted. Textile #6 is one of my favorites because it is a version of a precedent project that I wrote about in a Looking Outwards post. In my randomness post, I really enjoyed Georg Nees piece so #6 is my own version using randomness and movement to create a fun generative sketch. Overall I am happy with the outcome and look forward to using what I learned in this class to continue to generate fun imagery. A zip file is attached below containing all of the code for the 6 images.

Final Project

sketch

// CJ Walsh
// cjwalsh@andrew.cmu.edu
// Section D
// Final Project

var trl; // variable for turtle

function setup() {
    createCanvas(600, 600);
    
    frameRate(8);
    
}

function draw() {
	background(220);

	//grid of turtles
	for (var y = 10; y < height + 10; y += 50) {
		for (var x = 10; x < width + 10; x += 50) {
			trl = makeTurtle(x, y); // make turtle

			// random generate to create fun sketch movement quality
			trl.right(random(2, 60));
			trl.forward(random(4, 16));
			trl.left(random(20, 120));
			trl.forward(random(4, 10));
			trl.right(random(60, 145));
			trl.forward(10);
			trl.right(random(40, 227));
			trl.forward(random(5, 15));
			
		}
	}
	
	


}

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

Included below are some process shots of playing with color and pattern:

Lanna Lang – Final Project

lannal-project-12

Download the zip file and run the index HTML. I could not upload my sketch onto WordPress because my canvas size is 1000 x 1000. Read below to see how to access my project.

Instructions on accessing the project: To view this project, you must download the zip file attached above. Once the file is downloaded, a zip file called “lannal-project-12” should appear. Open the folder and then open “sketch.js” to access the code behind it.

Because this is outside of WordPress and my code has implemented sound, you have to create a local server to have the sound file playback to successfully view the project, so follow the instructions below (taken from Lab Week 10).

  1. Open a Terminal in OS X or a command window (cmd) in Windows.
  2. Change your current directory to the directory you want to serve: Type cd path-to-your-directory (ex. cd Desktop/104final )
  3. Type in Terminal:
    python -m SimpleHTTPServerOr if you are using Python 3, type:
    python -m http.server
  4. Visit the URL http://localhost:8000 in your browser to test your sketch.

My project is a rendition of Patatap, but with global warming and the climate crisis as the concept.

How it works:

Press the enter key to change between color schemes – there are 5 different schemes which go from cool colors to warm colors – symbolizing global warming and rising temperatures.

Press any arrow key to play corresponding graphics and sounds:

The up arrow key = the decrease and destruction of coral reefs

The down arrow key = the transformation of ocean bubbles to pollution smoke

The left arrow key = the exponential increase in the consumption of plastic water bottles and the amount of plastic in the oceans and our waste.

The right arrow key = the rising ocean water level due to the climate crisis.

In my body of work as an artist, I explore many concepts, but environmental awareness is one of the concepts I revisit pretty often. I was very intrigued by the Patatap project when we were introduced to it in a lecture, and I wanted to create my own version of it, combining with a discussion of the climate crisis. Coding this project in these past 2 weeks was a good challenge for me as it combined all the topics we learned throughout the semester: arrays, objects, for loops, if statements, images, sounds, noise, etc. I really want to expand on this project later and continue working on this, such as making it its own website, maybe as another project for another class.

As global warming progresses there is more consumption of plastic water bottles and more plastic in the ocean (depicted as the increase in bottles form a wave).

As global warming progresses, these ocean bubbles transform into pollution smoke from industrial technology.

As global warming progresses, the coral reefs in the oceans are disappearing and their numbers are decreasing.

As global warming progresses, the water level of the oceans are rising.

A screen recording of me interacting with the sketch. There was supposed to be sound but I think something went wrong with the screen recording, so this is just to show how the interaction works.

Monica Chang – Final Project

Monica Chang – Final Project

I had to upload through a zip file because my canvas size was 650 in width(a little over the max size for WordPress). Thus, continue reading to learn how to access the game.

Instructions on accessing the game: To begin this game, you must download the zip file attached above. Once the file is downloaded, a zip file called “Monica-Chang-Final-Project” should appear. Open the file and a folder called “104final” will appear; then, open “sketch.js” to access the code behind it.

Because this is outside of WordPress and my code has implemented sound, it is crucial to trigger the sound file playback and open the game by following the instructions below(taken from Lab Week 10).

  1. Open a Terminal in OS X or a command window (cmd) in Windows.
  2. Change your current directory to the directory you want to serve:Type cd path-to-your-directory (ex. cd Desktop/104final )
  3. Type in Terminal:
    python -m SimpleHTTPServerOr if you are using Python 3, type:
    python -m http.server
  4. Visit the URL http://localhost:8000 in your browser to test your sketch.

Description: For this final project, I developed a game in which the player or virtual “photographer” will be responsible for capturing pictures of the flying birds with the virtual camera by pressing the SPACEBAR. The problem is the birds fly by way too fast but the players are required to capture enough pictures to reach “captured” score of 100. There are no losing points in this game.

Another element that I implemented is changing the weather. Since the initial weather is gloomy and raining, the player may press his/her mouse to change the screen to a happy, blue sky. The field audio/sounds will change accordingly.

Default Screen – gloomy, rainy sky
When mouse pressed, screen changes to blue sky!
Bird – the player must press SPACEBAR to capture these.

Lauren Park – Final Project

sketch

//Lauren Park
//ljpark@andrew.cmu.edu
//Section D
//Final Project

//initialize sound variables
var love;

//load sound file
function preload(){
love = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/jasmine.wav");
}

function setup() {
  createCanvas(500, 400);
  love.loop();
  
  beat = new p5.Amplitude();
  beat.setInput(love);
}

function draw() {
  
  //abstract curves
  frameRate(1.65);
  background(50, 155, random(255), 140);
  //create the vertices curves
  var numCurvePoints = 10;
  beginShape();
  for (var i = 0; i < numCurvePoints; i++) {
    curveVertex(random(30, width - 20), random(100, height - 10));
  }
  endShape();

  stroke(random(215));
  strokeWeight(0);
  fill(254, 193, 255, 140); 
  var numCurvePoints = 12;
  beginShape();
  for (var i = 0; i < numCurvePoints; i++) {
    curveVertex(random(30, width - 20), random(95, height - 20));
  }
  endShape();

  //background lines
  for (var row = 0; row <= width; row = row + 70) {
    for (var col = 0; col <= height; col = col + 60) {
      fill(80);
      rect(random(row), random(col), 5, 45);
      fill(200);
      rect(random(row), random(col), 4, 30);
    }
  }
  
  //hoodie fill colors
  fill('#4BA680');
  ellipse(231, 300, 90, 200);
  ellipse(300, 305, 90, 200);
  ellipse(270, 390, 195, 180);
  ellipse(280, 265, 90, 100);

  //back hair
  fill('#8A4B21');
  ellipse(223, 147, 30, 30);
  ellipse(218, 160, 20, 30);
  ellipse(220, 205, 25, 30);
  ellipse(209, 227, 30, 31);
  ellipse(210, 221, 20, 30);
  strokeWeight(2);
  stroke('#4D2A12');
  fill('#8A4B21');
  curve(230, 100, 210, 137, 209, 170, 230, 150); 
  curve(230, 100, 213, 190, 187, 270, 300, 400); 

  //hoodie collar
  strokeWeight(3);
  stroke('#316E55');
  fill('#4BA680');
  beginShape();
  curveVertex(230, 215);
  curveVertex(256, 222);
  curveVertex(225, 209);
  curveVertex(245, 231);
  curveVertex(258, 191);
  endShape();
  
  //rightcollar
  beginShape();
  curveVertex(258, 171);
  curveVertex(252, 221);
  curveVertex(300, 205);
  curveVertex(371, 215);
  endShape();

  //hoodie left arm
  beginShape();
  curveVertex(271, 215);
  curveVertex(230, 218);
  curveVertex(193, 250);
  curveVertex(170, 400);
  curveVertex(193, 250);
  endShape();

  //right arm
  strokeWeight(3);
  stroke('#316E55');
  fill('#4BA680');
  beginShape();
  curveVertex(313, 223);
  curveVertex(300, 230);
  curveVertex(340, 250);
  curveVertex(370, 400);
  curveVertex(340, 250);
  endShape();

  //hood
  beginShape();
  curveVertex(205, 230);
  curveVertex(300, 205);
  curveVertex(333, 213);
  curveVertex(335, 241);
  curveVertex(300, 210);
  endShape();
  
  //inner arms shadow
  curve(230, 280, 215, 275, 205, 400, 150, 540); 
  curve(320, 250, 310, 280, 325, 400, 280, 200); 

  //face
  fill('#DAA67B');
  strokeWeight(1.5);
  stroke('#AD8361');
  ellipse(250, 175, 80, 88);

  //outer hair
  noStroke();
  fill('#8A4B21');
  ellipse(285, 200, 30, 175);
  ellipse(265, 167, 20, 40);
  ellipse(270, 190, 20, 60);
  ellipse(282, 280, 10, 30);
  strokeWeight(2);
  stroke('#4D2A12');
  fill('#8A4B21');
  
  beginShape();
  curveVertex(250, 463);
  curveVertex(290, 163);
  curveVertex(305, 270);
  curveVertex(280, 300);
  curveVertex(303, 300);
  endShape();

  beginShape();
  curveVertex(280, 300);
  curveVertex(280, 300);
  curveVertex(250, 146);
  curveVertex(200, 346);
  endShape();

  //hat
  fill(70);
  stroke(0);
  beginShape();
  curveVertex(210, 137);
  curveVertex(295, 163);
  curveVertex(210, 137);
  curveVertex(215, 125);
  curveVertex(295, 163);
  curveVertex(290, 147);
  curveVertex(215, 125);
  curveVertex(290, 147);
  endShape();

  beginShape();
  curveVertex(220, 214);
  curveVertex(215, 124);
  curveVertex(290, 110);
  curveVertex(296, 150);
  curveVertex(296, 150);
  endShape();

  //heart beat to song
  mood = beat.getLevel();
  fill(0);
  ellipse(260,300,25+mood*100, 30+mood*100);
  ellipse(280,300,25+mood*100, 30+mood*100);
  triangle(251, 309, 289, 309, 270, 330);
  ellipse(255, 317+mood*100, 3, 15);
  ellipse(277, 323+mood*100, 2, 12);
  ellipse(263, 337+mood*100, 2, 12);
  ellipse(281, 340+mood*100, 2, 14);
  ellipse(269, 353+mood*100, 2, 17);
  ellipse(261, 371+mood*100, 2, 17);
  ellipse(278, 390+mood*100, 2, 20);
  
  //ear
  stroke('#AD8361');
  fill('#DAA67B');
  curve(230, 197, 275, 170, 277, 182, 210, 230);  
  curve(260, 197, 275, 170, 277, 182, 300, 250);

  //earring
  stroke(210);
  curve(250, 87, 278, 178, 280, 179, 250, 230); 
  
  //hood string
  noStroke();
  fill(255);
  ellipse(245, 254, 3, 40);
  ellipse(247, 265, 4, 20);
  
  stroke(200);
  fill(255);
  ellipse(247, 235, 4.5, 4.5);
  curve(300, 180, 245, 235, 245, 275, 240, 300);
  curve(200, 300, 245, 275, 250, 275, 250, 250);
  curve(300, 180, 249.5, 235, 249.5, 275, 240, 300);

}

For this project, I really wanted to use a song file and have different elements and shapes move or change in rhythm to the song. I wanted to focus on the visuals and concept that also sync not only in beat but also in theme to the song. By incorporating this moody love song, I tried to capture the vibe of the music by creating a character and abstract forms in the background and by creating the dripping or bleeding black heart that beats to this song. For the color scheme and moving elements in the background, it is inspired by actual albums of the artists who sang this song. Overall, it was very challenging to properly load the sound and play around with the amplitude so that the heart beats, but it was a very fun piece that showcases some of my interests.