## 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!
``````//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 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');
noLoop();
}``````

## Shannon Ha – Final Project

``````//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 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!)

## Min Ji Kim Kim & Kristine Kim – Final Project

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;

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;

for (var i = 0; i < foodLinks.length; i++) { // push urls into array
}

for (var i = 0; i < animalLinks.length; i++) { // push urls into array
}

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
}

for (var i = 0; i < peopleLinks.length; i++) { // push urls into array
}

}

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

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() {
}
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();
}
}

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(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) {
}
}

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

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

// ------------------------------ 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() {
var turquoise = color(16, 157, 172);
var navy = color(1,84,134);

//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
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);

}

// -------------------------- 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
textSize(20);
fill(0)
if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
fill('#27AEE3'); // change color if mouse is hovering over
}
}

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

``````/* 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
var img = "https://i.imgur.com/pJRSO5b.jpg";
}

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

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

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

``````// 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;}
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 SimpleHTTPServer`Or 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.

## 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 SimpleHTTPServer`Or 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.

## Lauren Park – Final Project

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

//initialize sound variables
var love;

}

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();

curve(230, 280, 215, 275, 205, 400, 150, 540);
curve(320, 250, 310, 280, 325, 400, 280, 200);

//face
fill('#DAA67B');
strokeWeight(1.5);
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
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.