My project is a simple, interactive keyboard. They keys light up when you press them, and I included harmonics to make it sound more like a real piano.
Press on a key and the note will sound! You can click and drag in order to play more than one note quickly.
To run:
1. Download the file “sjahania-final-project”
2. Open “index.html” in your browser
3. Play away!
I did not embed the code because of the pixel size as well as multiple files the code loads. This is my final project in a .zip file. It includes multiple photos, but more importantly a font file that I couldn’t link in any way other than the file.
For this project, I want to visualize a set of data from NASA about temperature change and Antarctic mass loss. Instead of just looking at statistical graphs, I chose to investigate from a image perspective that the audience may get a better connection. I found out that although we all know what global warming is, we don’t really connect them to ourselves, thus, I create a direct connection between our daily necessities (food and water) and the changes. The project is divided to two parts, one is to visualize the relationship between the loss of wheat and increasing temperature, the second part is to visualize the relationship between the loss of water and the decreasing antarctic mass. For our knowledge, there are applications of recursion, use of objects, for loops, etc. The data are all transformed with equations calculated from certain patterns and unit comparison. The project on wordpress is not displayed correctly and very slow, for the full project, please download the linked zip file (below are both the original and the scaled) and see it chrome.
//Selina Lee
//Section C
//selinal@andrew.cmu.edu
//Final Project
var mapPic;//variable for image of map
var backPic; //background picture (collage of running in Pittsburgh)
var skiboStart; //turtle functions at different start poitns
//this one starts in front of skibo
var ovalStart; //this one occurs after reaching the schenley oval
var scaleX = 0.4; //scale down width wise from original canvas which is
// 480 / 1200
var scaleY = 0.6; //scale down height wise from original canvas whic is
// 480 / 800
//arrays containing the points to draw run routes with turtle functions
//route titled beechwood (x and y points placed into arrays)
var beechX = [760, 789, 778, 808, 859, 895, 968, 980, 1014, 984, 1024, 950,
809, 737, 733];
var beechY = [277, 262, 244, 225, 221, 242, 242, 325, 324, 175, 111, 125, 189,
195, 237];
//route titled the point
var pointX = [740, 726, 719, 697, 687, 695, 677, 632, 592, 568, 560, 464, 402,
268, 219, 35, 38, 61, 104, 148, 154, 201, 162, 183, 234, 418, 463, 502, 602,
672, 695, 732, 722, 735, 733, 745];
var pointY = [295, 298, 312, 315, 327, 353, 372, 378, 365, 389, 418, 361, 356,
379, 370, 279, 262, 258, 242, 226, 255, 244, 314, 328, 327, 338, 352, 355, 261,
235, 236, 234, 258, 261, 270, 275];
//route titled trader joe's
var traderX = [760, 789, 778, 808, 859, 859, 968, 1059, 1064, 1062, 1098, 964,
943, 718, 731, 737, 733, 744, 734];
var traderY = [277, 262, 244, 225, 221, 242, 242, 221, 212, 204, 138, 24, 12,
103, 147, 194, 234, 239, 270];
//route titled tranquil
var tranquilX = [760, 789, 778, 808, 859, 895, 968, 980, 1049, 1087, 1089, 1111,
1126, 1138, 1161, 1174, 1169, 1178, 1170, 1178, 1160, 1159, 1139, 1068, 1060,
1059, 1139, 1068, 1060, 1059, 968, 895, 859, 808, 778];
var tranquilY = [277, 262, 244, 225, 221, 242, 242, 325, 324, 338, 345, 343,
354, 346, 362, 350, 339, 322, 301, 287, 260, 234, 217, 191, 208, 218, 245, 242,
221, 225, 244];
//warmup route to work out location titled one-eight
var eightX = [743, 732, 715, 700, 686, 695, 687, 678, 687, 674, 673, 677, 671,
683, 683, 692, 759, 782, 787, 778, 761, 721];
var eightY = [291, 295, 310, 315, 328, 349, 365, 379, 394, 397, 406, 411, 421,
436, 444, 449, 403, 398, 392, 385, 391, 417];
//schenley oval route
var ovalX = [714, 720, 737, 746, 757, 764, 760, 751, 741, 720, 715];
var ovalY = [411, 415, 407, 396, 393, 389, 381, 379, 379, 395, 406];
//regular cool down route from oval
var coolX = [737, 778, 789, 794, 801, 789, 776, 733, 719, 709, 709, 713, 714,
723, 740, 746];
var coolY = [408, 387, 387, 392, 386, 378, 374, 358, 355, 342, 328, 321, 311,
308, 296, 274];
//other cool down route from oval called ten minute
var tenX = [724, 696, 684, 689, 688, 704, 690, 712, 707, 693, 696, 690, 694,
724, 731, 741];
var tenY = [420, 439, 426, 416, 407, 404, 385, 379, 372, 363, 351, 326, 318,
306, 294, 293];
//run titled southside
var southX = [745, 730, 740, 727, 673, 602, 499, 465, 418, 407, 409, 431, 477,
486, 496, 523, 576, 602, 632, 680, 675, 682, 686, 699, 761, 782, 795, 784, 733,
712, 694, 691, 694, 724, 731, 739];
var southY = [274, 271, 235, 233, 236, 262, 352, 354, 335, 417, 454, 460, 472,
463, 455, 477, 437, 460, 469, 460, 443, 435, 448, 448, 400, 395, 382, 376, 357,
350, 340, 323, 315, 304, 293, 293];
var counter = 0;// counter variable to count down differet routes shown
var backColR = 0; //background R value variable
var backColG = 0; //background G value variable
var backColB = 0; //background B value variable
var backColT = 270; //background opacity value
var colorArr = []; //empty array to contain color and placement creations
//see function fillInColorArray
var colors = ["black", "yellow"]; //colors to take
function preload() {
mapPic = loadImage("https://i.imgur.com/zIVTSXM.jpg"); //map preload
backPic = loadImage("https://i.imgur.com/vzuo6YG.jpg"); //background image
//preload
}
function setup() {
createCanvas(480, 480);
image(backPic, 0, 0, map.width, map.height);//drawing map picture
//used early on in project to find array points
/*if(mouseIsPressed) {
print(mouseX, mouseY);
}*/
skiboStart = makeTurtle(747 * scaleX, 274 * scaleY); //draws turtles that
//start and end at Skibo
ovalStart = makeTurtle(712 * scaleX, 410 * scaleY); // turtles that start at
//Schenley Oval
//I missed the criteria to scale the canvas to 480, so I used the scale
//variable to reduce the size of my points
for(var i = 0; i < beechX.length; i++) {
beechX[i] *= scaleX;
beechY[i] *= scaleY;
}
for(var i = 0; i < pointX.length; i++) {
pointX[i] *= scaleX;
pointY[i] *= scaleY;
}
for(var i = 0; i < traderX.length; i++) {
traderX[i] *= scaleX;
traderY[i] *= scaleY;
}
for(var i = 0; i < tranquilX.length; i++) {
tranquilX[i] *= scaleX;
tranquilY[i] *= scaleY;
}
for(var i = 0; i < ovalX.length; i++) {
ovalX[i] *= scaleX;
ovalY[i] *= scaleY;
}
for(var i = 0; i < eightX.length; i++) {
eightX[i] *= scaleX;
eightY[i] *= scaleY;
}
for(var i = 0; i < coolX.length; i++) {
coolX[i] *= scaleX;
coolY[i] *= scaleY;
}
for(var i = 0; i < tenX.length; i++) {
tenX[i] *= scaleX;
tenY[i] *= scaleY;
}
for(var i = 0; i < southX.length; i++) {
southX[i] *= scaleX;
southY[i] *= scaleY;
}
}
function mouseClicked() {
counter++; //when mouse is clicked, create a counter to increment
//every time
backColT = backColT - 20; //with every mouse click, the background
//transparency gets more opaque
}
function draw() {
image(backPic, 0, 0, map.width, map.height);//underlying image to be
//revealed
background(backColR, backColG, backColB, backColT); //background color
//based on variable values
fill(255); //prints directions on how to interact with piece ==>
//continuous clicking reveals the different routes and visuals and black
//and white background
text("Click on the canvas to reveal my running log in Pittsburgh!", 30,
30);
if(mouseIsPressed) {
print(mouseX, mouseY); //helps find position of mouse on map to draw
//turtle before translation
}
translate(-8, 50); //center the marks with these units
//BEECHWOOD ROUTE: 5 MILES
if (counter == 0 || counter >= 9) { //the start of the counter and when
//the mouse clicks through all slides, this will be shown
for(var i = 0; i < beechX.length; i++) { //iterate through route
//arrays to get points. The array length should be the same for
//X and Y because I manually clicked on the screen to get place
//numbers
skiboStart.setColor(color(255, 0, 255)); //magenta turtle
skiboStart.penDown(); //start drawing
skiboStart.goto(beechX[i], beechY[i]); //drawing beechwood route
//based on points in beechX and beechY array
skiboStart.penUp();//stop drawing
noStroke();
fill(150, 0, 255, 80); //light, see-through, purple rectangles
//these rectangles are drawn based on the values of the points
//and the differences of the points on the path
rect(beechX[i - 1], beechY[i - 1], beechX[i - 1] - beechX[i],
beechY[i - 1] - beechY[i]);
rect(beechX[i], beechY[i], beechX[i] - beechX[i],
beechY[i - 1] - beechY[i]);
rect(beechX[i - 1], beechY[i], beechX[i] - beechX[i - 1],
beechY[i] - beechY[i - 1]);
rect(beechX[i], beechY[i], beechX[i] - beechX[i - 1],
beechY[i] - beechY[i - 1]);
}
}
//THE POINT: 9.25 MILES
fillInColorArr(0); //see function fillInColorArr
//this starts the function at place 0
if (counter == 1 || counter >= 9) { //next shown visual from counter
//(all visuals are shown at the end of the list)
for(var i = 0; i < pointX.length; i++) {
backColB = 255; //background will be light blue
backColG = 200;
backColR = 100;
skiboStart.setColor(colorArr[i]); //the color of each
//turtle move is based on fillInColorArr (while it
//iterates, a value is placed into the color function out
//of the colorArr array)
skiboStart.setWeight(5); //thicker line
skiboStart.penDown();
skiboStart.goto(pointX[i], pointY[i]);
skiboStart.penUp();
noFill();
stroke(255, 255, 0); //yellow thin lines
strokeWeight(1);
beginShape(); //curves based off of Pittsburgh bridges
//and the curve vertex control points are based on
//position between selected points so that some
//abstraction is visualized from the data
curveVertex(pointX[i], pointY[i] + 30);
curveVertex(pointX[i], pointY[i] + 30);
curveVertex((pointX[i] + pointX[i - 1]) / 2,
(pointY[i - 1] + pointY[i]) / 4);
curveVertex((pointX[i - 1] + pointX[i]) / 2,
(pointY[i - 1] + pointY[i]) / 4);
curveVertex(pointX[i - 1], pointY[i - 1] + 30);
curveVertex(pointX[i - 1], pointY[i - 1] + 30);
endShape();
}
}
//TRADER JOE'S: 5.5 MILES
if(counter == 2 || counter >= 9) {
for(var i = 0; i < traderX.length; i++) {
backColR = 255; //light purple background
backColG = 120;
backColB = 200;
skiboStart.setColor(color(200, 255, 0)); //green-yellow
skiboStart.setWeight(1)
skiboStart.penDown();
skiboStart.goto(traderX[i], traderY[i]);
skiboStart.penUp();
for(var j = 0; j < 5; j++) { //make 5 of this command
noFill();
strokeWeight(2);
stroke(255, 200, 0); //orange bullseye design at
//each turtle point
ellipse(traderX[i], traderY[i], 10 * j, 10 * j);
}
}
}
//TRANQUIL: 6.3 MILES
if(counter == 3 || counter >= 9) {
for(var i = 0; i < tranquilX.length; i++) {
backColB = 75; //dark blu background
backColG = 0;
backColR = 0;
skiboStart.setColor(color(200, 255, 0)); //green-yellow
skiboStart.setWeight(1);
skiboStart.goto(tranquilX[i], tranquilY[i]);
skiboStart.penUp();
fill(255, 230, 0, 60); //see-through orange-yellow
//circles drawn at each tranquil turtle point
//one on top of the other like an eye
ellipse(tranquilX[i], tranquilY[i], 20, 20);
ellipse(tranquilX[i], tranquilY[i], 8, 8);
fill(150, 255, 100, 100); //see-through green
noStroke();
//these ellipses were drawn towards the top right of the turtle
//route as a conglomeration
ellipse(tranquilX[i] + 60, tranquilY[i] - 20, 50, 50);
fill(100, 255, 220, 100); //see-through blue-green
ellipse(tranquilX[i] + 50, tranquilY[i] - 40, 40, 40);
}
}
//ONE EIGHT- WARMUP ROUTE TO SCHENLEY OVAL VIA THE BRIDAL PATH: 1.8 MILES
if(counter == 4 || counter >= 9) {
for(var i = 0; i < eightX.length; i++) {
backColR = 255; //yellow background
backColG = 255;
backColB = 0;
skiboStart.setColor(color(255, 0, 0)); //red turtle
skiboStart.setWeight(1);
skiboStart.penDown();
skiboStart.goto(eightX[i], eightY[i]);
skiboStart.penUp();
fill(255, 50, 75, 20); //fill transparent red
var maxX = max(eightX); //maximum value in x value array
var minX = min(eightX); //minimum value in x value array
var midX = (maxX + minX) / 2; //average of max and min value in
//x array
var maxY = max(eightY); //maximum value in y array
var minY = min(eightY); //minimum value in y array
var midY = (maxY + minY) / 2; //avverage of max and min value in
//y array
var curveX1; //first control x value point
var curveY1; //first control y value point
var curveX2; //control two x value point
var curveY2; //control two y value point
if(eightX[i] < midX) { //if the turtle point is to the left of the
//"center"
curveX1 = eightX[i] + 10; //if using bezier curve function, the
//first control point goes towards the middle
curveX2 = eightX[i] - 10; //then the second control point goes
//away from the center
} else { //to the right of "center"
curveX1 = eightX[i] - 10; //towards middle
curveX2 = eightX[i] + 10; //away from center
}
if(eightY[i] < midY) { //if the turtle point is to the top of the
//middle of the route loop
curveY1 = eightY[i] + 10; //the first control point goes down
//towards the center
curveY2 = eightY[i] - 10; //second goes away from
} else { //to bottom of route
curveY1 = eightY[i] - 10; //first control point towards middle
curveY2 = eightY[i] + 10; //away from middle
}
stroke(255, 100, 100, 200); //red
strokeWeight(0.5);
//the curves meet at a midpoint
bezier(eightX[i], eightY[i], curveX1, curveY1, curveX2, curveY2,
midX, midY);
bezier(eightX[i], eightY[i], curveX2, curveY2, curveX1, curveY1,
midX, midY);
}
}
//OVAL LOOP = .625 MILES
if(counter == 5 || counter >= 9) {
for(var i = 0; i < ovalX.length; i++) {
stroke(255, 100, 255, 70); //light magenta
strokeWeight(40); //very thick line
//used a line so the turtle function does not get confused
//and hide the movement created visually.
//this line makes the same route as the turtle function
line(ovalX[i], ovalY[i], ovalX[i - 1], ovalY[i - 1]);
stroke(100, 150, 255, 120); //overlapping light blue lines
//on top of oval lap so you can still see the purple underneath
strokeWeight(15);
line(ovalX[i - 1], ovalY[i - 1], ovalX[i], ovalY[i]);
stroke(255, 200, 0); //orange turtle on top of laps
strokeWeight(3);
line(ovalX[i], ovalY[i], ovalX[i - 1], ovalY[i - 1]);
}
}
//COOL DOWN ROUTE FROM SCHENLEY OVAL VIA PANTHER HOLLOW TRAIL: 1.3 MILES
if(counter == 6 || counter >= 9) {
for(var i = 0; i < coolX.length; i++) {
ovalStart.setColor(color(0, 100, 255));
ovalStart.setWeight(1);
ovalStart.penDown();
ovalStart.goto(coolX[i], coolY[i]);
ovalStart.penUp();
fill(100, 150, 255, 30);
var maxX = max(coolX); //maximum value in x value array
var minX = min(coolX); //minimum value in x value array
var midX = (maxX + minX) / 2; //average of max and min value in
//x array
var maxY = max(coolY); //maximum value in y array
var minY = min(coolY); //minimum value in y array
var midY = (maxY + minY) / 2; //avverage of max and min value in
//y array
var curveX1; //first control x value point
var curveY1; //first control y value point
var curveX2; //control two x value point
var curveY2; //control two y value point
if(coolX[i] < midX) { //if the turtle point is to the left of the
//"center"
curveX1 = coolX[i] + 10; //if using bezier curve function, the
//first control point goes towards the middle
curveX2 = coolX[i] - 10; //then the second control point goes
//away from the center
} else { //to the right of "center"
curveX1 = coolX[i] - 10; //towards middle
curveX2 = coolX[i] + 10; //away from center
}
if(coolY[i] < midY) { //if the turtle point is to the top of the
//middle of the route loop
curveY1 = coolY[i] + 10; //the first control point goes down
//towards the center
curveY2 = coolY[i] - 10; //second goes away from
} else { //to bottom of route
curveY1 = coolY[i] - 10; //first control point towards middle
curveY2 = coolY[i] + 10; //away from middle
}
stroke(0, 200, 255, 200);
strokeWeight(.5);
bezier(coolX[i], coolY[i], curveX1, curveY1, curveX2, curveY2, midX,
midY);
bezier(coolX[i], coolY[i], curveX2, curveY2, curveX1, curveY1, midX,
midY);
}
}
//TEN MINUTE COOL DOWN: 1.1 MILES
if(counter == 7 || counter >= 9) {
for(var i = 0; i < tenX.length; i++) {
ovalStart.setColor(color(0, 150, 255));
ovalStart.penDown();
ovalStart.goto(tenX[i], tenY[i]);
ovalStart.penUp();
fill(20, 20, 255, 30);
var maxX = max(tenX); //maximum value in x value array
var minX = min(tenX); //minimum value in x value array
var midX = (maxX + minX) / 2; //average of max and min value in
//x array
var maxY = max(tenY); //maximum value in y array
var minY = min(tenY); //minimum value in y array
var midY = (maxY + minY) / 2; //avverage of max and min value in
//y array
var curveX1; //first control x value point
var curveY1; //first control y value point
var curveX2; //control two x value point
var curveY2; //control two y value point
if(tenX[i] < midX) { //if the turtle point is to the left of the
//"center"
curveX1 = tenX[i] + 10; //if using bezier curve function, the
//first control point goes towards the middle
curveX2 = tenX[i] - 10; //then the second control point goes
//away from the center
} else { //to the right of "center"
curveX1 = tenX[i] - 10; //towards middle
curveX2 = tenX[i] + 10; //away from center
}
if(tenY[i] < midY) { //if the turtle point is to the top of the
//middle of the route loop
curveY1 = tenY[i] + 10; //the first control point goes down
//towards the center
curveY2 = tenY[i] - 10; //second goes away from
} else { //to bottom of route
curveY1 = tenY[i] - 10; //first control point towards middle
curveY2 = tenY[i] + 10; //away from middle
}
stroke(0, 150, 255, 200);
strokeWeight(0.5);
bezier(tenX[i], tenY[i], curveX1, curveY1, curveX2, curveY2, midX,
midY);
bezier(tenX[i], tenY[i], curveX2, curveY2, curveX1, curveY1, midX,
midY);
}
}
//SOUTHSIDE: 6.6 MILES
if(counter == 8 || counter >= 9) {
for(var i = 0; i < southX.length; i++) {
backColG = 255; //green background
backColR = 50;
backColB = 100;
skiboStart.setColor(color(255, 0, 255));
skiboStart.penDown();
skiboStart.goto(southX[i], southY[i]);
skiboStart.penUp();
stroke(255, 50, 100); //red
fill(255, 120, 50, 50); //transparent red orange
//lines drawn to create turtle skeleton
line(southX[i], southY[i], southX[i] * 0.9, southY[i] + 20);
line(southX[i] * 0.9, southY[i] + 20, southX[i - 1] * 0.9,
southY[i - 1] + 20);
line(southX[i - 1] * 0.9, southY[i - 1] + 20, southX[i] * 0.85,
southY[i] - 30);
line(southX[i] * 0.85, southY[i] - 30, southX[i - 1] * 0.85,
southY[i - 1] - 30);
line(southX[i] * 0.85, southY[i] - 30, 180, 330);
noStroke();
//triangles based off of parameters to create line skeleton
triangle(southX[i], southY[i], southX[i] * 0.9, southY[i] + 20,
southX[i - 1] * 0.9, southY[i - 1] + 20);
triangle(southX[i - 1] * 0.9, southY[i - 1] + 20,
southX[i] * 0.85, southY[i] - 30, 180, 330)
}
}
}
function fillInColorArr(filledSoFar) { //recursive function to change color
//every action of the turtle
if(filledSoFar == 0) { //if nothing has been drawn yet, leave the array
colorArr = [];
colorArr.push(colors[0]); //push the colors from colors array into
//colorArr so that they can be used and start from 0 which is "black"
var currentFillNumber = filledSoFar + 1; //counts which property has
//recieved a color to use
fillInColorArr(currentFillNumber); //fill in this area with the color
//corresponding to the placement of the turtle in its start point in
//its array
} else if(filledSoFar >= pointX.length) {
return;
} else { //if the paremeters that have been filled so far do not exceed
//the length of the point array, do the same as if nothing has been
//drawn yet and give the parameter a color to use
colorArr.push(colors[filledSoFar % colors.length]);
var currentFillNumber = filledSoFar + 1;
fillInColorArr(currentFillNumber);
}
}
function turtleLeft(d) {
this.angle -= d;
}
function turtleRight(d) {
this.angle += d;
}
function turtleForward(p) {
var rad = radians(this.angle);
var newx = this.x + cos(rad) * p;
var newy = this.y + sin(rad) * p;
this.goto(newx, newy);
}
function turtleBack(p) {
this.forward(-p);
}
function turtlePenDown() {
this.penIsDown = true;
}
function turtlePenUp() {
this.penIsDown = false;
}
function turtleGoTo(x, y) {
if (this.penIsDown) {
stroke(this.color);
strokeWeight(this.weight);
line(this.x, this.y, x, y);
}
this.x = x;
this.y = y;
}
function turtleDistTo(x, y) {
return sqrt(sq(this.x - x) + sq(this.y - y));
}
function turtleAngleTo(x, y) {
var absAngle = degrees(atan2(y - this.y, x - this.x));
var angle = ((absAngle - this.angle) + 360) % 360.0;
return angle;
}
function turtleTurnToward(x, y, d) {
var angle = this.angleTo(x, y);
if (angle < 180) {
this.angle += d;
} else {
this.angle -= d;
}
}
function turtleSetColor(c) {
this.color = c;
}
function turtleSetWeight(w) {
this.weight = w;
}
function turtleFace(angle) {
this.angle = angle;
}
function makeTurtle(tx, ty) {
var turtle = {x: tx, y: ty,
angle: 0.0,
penIsDown: true,
color: color(128),
weight: 1,
left: turtleLeft, right: turtleRight,
forward: turtleForward, back: turtleBack,
penDown: turtlePenDown, penUp: turtlePenUp,
goto: turtleGoTo, angleto: turtleAngleTo,
turnToward: turtleTurnToward,
distanceTo: turtleDistTo, angleTo: turtleAngleTo,
setColor: turtleSetColor, setWeight: turtleSetWeight,
face: turtleFace};
return turtle;
}
For my project I ended up focusing on the feeling of finding an abandoned place (in this case an old barn). You push aside the overgrown weeds and use the odds and ends in that location to construct a story of your own. I drew the little crow myself, and the sky changes with every second in a way that I intended to be a little unsettling.
/* Name | Ai Fukuda
* Course Section | C
* Email | afukuda@andrew.cmu.edu
* Project | Final Project
*/
// ---- VARIABLES FOR FERRIS WHEEL ----
// ferris wheel color
var structureColor = 255; // white
var supportColor = 90; // grey
// speed
var speed = 160;
// ferris wheel dimensions
// note: counting circles from most inner to outermost
var centerX; // center of ferris wheel (x-coordinate)
var centerY; // center of ferris wheel (y-coordinate)
var radiusC1; // radius of circle 1
var radiusC2; // radius of circle 2
var radiusC3; // radius of circle 3 (carrying the passenger cars)
var radiusC3R; // radius of circle 3 (passenger cars rotate on it)
var radiusCar; // radius of passenger car
var radiusBolt; // radius of bolt on passenger car (detail)
var base; // base of ferris wheel
var baseW; // width of base of ferris wheel
var baseH; // height of base of ferris wheel
// ---- END OF VARIABLES FOR FERRIS WHEEL ----
// ---- VARIABLES FOR FIREWORK ----
var fireworks = [];
var particles = [];
var gravity = 0.7;
// ---- END OF VARIABLES FOR FIREWORK ----
function setup() {
createCanvas(480, 480);
frameRate(10);
strokeWeight(1);
stroke(255);
// ---- FERRIS WHEEL ----
// define ferris wheel dimensions
var h = height/1.75; // scaling ferris wheel (overall)
centerX = h/2.2;
centerY = h - h/10;
radiusC1 = h/11;
radiusC2 = h/2.8;
radiusC3 = h/1.3;
radiusC3R = h/1.4;
radiusCar = h/10;
radiusBolt = h/60;
base = h/90;
baseW = h/6.5;
baseH = 1.35*h;
// ---- FIREWORK ----
fireworks.push(new Firework());
}
function draw() {
background(36, 69, 140);
background('rgba(0,0,0, 0.1)');
// ---- FERRIS WHEEL ----
// ---- ROTATIONAL ----
// draw grey beam
push();
strokeWeight(1.1);
stroke(supportColor);
noFill();
translate(centerX,centerY);
rotate(frameCount/speed);
for (k = PI/8; k < 2*PI; k += PI/4) {
arc(0, 0, radiusC3, radiusC3, k, k + PI/4, PIE);
}
pop();
// draw white beam & circle
push();
strokeWeight(1);
stroke(structureColor);
noFill();
translate(centerX,centerY);
rotate(frameCount/speed);
for( i=0; i < 2*PI; i += PI/4) {
arc(0, 0, radiusC3, radiusC3, i, i + PI/4, PIE);
}
pop();
// draw passenger car
push();
for (k=0; k<8; k++) {
fill(72,157,206);
arc(radiusC3R/1.85*cos(frameCount/speed + (PI/4*k)) + centerX, radiusC3R/1.85*sin(frameCount/speed + (PI/4*k)) + centerY, radiusCar, radiusCar, 0, PI);
}
fill(supportColor);
translate(centerX,centerY);
rotate(frameCount/speed);
for (j=0; j < 2*PI; j += PI/4) {
ellipse(radiusC3R/1.85*cos(j), radiusC3R/1.85*sin(j), radiusBolt, radiusBolt);
}
pop();
// ---- STATIONARY ----
// circle 1
push();
strokeWeight(1.2);
stroke(structureColor);
fill(supportColor);
ellipse(centerX,centerY,radiusC1,radiusC1);
pop();
// circle 2
push();
strokeWeight(1.2);
stroke(structureColor);
noFill();
ellipse(centerX,centerY,radiusC2,radiusC2);
pop();
// support beam (base & passenger car)
push();
strokeWeight(1);
stroke(structureColor);
fill(0,0,0,0);
for(a=0; a<base; a++) {
triangle(centerX, centerY + a, centerX - baseW + a, baseH, centerX + baseW - a, baseH);
}
pop();
// ---- PIER ----
push();
strokeWeight(5);
stroke(102,51,0);
line(0,baseH, centerX*1.5, baseH);
line(centerX*1.5-10, baseH, centerX*1.5-10, height);
line((centerX*1.5-10)*2/3, baseH, (centerX*1.5-10)*2/3, height);
line((centerX*1.5-10)/3, baseH, (centerX*1.5-10)/3, height);
line(10, baseH, 10, height);
pop();
// ---- OCEAN ----
push();
drawWaveDistant(); // calling wave draw function (foreground)
drawWaveClose(); // calling wave draw function (foreground)
pop();
// ---- FIREWORK ----
push();
translate(width / 2, height);
if (random(1) < 0.10) { // probability of firework release
fireworks.push(new Firework())
}
for (var i = fireworks.length - 1; i >= 0; i--) {
if(fireworks[i].type == "Exploded") {
fireworks.splice(i,1);
}
else {
fireworks[i].draw();
}
}
for (var i = particles.length - 1; i >= 0; i--) {
if(particles[i].position.y > 0 || particles[i].brt <= 0) {
particles.splice(i,1);
}
else {
particles[i].draw();
}
}
pop();
} // ---- END OF DRAW FUNCTION -------
function Firework() {
push();
this.position = createVector(int(random(0, 0+width/3)), 0);
this.speed = createVector(random(-1,1), -random(20,24));
this.sparkler = round(random(0,1)) == 0;
this.fuse = random(-1,1);
fireworkType = int(random (0,6));
switch (fireworkType) {
case 0:
this.type = "simple";
break;
case 1:
this.type = "simple"; // used to be crackle but transformation was messing up geometry
break;
case 2:
this.type = "sparkle";
break;
case 3:
this.type = "double";
break;
case 4:
this.type = "finale";
break;
case 5:
this.type = "shooter";
break;
}
this.draw = function() { // FUNCTION 1
stroke(255);
if (this.fuse < this.speed.y) {
this.explode();
}
if (this.sparkler) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,1);
sparkleSpd = createVector(sparkleVel * cos(sparkleDir), sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(createVector(this.position.x+sparkleSpd.x, this.position.y+sparkleSpd.y), sparkleSpd.copy(),random(3,8), random(255), random(255), random(255));
particles.push(thisSparkle);
}
strokeWeight(2);
stroke(random(255), random(255), random(255));
point(this.position.x,this.position.y);
this.position.add(this.speed);
this.speed.y = this.speed.y + gravity;
} // END OF FUNCTION 1
this.explode = function() { // FUNCTION 2
switch (this.type) {
case "sparkle":
if (this.type == "sparkle") {
for (var i = 0; i < 60; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,3) + random(0,3);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(3,8), random(255), random(255), random(255), "sparkle");
particles.push(thisSparkle);
}
this.type = "Exploded";
}
break;
case "double": {
for (var i = 0; i < 90; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(3,5);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(2,4), random(255), random(255), random(255));
particles.push(thisSparkle);
}
for (var i = 0; i < 10; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,.5);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(2,4), random(255), random(255), random(255));
particles.push(thisSparkle);
}
this.type = "Exploded";
}
break;
case "finale": {
for (var i = 0; i < 500; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,4)+random(0,4);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(3,6), random(255), random(255), random(255));
particles.push(thisSparkle);
}
this.type = "Exploded";
}
break;
case "shooter": {
for (var i = 0; i < 100; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,2)+random(0,3);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(1,3), random(255), random(255), random(255),"shooter");
particles.push(thisSparkle);
}
this.type = "Exploded";
}
break;
case "crackle": {
for (var i = 0; i < 60; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,3) + random(0,3);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(7,10), random(255), random(255), random(255),"crackle");
particles.push(thisSparkle);
}
this.type = "Exploded";
}
break;
default: {
for (var i = 0; i < 100; i++) {
sparkleDir = random(0, TWO_PI);
sparkleVel = random(0,5);
sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(1,3), random(255), random(255), random(255));
particles.push(thisSparkle);
}
this.type = "Exploded";
}
}
} // ---- END OF FUNCTION 2
pop();
}
function Particle(position, speed, fade, r, g, b, type) {
this.position = position.copy();
this.speed = speed.copy();
this.fade = (fade == undefined ? 5 : fade);
this.r = r
this.g = g
this.b = b
this.type = type;
this.brt = 70;
this.burntime=0;
this.draw = function() {
stroke(this.r, this.g, this.b);
newPositionX = this.position.x + log(this.burntime) * 8 * this.speed.x;
newPositionY = this.position.y + log(this.burntime) * 8 * this.speed.y + this.burntime * gravity;
point(newPositionX, newPositionY);
if (this.type == "shooter" & this.burntime > 1) {
line(newPositionX, newPositionY, this.position.x + log(this.burntime-2) * 8 * this.speed.x, this.position.y + log(this.burntime-2) * 8 * this.speed.y + this.burntime * gravity);
(note: I uploaded my final project before the midnight deadline on Friday, however, I noticed that the visuals was not showing up on my post so I tried editing it. It is still not showing up on WordPress when it was originally.)
I changed my idea from my Final Project proposal; initially I wanted to create a storyboard that incorporated fireworks as the final landscape. But I thought a storyboard wasn’t “computational” enough and I wanted to incorporate more concepts learned in class. So that’s why I maintained creating a code for fireworks and incorporated a generative landscape of a ferris wheel. I wrote the fireworks to be multi-colored, and at random fire different styles of fireworks. One thing I struggled with is putting the ferris wheel code and the fireworks code together; the codes would affect the other and therefore I had to use push() and pop() to maintain the stylistic elements of the two components of my final project.
Instructions:
You can click your mouse to move your character, (which changes from dream to dream) – and you change dreams by pressing 1,2,3,4 or 5 on your keyboard. When you’re in dreams you can hover over certain notes to see what that dream is about – (for the green woman you hover over her mouth since there is no note).
//Isadora Krsek
//Ikrsek@andrew.cmu.edu
//Section C
//Final Project(Project 12): "Dreamscape"
var DreamTracker = (0);
//vars scenery
var morningStars = [];
//dream5
var clouds;
var daSky;
var daGround;
var stillMan;
var message5;
var message5X = (145.5);
var message5Y = (298);
//dream4
var bed;
var woman;
var message4;
var message4X = (401);
var message4Y = (75);
//dream3
var building;
var tree;
var moon;
var dirt;
var groundRipples;
var message3;
var message3X = (453);
var message3Y = (330);
//dream2
var spinnyThing;
var lamp;
var touchyGuy;
var LadyWithEyes;
var weirdKid;
var note;
var message2;
var message2X = (405);
var message2Y = (311);
//dream1
var ripples;
var girl;
var papers;
var trees;
var message1;
var message1X = (155);
var message1Y = (252);
//vars for moveable character in dream 5
var kidFramez = []; // An array to store the images
var kidPreX; // The last X location of the character
var kidPreY; // The last Y location of the character
var kidTrack = (0); //to keep kidTrack fo index in array "kidFramez"
var kidX; //the current x location of character
var kidY = 360; //the current y location of character
//vars for moveable fly
var flyFramez = []; // An array to store the images
var flyPreX; // The last X location of the character
var flyPreY; // The last Y location of the character
var flyTrack = (0); //to keep flyTrack fo index in array "flyFramez"
var flyX; //the current x location of character
var flyY; //the current y location of character
//vars for main character
var mainCharFramez = []; // An array to store the images
var mainCharPreX; // The last X location of the character
var mainCharPreY; // The last Y location of the character
var trackMain = (0); //to keep trackMain fo index in array "mainCharFramez"
var mainCharX; //the current x location of character
var mainCharY = 300; //the current y location of character
var targetX; // The X goal, from the user's click
var targetY; // The Y goal, from the user's click
//------let the code begin------------------------------------------
function preload(){
//These URLs are for main character's walk cycle images
var filenames = [];
filenames[0] = "https://i.imgur.com/hi7fjid.png"
filenames[1] = "https://i.imgur.com/DlkJlK6.png"
filenames[2] = "https://i.imgur.com/KQcAqSF.png"
filenames[3] = "https://i.imgur.com/PgWS8Ek.png"
filenames[4] = "https://i.imgur.com/S7T2PoJ.png"
filenames[5] = "https://i.imgur.com/lNmB0Sh.png"
filenames[6] = "https://i.imgur.com/6rRh9JS.png"
filenames[7] = "https://i.imgur.com/lNmB0Sh.png"
//array for the walking cycle
for(var i=0; i < filenames.length; i++) {
mainCharFramez.push(loadImage(filenames[i]));
}
//dream 5 load-ins
clouds = loadImage("https://i.imgur.com/K0WuYlD.png");
daSky = loadImage("https://i.imgur.com/xtFA8AG.png");
daGround = loadImage("https://i.imgur.com/KVhbWTf.png");
stillMan = loadImage("https://i.imgur.com/JRbHrTk.png");
message5 = loadImage("https://i.imgur.com/BuNkluX.png");
//for the walking kid
var filenames2 = [];
filenames2[0] = "https://i.imgur.com/8IEaEQz.png"
filenames2[1] = "https://i.imgur.com/eSKype2.png"
filenames2[2] = "https://i.imgur.com/3Jc1SAO.png"
filenames2[3] = "https://i.imgur.com/xD4OH72.png"
filenames2[4] = "https://i.imgur.com/IT7FXKF.png"
filenames2[5] = "https://i.imgur.com/Syn95Ib.png"
filenames2[6] = "https://i.imgur.com/OHlPsCf.png"
filenames2[7] = "https://i.imgur.com/mJMmHXz.png"
//array for walking
for(var z=0; z < filenames2.length; z++) {
kidFramez.push(loadImage(filenames2[z]));
}
//dream 4 load-ins
bed = loadImage("https://i.imgur.com/0Lc8iQs.png");
woman = loadImage("https://i.imgur.com/bINLqta.png");
message4 = loadImage("https://i.imgur.com/HzVhpA1.png");
//dream 3 load-ins
building = loadImage("https://i.imgur.com/rNIfdQ5.png");
tree = loadImage("https://i.imgur.com/hgvQQsn.png");
moon = loadImage("https://i.imgur.com/b2JY2gV.png");
groundRipples = loadImage("https://i.imgur.com/12PrKWt.png");
dirt = loadImage("https://i.imgur.com/SIdPvf1.png");
message3 = loadImage("https://i.imgur.com/ZqzLPma.png");
//dream 2 load-ins
spinnyThing = loadImage("https://i.imgur.com/VLWV1Ri.png");
lamp = loadImage("https://i.imgur.com/cfaSffr.png");
touchyGuy = loadImage("https://i.imgur.com/bcEIg2B.png");
LadyWithEyes = loadImage("https://i.imgur.com/AHm0VMD.png");
weirdKid = loadImage("https://i.imgur.com/AkoodGn.png");
note = loadImage("https://i.imgur.com/PP7U6Rg.png");
message2 = loadImage("https://i.imgur.com/hbIgCMR.png");
//dream 1 load-ins
trees = loadImage("https://i.imgur.com/WXXHuxn.png");
girl = loadImage("https://i.imgur.com/vI3RID0.png");
papers = loadImage("https://i.imgur.com/gdNlDPK.png");
ripples = loadImage("https://i.imgur.com/DpPYeiP.png");
message1 = loadImage("https://i.imgur.com/VKZcrYA.png");
//These URLs are for fly's cycle
var filenames3 = [];
filenames3[0] = "https://i.imgur.com/MSyp1iw.png"
filenames3[1] = "https://i.imgur.com/lVJeXAA.png"
filenames3[2] = "https://i.imgur.com/GENXp9g.png"
filenames3[3] = "https://i.imgur.com/Th6Ckap.png"
//fly man
for(var q=0; q < filenames3.length; q++) {
flyFramez.push(loadImage(filenames3[q]));
}
}
function setup(){
createCanvas(480, 375);
background(30);
imageMode(CENTER);
frameRate(10);
//Initialize main character postition & target
mainCharPreX = 50;
mainCharPreY = height/2;
targetX = mainCharPreX;
targetY = mainCharPreY;
//initialize fly's position & target
flyPreX = 50;
flyPreY = height/2;
targetX = flyPreX;
targetY = flyPreY;
//initialize fly's position & target
flyPreX = width/2;
flyPreY = height/2;
targetX = flyPreX;
targetY = flyPreY;
//initialize child's position & target
kidPreX = width-50;
kidPreY = 360;
targetX = kidPreX;
targetY = kidPreY;
//stars
//# which allows for new star to appear
StarProb = 30;
//morningStars inital amount
for (var i = 0; i < 22; i++) {
morningStars[i] = new Star(random(width));
}
}
function draw(){
//cycle through dreams by pressing 1,2,3,4, or 5
if (DreamTracker === 0){
Dream1();
} else if (DreamTracker == 1){
Dream2();
} else if (DreamTracker == 2){
Dream3();
} else if (DreamTracker == 3){
Dream4();
} else if (DreamTracker == 4){
Dream5();
}
}
function Dream1(){
push();
scale(.81);
noStroke();
fill(224,196,195);
rect(0,0,width+120,height-100); //sky
drawStars();
noStroke();
fill(192,198,210);
rect(0,height-124,width+120,height); //ground
image(trees,302,215,trees.width*1.2,trees.height*1.2);
image(girl,312,265,girl.width*1.1,girl.height*1.1);
image(ripples,312,219,ripples.width*1.3,ripples.height*1.1);
image(papers,312,255,papers.width*1.2,papers.height*1.2);
pop();
fly();
//hover over note to see message
if(dist(mouseX,mouseY,message1X,message1Y)<10){
image(message1,width/2,height/2);
}
}
function Dream2(){
push();
scale(.81);
noStroke();
mainCharY = 305;
fill(223,212,119);
rect(0,0,width+120,170); //sky
noStroke();
fill(252,207,185);
rect(0,170,width+120,height); //ground
image(spinnyThing,312,225,spinnyThing.width*1.2,spinnyThing.height*1.2);
image(lamp,300,225,lamp.width*1.2,lamp.height*1.2);
image(touchyGuy,312,225,touchyGuy.width*1.2,touchyGuy.height*1.2);
image(LadyWithEyes,312,225, LadyWithEyes.width*1.2, LadyWithEyes.height*1.2);
mainCharWalks();
image(weirdKid,312,225,weirdKid.width*1.2,weirdKid.height*1.2);
image(note,312,225,note.width*1.2,note.height*1.2);
pop();
//hover over note to see message
if(dist(mouseX,mouseY,message2X,message2Y)<15){
image(message2,width/2,height/2);
}
}
function Dream3(){
push();
scale(.75);
mainCharY = 405;
noStroke();
fill(179,132,13);
rect(0,0,width+180,height*2); //sky
fill(51,45,29);
rect(0,height+20,width+180,height*2); //ground
drawStars();
image(dirt,312,235,dirt.width*1.3,dirt.height*1.3);
image(moon,310,250,moon.width*1.3,moon.height*1.3);
image(tree,312,235,tree.width*1.3,tree.height*1.3);
image(groundRipples,312,235,groundRipples.width*1.3,groundRipples.height*1.3);
image(building,312,235,building.width*1.3,building.height*1.3);
image(note,500,352,note.width/1.5,note.height/1.5);
mainCharWalks();
pop();
//hover over note to see message
if(dist(mouseX,mouseY,message3X,message3Y)<10){
image(message3,width/2,height/2);
}
}
function Dream4(){
push();
scale(.75);
noStroke();
fill(32,34,26);
rect(0,0,width,height); //sky
image(bed,320,250,bed.width*1.3,bed.height*1.4)
image(woman,320,250,woman.width*1.3,woman.height*1.4)
pop();
fly();
//hover over note to see message
if(dist(mouseX,mouseY,message4X,message4Y)<10){
image(message4,width/2,height/2);
}
}
function Dream5(){
push();
scale(.75);
//the sky is is comprised of two images
image(daSky,320,210,daSky.width*1.6,daSky.height*1.2)
drawStars();
image(clouds,320,250,clouds.width*1.3,clouds.height*1.4)
image(daGround,320,250,daGround.width*1.3,daGround.height*1.4)
image(stillMan,585,345,stillMan.width*1.05,stillMan.height*1.05)
image(note,90,309,note.width/1.5,note.height/1.5);
image(mainCharFramez[5],40,412)
pop();
push();
scale(.75)
kidWalks();
pop();
//hover over note to see message
if(dist(mouseX,mouseY,message5X,message5Y)<10){
image(message5,width/2,height/2);
}
}
//all of the moveable characters
function fly(){
//--------flying conditions...
var dx = targetX - flyPreX;
var dy = targetY - flyPreY;
var distanceFromCharacterToTarget = sqrt(dx*dx + dy*dy);
//control how fly moves toward target
flyX = lerp(flyPreX,targetX,0.15);
flyY = lerp(flyPreY,targetY,0.15);
//keep looping through the images seamlessly
if (flyTrack >= flyFramez.length){
flyTrack = 0;
}
//--------the actual flying part & more conditions...
if (flyX < flyPreX){
push();
scale(-1,1);//flip image
image(flyFramez[flyTrack],flyX*-1,flyY); //you multiply the X-coordinate by -1 so it walks in the right direction
pop();
}
//otherwise if it's larger, it will be flying right
else if (flyX >= flyPreX){
image(flyFramez[flyTrack],flyX,flyY);
}
//------------------Refresh values...
flyPreX = flyX;
flyPreY = flyY;
//cycle through the walking images
flyTrack = flyTrack + 1
}
function kidWalks(){
//--------walking conditions...
var dx = targetX - kidPreX;
var dy = targetY - kidPreY;
var distanceFromCharacterToTarget = sqrt(dx*dx);
//control how character moves toward target
kidX = lerp(kidPreX,targetX,.15);
//keep looping through the images seamlessly
if (kidTrack >= kidFramez.length){
kidTrack = 0;
}
//--------the actual walking part & more conditions...
//if the current x location is smaller than last x location, walk left
if (distanceFromCharacterToTarget < 15 && kidX < kidPreX){
push();
scale(-1,1);//flip image
image(kidFramez[2],kidX*-1,kidY);
pop();
}
else if(distanceFromCharacterToTarget < 15){
image(kidFramez[2],kidX,kidY);
}
else if(kidX < kidPreX){
push();
scale(-1,1);//flip image
image(kidFramez[kidTrack],kidX*-1,kidY);
pop();
}
//otherwise if larger, walk right
else if(kidX >= kidPreX){
image(kidFramez[kidTrack],kidX,kidY);
}
//------------------Refresh values...
kidPreX = kidX;
kidTrack = kidTrack + 1;
}
function mainCharWalks(){
//--------walking conditions...
var dx = targetX - mainCharPreX;
var dy = targetY - mainCharPreY;
var distanceFromCharacterToTarget = sqrt(dx*dx );
//control how character moves toward target
mainCharX = lerp(mainCharPreX,targetX,.15);
theY = lerp(mainCharPreY,targetY,.15);
//keep looping through the images continuously/seamlessly
if (trackMain >= mainCharFramez.length){
trackMain = 0;
}
//--------the actual walking part & more conditions...
//if the current x location is smaller than last x location, walk left
if(distanceFromCharacterToTarget < 15 && mainCharX < mainCharPreX){
push();
scale(-1,1);//flip image
image(mainCharFramez[7],mainCharX*-1,mainCharY);
pop();
}
else if(distanceFromCharacterToTarget < 15){
image(mainCharFramez[7],mainCharX,mainCharY);
}
else if (mainCharX < mainCharPreX){
push();
scale(-1,1);//flip image
image(mainCharFramez[trackMain],mainCharX*-1,mainCharY);
pop();
}
//otherwise if larger, walk right
else if (mainCharX > mainCharPreX){
image(mainCharFramez[trackMain],mainCharX,mainCharY);
}
//------------------Refresh values...
mainCharPreX = mainCharX;
mainCharPreY = theY;
trackMain = trackMain + 1;
}
//other stuff
function mousePressed(){
targetX = mouseX;
targetY = mouseY;
}
function keyPressed(){
if (key == "1"){
DreamTracker = (0);
} else if (key == "2"){
DreamTracker = (1);
} else if (key == "3"){
DreamTracker = (2);
} else if (key == "4"){
DreamTracker = (3);
} else if (key == "5"){
DreamTracker = (4);
}
}
function drawStars(){
//when random # is smaller than probability then new start occurs
if (StarProb > random(0,100)) {
morningStars.push(new Star(width));
}
for (var i = 0; i < morningStars.length; i++) {
morningStars[i].move(); //update star array
morningStars[i].display();
//if star goes out of boundary, remove it
if (morningStars[i].x < 0) {
morningStars.splice(i, 1);
}
}
}
//generate morningStars
function Star(xLocation){
var randoOpa = random(80,180); //have the brightness of stars vary
var randoSize = random(0.5,2); //have star size vary
strokeWeight(randoSize);
this.x = xLocation;//controlled above by random width
this.y = random(1,380); //range for stars to appear
this.speed = (-1.5); //speed
this.move = function() {
this.x += this.speed; //move the stars
}
this.display = function() {
//draw the stars here
stroke(202,195,232,80);
fill(202,195,232,randoOpa);
ellipse(this.x, this.y,randoSize,randoSize);
}
}
Conclusion:
Overall this project was exhausting to complete – but I’m pleased with the way it looks. Each image was hand drawn in photoshop with a one pixel brush so as to have the utmost control over my vision. I spent all of my free-time working on this, trying to bring it to life as best I could. There is still much more I would’ve liked to do with it, such as adding smoother transitions between dream sequences or adding more notes but overall it really sticks close to how I envision it in my head. In terms of the notes, I intended for them to be difficult to read to act as a parallel to the ambiguity and hazy quality of dreams – how things can seem so fuzzy and vague but you still can understand what’s going on perfectly.
Here’s a video of a play through with all the actions:
Here are some photos of each scene and the corresponding note:
If you want to know what each of the notes say, here is a quick copy of each of them:
Note from dream 1: “I remember a young girl desparately searching for something… she was wading through papers in a clear blue body of water. There were pathetic and skinny little trees that grew around and behind her directly from the water which was a bit of an odditiy… I remeber trying to call out to her – ask her what she was looking for or if I could help… but she ignored me. The more I tried to screm the less I seemed to make a sound and I was quickly becoming panicked – it was at that point that I realized thtat I was just a fly. She couldn’t hear or understand me no matter how hard I would try and I was nothing more than a buzzing nuisance. I resigned to watch after realizing this and was surprised by the fact that she was so involved in her task – that she was completely unbothered by the annoying buzzing coming from me.”
Note from dream 2: “There were three people all standing or sitting around, it was outside – but I’m not exactly sure where – mostly because we were in the grass but there was also a lamp plugged in outside? I tried to turn it on, but the lamp was broken. The sky in combination with the color of the ground reminded me of an anemic watermelon – maybe this is summer then? Anywho I remember seeing a girl sitting down and a gentlemen beside her -only he wasn’t much of a gentleman… his hands were crawling up her leg and I could see her whole face go black (well, everything but her eyes which remained a piercing white color). There was also a strange you child – just watching. Everyone had eyes but the only one with a mouth was Mr.Touchy feely.. I still don’t understand this.”
Note from dream 3: “This dream I don’t remember all too well – all I remember is how it looked and felt to be there, the way the stars moved across the sky (as they always do in my dreams for some reason) and the odd abandoned structure sitting still beneath a blossomig tree – It looked so rickety, like it could’nt possibly hold anyone up inside of it… but somehow in that absence of another person – you could feel them there… I don’t know who exactly, just that there was supposed to be someone there. There is some presence in absence here…”
Note from dream 4: “I remember this dream so vividly – it was beautiful – the plush bed reminded me of the way that cloth is rendered in paintings of Vesnus by TItian or other great artsists who inspired the classical period – the colors were off though – the women, although supple and lush was a gastly shade of green and somehow upon looking at her I knew she was dead. Dead people aren’t usually green – I know, but it was that weird “dreamer’s intuition” where you know nothing makes sense but somehow you are able to piece things together and just know things somehow. What didn’t know was why or how. Maybe there’se something to be said for the fact that I appeared asa fly in this dream as well…”
Note from dream 5: “It was dark – like time was moving backward . The sky shifted from a deep red to dark blue – almost like a sunset? But not quite. The clouds draped down the sky and had an overwhleming presence – they were almost too big – and I remember the way the stars moved behind the clouds – like they were being projected in motion across the sky – but the strangest part were the two people I saw – one not even moving, but entranced by the sky – the other walked backwards and refused to make eye-contct. I couldn’t move at all – I was trapped like the one looking to the sky and I only remember the fear that filled my body at the younger one moved closer – I was unsure of what they would do”
//Anna Boyle and Thomas Wrabetz
//Main functions
//Thomas' code
function setup() {
createCanvas(480, 480);
rectMode( CENTER );
player = makePlayer( width / 2, height / 2 );
level = makeLevel();
var sec=second();
}
function draw() {
background(200);
player.draw();
player.step();
level.draw();
//Anna's code
fill(0);
txt=width/2
fill(255);
noStroke();
if (drawBubble==1){
//triangle for speech bubble
triangle(width/2-20, txtH+20, bubbleX, bubbleY, width/2+20, txtH+20)
//if the player is on the top half, make the bubble on the bottom half
if (player.y<height/2){
txtH=440;
rect(width/2, 470, width, bubbleHeight);
//adjust the line height when there is only one line
singleLineHeight=465;
//if the player is on the bottom half, make the bubble on the top half
}if (player.y>=height/2){
txtH=30;
rect(width/2, 20, width, bubbleHeight);
//adjust the line height when there is only one line
singleLineHeight=30;
}
fill(0);
//makes the quote
textSize(17);
textAlign(CENTER);
printQuote( whichQuote );
}
rectMode(CORNER);
//draws the inspiration meter red bar
fill(188, 64, 64);
rect(width-20, 0, 20, height);
//draws the inspiration meter's variable green bar
fill(64, 188, 64);
rect(width-20, height-inspiroMeter, 20, height);
rectMode(CENTER);
//if the player gets enough quotes, they will win and see this screen
if (inspiroMeter>480){
fill(255);
rect(width/2, height/2, width, height)
fill(0);
textSize(32)
text("CONGRATULATIONS!", width/2, height/2-25);
text("YOU ARE INSPIRED", width/2, height/2+25);
noLoop();
}
}
//Thomas Wrabetz
//Section C
//twrabetz@andrew.cmu.edu
//Player object
//-----PLAYER OBJECT-----//
var PSIZE = 30;
var PCOLOR = [ 25, 150, 25, 255 ];
var PSPEED = 3;
var keyArray = [];
//Updates the player's position based on keyboard input
function stepPlayer()
{
//Variables to track the player's movement in each direction
var yStep = 0;
var xStep = 0;
if( keyIsPressed )
{
for( var i = 0; i < keyArray.length; i++ )
{
switch( keyArray[i] )
{
case 'W':
yStep -= PSPEED;
break;
case 'S':
yStep += PSPEED;
break;
case 'A':
xStep -= PSPEED;
break;
case 'D':
xStep += PSPEED;
break;
}
}
//Adjust speed for diagonal movement
if( xStep != 0 & yStep != 0 )
{
xStep *= 0.7071
yStep *= 0.7071
}
//Check if the player will collide with a wall in the x-direction
//and move the player if not
if( !level.collisionSearch( this.x + xStep, this.y, PSIZE ) )
{
//If the player is too close to the edges of the screen,
//move the level instead of the player
if( ( this.x < width * 4/5 || xStep < 0 )
&& ( this.x > width * 1/5 || xStep > 0 ) ) this.x += xStep;
else level.xOffset -= xStep;
}
//Check if the player will collide with a wall in the y-direction
//and move the player if not
if( !level.collisionSearch( this.x, this.y + yStep, PSIZE ) )
{
//If the player is too close to the edges of the screen,
//move the level instead of the player
if( ( this.y < height * 4/5 || yStep < 0 )
& ( this.y > height * 1/5 || yStep > 0 ) ) this.y += yStep;
else level.yOffset -= yStep;
}
//If the player collides with a figure, update the bubble
var figure = level.figureCollisionSearch( this.x + xStep,
this.y + yStep, PSIZE );
if( figure != -1 )
{
if( !drawBubble )
{
drawBubble = true;
//Only update to a new quote if this is a different figure
if( bubbleID != level.figures[ figure ].ID )
{
bubbleID = level.figures[ figure ].ID;
updateBubble();
}
}
bubbleX = level.figures[ figure ].x + level.xOffset;
bubbleY = level.figures[ figure ].y + level.yOffset;
}
else if( drawBubble )
drawBubble = false;
level.step();
}
}
//Draw the player
function drawPlayer()
{
fill( PCOLOR );
rect( this.x, this.y, PSIZE, PSIZE );
}
function makePlayer( px, py )
{
player = { x: px, y: py, draw: drawPlayer, step: stepPlayer };
return player;
}
//-----KEY TRACKING-----//
//Each key pressed is stored in the key array
function keyPressed()
{
keyArray.push( key );
}
//Keys are removed from the key array when released
function keyReleased()
{
for( var i = 0; i < keyArray.length; i++ )
{
if( keyArray[i] == key ) keyArray.splice( i, 1 );
}
}
//Thomas Wrabetz
//Section C
//twrabetz@andrew.cmu.edu
//Walls and level and figures
//-----INSPIRATIONAL FIGURE OBJECT-----//
figureColorArray = [ "Red", "Blue", "Green", "Yellow",
"Purple", "Orange", "Brown" ];
//Counter to give the figures unique IDs
figureIDCounter = 0;
//Counter that keeps track of how many open spaces have been created
figureCounter = 0;
//Each time figureCounter reaches FIGUREFREQ, a new figure is created
FIGUREFREQ = 10;
//Size of a figure
FIGUREWIDTH = 30;
function makeFigure( xPos, yPos )
{
figure = { x: xPos, y: yPos, figureColor: random(figureColorArray),
ID: figureIDCounter };
figureIDCounter++;
return figure;
}
//-----WALL OBJECT-----//
//Size of a wall
var WALLWIDTH = 80;
var WALLCOLOR = [ 116, 18, 229, 255 ];
var WALLCOLORDARK = [ 39, 7, 76, 255 ];
function makeWall( wx, wy )
{
var wall = { x: wx, y: wy, pattern: makePattern() };
return wall;
}
//-----LEVEL OBJECT-----//
//Add a row to the level. The parameters indicate which side
function levelAddRow( xRef, yRef )
{
//Variables to track whether the new row is an empty row
//and whether it has intersected an existing corridor
var before = false;
var after = false;
var passed = false;
var justPassed = false;
//Left Side
if( xRef == 1 )
{
//Clear out old row on opposite side
this.walls.unshift( [] );
this.walls.splice( this.walls.length - 1, 1 );
//Decide whether the new row is empty or a turning corridor
if( random() < 0.17 ) before = true;
else if( random() < 0.204 ) after = true;
else if( random() < 0.2572 )
{
before = true;
after = true;
}
//There can't be two empty rows next to each other
for( var i = 0; i < this.walls[1].length-2; i++ )
{
if( this.walls[1][i] == 0 & this.walls[1][i+1] == 0 )
{
before = false;
after = false;
}
}
//Generate the row
for( var i = 0; i < this.walls[1].length; i++ )
{
//Check if the row intersects a corridor
if( this.walls[1][i] == 0 )
{
passed = true;
justPassed = true;
}
//Generate a wall unless this row is empty or blocking a corridor
if( ( this.walls[1][i] == 0 & i != 0 && this.walls[1][i-1] != 0 &&
i != this.walls[1].length - 1 && this.walls[1][i+1] != 0 ) ||
( before && ( !passed || justPassed ) ) || ( after && passed ))
{
this.walls[0][i] = 0;
if( figureCounter == FIGUREFREQ - 1 )
this.figures.push( makeFigure( -1 * WALLWIDTH,
(i - 1) * WALLWIDTH ) );
figureCounter = (figureCounter + 1) % FIGUREFREQ;
}
else this.walls[0][i] = makeWall( -1 * WALLWIDTH,
(i - 1) * WALLWIDTH );
justPassed = false;
}
}
//Right Side
if( xRef == -1 )
{
//Clear out old row on opposite side
this.walls.push( [] );
this.walls.shift( 1 );
//Decide whether the new row is empty or a turning corridor
if( random() < 0.17 ) before = true;
else if( random() < 0.204 ) after = true;
else if( random() < 0.2572 )
{
before = true;
after = true;
}
//There can't be two empty rows next to each other
for( var i = 0; i < this.walls[1].length-2; i++ )
{
if( this.walls[this.walls.length-2][i] == 0
& this.walls[this.walls.length-2][i+1] == 0 )
{
before = false;
after = false;
}
}
//Generate the row
for( var i = 0; i < this.walls[this.walls.length-2].length; i++ )
{
//Check if the row intersects a corridor
if( this.walls[this.walls.length-2][i] == 0 )
{
passed = true;
justPassed = true;
}
//Generate a wall unless this row is empty or blocking a corridor
if( ( this.walls[this.walls.length-2][i] == 0 & i != 0 &&
this.walls[this.walls.length-2][i-1] != 0 &&
i != this.walls[this.walls.length-2].length - 1 &&
this.walls[this.walls.length-2][i+1] != 0 ) ||
( before && (!passed || justPassed) ) || ( after && passed ) )
{
this.walls[this.walls.length-1][i] = 0;
if( figureCounter == FIGUREFREQ - 1 )
this.figures.push( makeFigure( (this.walls.length-2)
* WALLWIDTH,
(i-1) * WALLWIDTH ) );
figureCounter = (figureCounter + 1) % FIGUREFREQ;
}
else this.walls[this.walls.length-1][i] =
makeWall( (this.walls.length-2)
* WALLWIDTH, (i-1) * WALLWIDTH );
justPassed = false;
}
}
//Top
if( yRef == 1 )
{
//Clear out old row on opposite side
for( i = 0; i < this.walls.length; i++ )
{
this.walls[i].unshift( -1 );
this.walls[i].splice( this.walls[i].length - 1, 1 );
}
//Decide whether the new row is empty or a turning corridor
if( random() < 0.17 ) before = true;
else if( random() < 0.204 ) after = true;
else if( random() < 0.2572 )
{
before = true;
after = true;
}
//There can't be two empty rows next to each other
for( var i = 0; i < this.walls.length-2; i++ )
{
if( this.walls[i][1] == 0 & this.walls[i+1][1] == 0 )
{
before = false;
after = false;
}
}
//Generate the row
for( var i = 0; i < this.walls.length; i++ )
{
//Check if the row intersects a corridor
if( this.walls[i][1] == 0 )
{
passed = true;
justPassed = true;
}
//Generate a wall unless this row is empty or blocking a corridor
if( ( this.walls[i][1] == 0 & i != 0 && this.walls[i-1][1] != 0
&& i != this.walls.length - 1
&& this.walls[i+1][1] != 0 )
|| (before && (!passed || justPassed)) || (after && passed))
{
this.walls[i][0] = 0;
if( figureCounter == FIGUREFREQ - 1 )
this.figures.push( makeFigure( (i-1) * WALLWIDTH,
-1 * WALLWIDTH ) );
figureCounter = (figureCounter + 1) % FIGUREFREQ;
}
else
this.walls[i][0] = makeWall((i-1) * WALLWIDTH, -1 * WALLWIDTH);
justPassed = false;
}
}
//Bottom
if( yRef == -1 )
{
//Clear out old row on opposite side
for( i = 0; i < this.walls.length; i++ )
{
this.walls[i].push( -1 );
this.walls[i].shift( 1 );
}
//Decide whether the new row is empty or a turning corridor
if( random() < 0.17 ) before = true;
else if( random() < 0.204 ) after = true;
else if( random() < 0.2572 )
{
before = true;
after = true;
}
//There can't be two empty rows next to each other
for( var i = 0; i < this.walls.length-2; i++ )
{
if( this.walls[i][this.walls.length-2] == 0
& this.walls[i+1][this.walls.length-2] == 0 )
{
before = false;
after = false;
}
}
//Generate the row
for( var i = 0; i < this.walls.length; i++ )
{
//Check if the row intersects a corridor
if( this.walls[i][this.walls[0].length-2] == 0 )
{
passed = true;
justPassed = true;
}
//Generate a wall unless this row is empty or blocking a corridor
if( ( this.walls[i][this.walls[0].length-2] == 0 & i != 0
&& this.walls[i-1][this.walls[0].length-2] != 0
&& i != this.walls.length - 1
&& this.walls[i+1][this.walls[0].length-2] != 0 )
|| (before && (!passed || justPassed)) || (after && passed))
{
this.walls[i][this.walls[0].length-1] = 0;
if( figureCounter == FIGUREFREQ - 1 )
this.figures.push( makeFigure( (i-1) * WALLWIDTH,
(this.walls[0].length-2) * WALLWIDTH ) );
figureCounter = (figureCounter + 1) % FIGUREFREQ;
}
else
this.walls[i][this.walls[0].length-1] =
makeWall( (i-1) * WALLWIDTH,
(this.walls[0].length-2) * WALLWIDTH );
justPassed = false;
}
}
}
//Update the level, moving objects inside and adding new rows if needed
function levelStep()
{
//If the offset for the walls is greater than the width of a wall,
//Shift the array of walls and add a new row
if( abs( this.xOffset ) >= WALLWIDTH )
{
//Incorporate offset into walls' basic x-positions
for( var j = 0; j < this.walls.length; j++ )
{
for( var k = 0; k < this.walls[j].length; k++ )
{
if( this.xOffset > 0 )
{
this.walls[j][k].x += WALLWIDTH;
}
if( this.xOffset < 0 )
{
this.walls[j][k].x -= WALLWIDTH;
}
}
}
//Incorporate offset into figures' basic x-positions
for( var j = 0; j < this.figures.length; j++ )
{
if( this.xOffset > 0 )
{
this.figures[j].x += WALLWIDTH;
}
if( this.xOffset < 0 )
{
this.figures[j].x -= WALLWIDTH;
}
//Remove figures that are off the screen
if( this.figures[j].x > width + FIGUREWIDTH / 2
|| this.figures[j].x < 0 - FIGUREWIDTH / 2 )
{
this.figures.splice( j, 1 );
j--;
}
}
//Reset the offset and add a new row
if( this.xOffset > 0 )
{
this.xOffset -= WALLWIDTH;
this.addRow( 1, 0 );
}
if( this.xOffset < 0 )
{
this.xOffset += WALLWIDTH;
this.addRow( -1, 0 );
}
}
if( abs( this.yOffset ) >= WALLWIDTH )
{
//Incorporate offset into walls' basic y-positions
for( var j = 0; j < this.walls.length; j++ )
{
for( var k = 0; k < this.walls[j].length; k++ )
{
if( this.yOffset > 0 )
{
this.walls[j][k].y += WALLWIDTH;
}
if( this.yOffset < 0 )
{
this.walls[j][k].y -= WALLWIDTH;
}
}
}
//Incorporate offset into figures' basic y-positions
for( var j = 0; j < this.figures.length; j++ )
{
if( this.yOffset > 0 )
{
this.figures[j].y += WALLWIDTH;
}
if( this.yOffset < 0 )
{
this.figures[j].y -= WALLWIDTH;
}
//Remove figures that are off the screen
if( this.figures[j].y > height + FIGUREWIDTH / 2
|| this.figures[j].y < 0 - FIGUREWIDTH / 2 )
{
this.figures.splice( j, 1 );
j--;
}
}
//Reset the offset and add a new row
if( this.yOffset > 0 )
{
this.yOffset -= WALLWIDTH;
this.addRow( 0, 1 );
}
if( this.yOffset < 0 )
{
this.yOffset += WALLWIDTH;
this.addRow( 0, -1 );
}
}
}
//Checks if a square at x,y with size size would collide with the wall
//at index a,b of the array of walls
function levelWallCollision( x, y, size, a, b )
{
var wall = this.walls[a][b];
if( wall == 0 ) return false;
return abs( x - ( wall.x + this.xOffset ) ) < size / 2 + WALLWIDTH / 2
& abs( y - ( wall.y + this.yOffset ) ) < size / 2 + WALLWIDTH / 2;
}
//Check collision for all the walls
function levelCollisionSearch( x, y, size )
{
for( i = 0; i < this.walls.length; i++ )
{
for( j = 0; j < this.walls[i].length; j++ )
{
if( this.wallCollision( x, y, size, i, j ) ) return true;
}
}
return false;
}
//Draw the wall at index a,b of the wall array
function levelDrawWall( a, b )
{
var wall = this.walls[a][b];
if( wall == 0 ) return;
push();
stroke( WALLCOLORDARK );
fill( WALLCOLOR );
rect( wall.x + this.xOffset, wall.y + this.yOffset, WALLWIDTH, WALLWIDTH );
wall.pattern.draw( wall.x + this.xOffset, wall.y + this.yOffset );
pop();
}
//Checks if a square at x,y with size size would collide with a figure
//at index a of the figure array
function levelFigureCollision( x, y, size, a )
{
if( a >= this.figures.length ) return false;
var figure = this.figures[a];
return abs( x - ( figure.x + this.xOffset ) ) < size / 2 + FIGUREWIDTH / 2
& abs( y - ( figure.y + this.yOffset ) )
< size / 2 + FIGUREWIDTH / 2;
}
//Check collision for all the figures. If found, returns the index of
//the colliding figure in the figure array. If not, returns -1.
function levelFigureCollisionSearch( x, y, size )
{
for( i = 0; i < this.figures.length; i++ )
{
if( this.figureCollision( x, y, size, i ) ) return i;
}
return -1;
}
//Draw the figure at index a of the figure array
function levelDrawFigure( a )
{
var figure = this.figures[a];
if( figure == 0 ) return;
push();
stroke( 0 );
fill( figure.figureColor );
ellipse( figure.x + this.xOffset, figure.y + this.yOffset,
FIGUREWIDTH, FIGUREWIDTH );
pop();
}
//Draw all the walls and figures
function levelDraw()
{
for( i = 0; i < this.walls.length; i++ )
{
for( j = 0; j < this.walls[i].length; j++ )
{
this.drawWall( i, j );
}
}
for( i = 0; i < this.figures.length; i++ )
{
this.drawFigure( i );
}
}
//Make a level, which contains arrays of walls and figures as well as a shared
//x and y offet which applies to every object in the level
function makeLevel()
{
var wallsArray = [];
var figuresArray = [];
for( i = 0; (i - 1) * WALLWIDTH <= width + WALLWIDTH; i++ )
{
wallsArray.push( [] );
for( j = 0; (j - 1) * WALLWIDTH <= height + WALLWIDTH; j++ )
{
if( i == 4 || j == 4 ) wallsArray[i].push( 0 );
else
wallsArray[i].push( makeWall( (i - 1) * WALLWIDTH,
(j - 1) * WALLWIDTH ) );
}
}
level = { walls: wallsArray, figures: figuresArray, xOffset: 0, yOffset: 0,
draw: levelDraw, drawWall: levelDrawWall,
wallCollision: levelWallCollision,
collisionSearch: levelCollisionSearch,
step: levelStep, addRow: levelAddRow,
drawFigure: levelDrawFigure,
figureCollision: levelFigureCollision,
figureCollisionSearch: levelFigureCollisionSearch };
return level;
}
//Thomas Wrabetz
//Section C
//twrabetz@andrew.cmu.edu
//Pattern object for wall blocks
var DOTSIZE = 3;
var colors = [ [66,134,234,255], [23,216,213,255],
[23,216,236,255], [68,216,23,255], [228,242,42,255] ];
function makePattern() {
var angle;
var newPattern={c: random(colors), arms: int( random( 4 ) ) + 2,
a: random(2*PI), draw: drawPattern, dotPositionArray: [] };
for( var i = 0; i < newPattern.arms; i++ )
{
for( var j = 0; j < WALLWIDTH / 2 - 5; j+= DOTSIZE * 2 )
{
angle = newPattern.a + i * (2 * PI / newPattern.arms);
newPattern.dotPositionArray.push( j * cos( angle ) +
( sin( j ) * 20 * cos( angle + PI / 2 ) ) );
newPattern.dotPositionArray.push( j * sin( angle ) +
( sin( j ) * 20 * sin( angle + PI / 2 ) ) );
}
}
return newPattern;
}
function drawPattern( x, y ){
fill(this.c)
push();
noStroke();
var currentX;
var currentY;
for( var i = 0; i < this.dotPositionArray.length - 1; i+= 2 )
{
ellipse( x + this.dotPositionArray[i], y + this.dotPositionArray[i+1],
DOTSIZE, DOTSIZE );
}
pop();
}
//Anna Boyle
//Section D
//aboyle@andrew.cmu.edu
//Quote generator
var abstractNouns = ["Rebellion", "Curiosity", "Jealousy", "Friendship",
"Family", "Evil", "Life", "Hope", "Grace", "Love", "Faith", "Opportunity",
"Dedication", "Insanity", "Fortune", "Luck", "Hatred", "Knowledge", "Pain",
"Heaven"];
var inspireNouns = ["rainbow", "cloud", "light", "star", "candle", "child",
"dream", "building", "hero", "breeze", "eye", "moon", "snowflake", "apple",
"tree", "flower", "butterfly", "mirror", "door", "heart"];
var inspireNounsPlural = ["rainbows", "clouds", "lights", "stars", "candles",
"children", "kisses", "buildings", "hands", "brothers", "sisters",
"snowflakes", "dreams", "apples", "trees", "flowers", "butterflies", "mirrors",
"doors", "hearts"];
var strangeNouns=["peach cobbler", "deodorant", "used tissue", "conch shell",
"toaster", "pasta strainer", "blade of grass", "grandma's house", "unicycle",
"weed whacker", "shampoo bottle", "corpse", "snickerdoodle",
"ten gallon hat", "toupee", "colony of termites", "mother-in-law",
"sexy firemen calendar", "underground bunker", "angry baboon"];
var strangeNounsPlural = ["alien invasions", "clowns", "podiatrists",
"belly dancers", "cacti", "voodoo dolls", "raspberries", "dust bunnies",
"distant relatives", "kentucky fried chicken", "rotten eggs", "nudists",
"nunchuks", "toenail clippings", "rocket scientists", "green beans", "nuns",
"croissants", "drunk ballerinas", "shoelaces" ];
var inspireVerbs= ["flies", "moves", "shines", "waits", "stands", "goes",
"sleeps", "thinks", "cries", "laughs", "yells", "watches", "jumps"];
var inspireVerbsObj = ["hold", "hug", "love", "hate", "grab", "accept",
"support", "look at", "want", "sacrifice", "kiss", "pray for", "abandon"];
var inspireVerbsGerund= ["flying", "moving", "doing", "waiting", "standing",
"going", "saying", "thinking", "crying", "laughing", "yelling", "watching",
"jumping"];
var inspireVerbsObjGerund = ["holding", "hugging", "loving", "hating",
"grabbing", "accepting", "supporting", "seeing", "wanting", "finding",
"kissing", "praying for", "abandoning"];
var strangeVerbs=["dances", "dies", "melts", "yodels", "sneezes", "does yoga",
"crawls", "beatboxes", "undresses", "vomits", "whistles", "rollerblades",
"explodes"];
var strangeVerbsObj=["stab", "fight", "smack", "bury", "kick", "exorcise",
"kidnap", "high five", "sniff", "smuggle", "tickle", "cuddle", "nibble"];
var strangeVerbsGerund=["dancing", "dying", "melting", "yodeling", "sneezing",
"doing yoga","crawling", "sleeping", "undressing", "vomiting", "whistling",
"rollerblading", "exploding"];
var strangeVerbsObjGerund=["stabbing", "fighting", "smacking", "burying",
"kicking", "exorcising", "kidnapping", "high fiving", "sniffing", "smuggling",
"tickling", "cuddling", "nibbling"];
var locationWords=["behind", "in front of", "next to", "inside of", "below",
"on top of", "above", "under", "among", "beside", "over", "far away from",
"underneath"];
var comparison=["darker", "sadder", "bigger", "smaller", "harder", "softer",
"better", "worse", "faster", "slower", "stronger", "weaker", "happier",
"drunker", "older", "younger", "smarter", "dumber", "hotter", "colder"];
var personQuote=["Albert Einstein", "Mahatma Gandhi", "Oprah Winfrey",
"George Washington", "Nelson Mandela", "Jesus Christ", "Benjamin Franklin",
"Plato", "Mother Teresa", "My mom", "Beyonce", "Martin Luther King Jr.",
"Santa Claus"]
//variable for the quote templates
var whichQuote;
/*nCh=nineteen choices, tCh=twelve choices
There are multiple variables to prevent parts of speech with same amount of
choices don't get constantly paired with each other */
var nCh1;
var nCh2;
var nCh3;
var nCh4;
var tCh1;
var tCh2;
var tCh3;
var tCh4;
//Variables related to drawing the speech bubble
var txt;
var txtH;
var bubbleHeight;
var singleLineHeight;
var bubbleX = 0;
var bubbleY = 0;
var drawBubble = false;
var bubbleID = -1;
var inspiroMeter=0;
function updateBubble(){
//randomizes which number in the array will be chosen for the parts of speech
nCh1=int(random(20));
nCh2=int(random(20));
nCh3=int(random(20));
nCh4=int(random(20));
tCh1=int(random(13));
tCh2=int(random(13));
tCh3=int(random(13));
tCh4=int(random(13));
//randomzies which quote template will be chosen
whichQuote=int(random(14));
inspiroMeter=inspiroMeter+20;
}
//Chooses which quote template will be chosen based on the random number
//between 0 and 13
function printQuote( num )
{
switch(num)
{
case 0:
worthTwo();
break;
case 1:
tryToBe();
break;
case 2:
whenYouHave();
break;
case 3:
judgeEach();
break;
case 4:
ifYouMiss();
break;
case 5:
theBest();
break;
case 6:
duringOurMoments();
break;
case 7:
letUs();
break;
case 8:
palesInComparison();
break;
case 9:
haveSeen();
break;
case 10:
inSeason();
break;
case 11:
combination();
break;
case 12:
onlyICan();
break;
case 13:
jokeQuote();
break;
}
}
//Below are all the quote template functions
//bubbleHeight changes the size of bubble when there are different amounts of text
function tryToBe(){
text("Try to be a "+inspireNouns[nCh1]+" in someone's "
+strangeNouns[nCh2], txt, singleLineHeight);
bubbleHeight=75;
}
function worthTwo(){
text("One "+inspireNouns[nCh1]+" is worth two "+
strangeNounsPlural[nCh2], txt, singleLineHeight);
bubbleHeight=75;
}
function whenYouHave(){
text("When you have a "+strangeNouns[nCh1]+", you've got to ", txt, txtH);
text(inspireVerbsObj[tCh1]+" it and never "+strangeVerbsObj[tCh2]+
" it", txt, txtH+25);
bubbleHeight=130;
}
function judgeEach(){
text("Don't judge each day by the "+inspireNounsPlural[nCh1],
txt, txtH);
text(" you "+inspireVerbsObj[tCh1]+", but by the "+strangeNounsPlural[nCh1]
+" you "+strangeVerbsObj[tCh1], txt, txtH+25);
bubbleHeight=130;
}
function ifYouMiss(){
text("Shoot for the "+inspireNouns[nCh1]+", and if you miss", txt, txtH);
text(" you will still be "+locationWords[tCh1]+" the "
+strangeNounsPlural[nCh2], txt, txtH+25);
bubbleHeight=130;
}
function theBest(){
text("The best preparation for tomorrow is", txt, txtH);
text(strangeVerbsObjGerund[tCh1]+" your "+
strangeNouns[nCh1]+" today", txt, txtH+25);
bubbleHeight=130;
}
function duringOurMoments(){
text("It is during our "+comparison[nCh1]+" moments that we must", txt, txtH);
text("focus to "+strangeVerbsObj[tCh1]+" the "+
strangeNounsPlural[nCh2], txt, txtH+25);
bubbleHeight=130;
}
function letUs(){
text("Let us sacrifice our "+inspireNounsPlural[nCh1]
+" so that", txt, txtH);
text("our children can "+strangeVerbsObj[tCh1]+" a "+
comparison[nCh2]+" "+strangeNouns[nCh3], txt, txtH+25);
bubbleHeight=130;
}
function palesInComparison(){
text("What "+inspireVerbs[tCh1]+" behind you and what "+
inspireVerbs[tCh2]+" in front of you,", txt, txtH);
text("pales in comparison to what "+strangeVerbs[tCh3]+" "+
locationWords[tCh4]+" you", txt, txtH+25)
bubbleHeight=130;
}
function haveSeen(){
text("If I have seen further than others, it is", txt, txtH);
text("by "+strangeVerbsGerund[tCh1]+" "+locationWords[tCh2]+" "
+strangeNounsPlural[nCh1], txt, txtH+25)
bubbleHeight=130;
}
function inSeason(){
text(abstractNouns[nCh1]+" is a fruit in season at all times,", txt, txtH);
text("and within reach of every "+strangeNouns[nCh2], txt, txtH+25);
bubbleHeight=130;
}
function combination(){
text(abstractNouns[nCh1]+" and "+strangeNounsPlural[nCh2]+
" are a powerful combination", txt, singleLineHeight);
bubbleHeight=75;
}
function onlyICan(){
text("Only you can "+strangeVerbsObj[tCh1]+" your "+strangeNouns[nCh1]+".",
txt, txtH);
text("No one else can do it for you.", txt, txtH+25);
bubbleHeight=130;
}
function jokeQuote(){
text("This project definitely deserves an A", txt, txtH);
text("-- "+personQuote[tCh1], txt+15, txtH+25);
bubbleHeight=130;
}
For our final project, we made an Inspirational Quote Maze. The player moves a small square around in a randomly generated maze using the WASD keys. The dots in the maze tell the player inspirational quotes when they collide. For every quote the character receives, they gain a couple points in their “InspiroMeter.” Once they hear enough quotes, the game is over and they are congratulated for being inspired.
Thomas mainly worked in the wall, player, and patterns files. He made the player movements and randomly generated the maze and the dots found within. He made it so the player can’t receive a different quote from the same dot twice in a row. He also created patterns to make the blocks look more exciting.
Anna mainly worked in the main and quotes files. She decided on the quote templates, made arrays filled with parts of speech, and randomized both of them for unique quotes. She made the speech bubble that appears when a character is talking. She also made the “InspiroMeter” and made the game end after a certain number of quotes.
Overall, we think that our project turned out well and we are proud of our efforts!
Audio embedded, please turn up volume. Vimeo recording also included at bottom.
In our final project, we made a music video and explored the relationship between geometric motion and rhythm. We divided the video into four sections of movements, interacting with the rhythm and mood of the music.
My final project is a playable viola that creates art in the background based on the notes played and length of the notes played. I drew the viola utilizing arcs, triangles, lines, and other 2D shapes. Then I added sounds to the notes played and ellipses that move with the music.
Each note is connected to a key, that when pressed, plays a note and a visual representation of the sound as a green dot showing the placement of the note on the fingerboard. In addition, there are 20 uniquely colored balls hiding behind the viola that are connected to 20 notes that can be played with the keyboard. Each ball will move at its individual vertical and horizontal velocities when the key is pressed. When the key is lifted, the sound will stop and ball will stop in place. When the performer is finished playing, it will leave a pattern of balls in the background. With the end of each unique composition, the background will look unique, linking each unique piece of music with a unique piece of art.
Note: WordPress does not display the audio correctly, so here is a zip file with the audio files and functioning code. In order to run this code, you access it in the terminal and type “python -m SimpleHTTPServer” and the code will run properly. Above is a screenshot of the completely functioning code.