sketchDownloadvar terraine = []; var noiseParam = 0; var noiseStep = .02; var icesize = noiseStep*2500;
var washer;
var handwasher;
var bubble;
var bubs = [];
var waterbottle;
var reusebottle;
var car;
var bus;
var shoponline;
var shoplocal;
var allobj = []; var len; var n = 0; var q;
var isMouseClicked = -1;var waterdrop;
var watersplash;
function makeWasher(cx, cy) {
washer = { x: cx,
y: cy,
show: drawWasher,
melt: 4,
txt: "Use electric washer" }
return washer;
}
function makeHandwasher(cx, cy) {
for (var i=0; i<30; i++) {
bubx = random(-35, 35);
buby = -random(-.5, 3)*i;
var bub = makeBubble(bubx, buby);
bubs.push(bub);
}
handwasher = { x: cx,
y: cy,
show: drawHandwasher,
melt: 1,
txt: "Hand-wash clothing" }
return handwasher;
}
function makeBubble(bubx, buby) {;
bubble = {x: bubx,
y: buby,
sz: random(2, 6),
show: drawBubble }
return bubble;
}
function makeWaterbottle(cx, cy) {
waterbottle = {x: cx,
y: cy,
show: drawWaterbottle,
melt: 3,
txt: "Plastic water bottle"}
return waterbottle;
}
function makeReusebottle(cx, cy) {
reusebottle = {x: cx,
y: cy,
show: drawReusebottle,
melt: 1,
txt: "Reusable water bottle"}
return reusebottle;
}
function makeCar(cx, cy) {
car = {x: cx,
y: cy,
show: drawCar,
melt: 5,
txt: "Drive a car"}
return car;
}
function makeBus(cx, cy) {
bus = {x: cx,
y: cy,
show: drawBus,
melt: 1,
txt: "Take public transportation"}
return bus;
}
function makeOnline(cx, cy) {
shoponline = {x: cx,
y: cy,
show: drawOnline,
melt: 10,
txt: "Shop online"}
return shoponline;
}
function makeLocal(cx, cy) {
shoplocal = {x: cx,
y: cy,
show: drawLocal,
melt: 1,
txt: "Shop local"}
return shoplocal;
}
function preload() {
waterdrop = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/splash.wav");
watersplash = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/bigsplash.mp3");
}
function setup() {
createCanvas(400, 400);
strokeWeight(2);
rectMode(CENTER);
textAlign(CENTER);
textFont('Georgia');
textSize(13);
useSound();
for (var i=0; i<icesize; i++) {
var n = noise(noiseParam); var value = map(n, 0, 1, height/3, height); terraine.push(value); noiseParam += noiseStep;
}
washer = makeWasher(125, 100);
handwasher = makeHandwasher(275, 100);
waterbottle = makeWaterbottle(265, 100);
reusebottle = makeReusebottle(135, 100);
car = makeCar(125, 100);
bus = makeBus(275, 100);
shoponline = makeOnline(290, 100);
shoplocal = makeLocal(115, 100);
allobj = [washer, handwasher,
reusebottle, waterbottle,
car, bus,
shoplocal, shoponline];
len = allobj.length;
}
function soundSetup() { waterdrop.setVolume(0.5);
watersplash.setVolume(0.5);
}
function draw() {
background(100, 175, 240);
drawIce();
meltIce();
if (terraine.length > 1) {
q = n%(len); allobj[q].show();
allobj[q+1].show();
}
}
function mousePressed() {
let onObj = checkClick();
if (onObj == true) {
isMouseClicked = -isMouseClicked;
n += 2; isMouseClicked = -isMouseClicked;
}
}
function checkClick() {
if (mouseX>75 & mouseX<175 && mouseY>50 && mouseY<150) {
meltMore(allobj[q]);
return true;
}
if (mouseX>225 & mouseX<325 && mouseY>50 && mouseY<150) {
meltMore(allobj[q+1]);
return true;
}
}
function drawIce() {
fill(255);
stroke(0);
strokeWeight(1);
beginShape();
vertex(-5, height);
vertex(-5, terraine[0]);
for (var j=0; j<terraine.length-1; j++) {
vertex(j*5, terraine[j]);
}
vertex((terraine.length-1)*icesize, terraine[terraine.length]);
vertex((terraine.length-1)*5, height);
endShape();
checkIce();
}
function meltIce() {
if (terraine.length == 1) { return }
if (frameCount%250==0) {
terraine.pop();
waterdrop.play();
}
}
function meltMore(obj) {
for (var k=0; k<obj.melt; k++) {
terraine.pop();
}
if (obj.melt == 1) { waterdrop.play() }
else { watersplash.play() }
}
function checkIce() {
if (terraine.length <= 1) {
rect(width/2, height/2, 350, 350);
textAlign(CENTER);
textSize(35);
fill(0);
text("Oh No!", width/2, 150);
textSize(16);
fill(150, 0, 0);
text("Looks like your choices caused global warming.", width/2, 175);
textSize(20);
fill(0);
text("Next time, try to make better choices.", width/2, 215);
textSize(13);
text("You were already trying to make good choices?", width/2, 300);
text("You picked the best options that were avaiable to you?", width/2, 325);
textSize(18);
fill(150, 0, 0);
text("Have better options next time I guess.", width/2, 350);
textSize(11);
noStroke();
fill(255);
text("Refresh this page for another try!", width/2, 390);
noLoop();
}
}
function drawWasher() {
push();
translate(this.x, this.y);
fill(220);
square(0, 0, 100, 5);
fill(150);
circle(0, 0, 75);
noStroke();
fill(75, 125, 225);
beginShape();
vertex(-30, 0);
vertex(-30, 0);
curveVertex(-24, 2);
curveVertex(-18, 0);
curveVertex(-12, 2);
curveVertex(-6, 0);
curveVertex(0, 2);
curveVertex(6, 0);
curveVertex(12, 2);
curveVertex(18, 0);
curveVertex(24, 2);
vertex(30, 0);
curveVertex(26, 16);
curveVertex(15, 26);
curveVertex(0, 30);
curveVertex(-15, 26);
curveVertex(-26, 16);
vertex(-30, 0);
vertex(-30, 0);
endShape();
stroke(0);
fill(175, 200, 255, 175);
circle(0, 0, 60);
noStroke();
push();
rotate(radians(40));
fill(200, 215, 255);
ellipse(0, -15, 30, 5);
ellipse(0, -20, 15, 3);
pop();
fill(200, 0, 0);
circle(40, -40, 3);
fill(75);
circle(35, -40, 3);
circle(30, -40, 3);
fill(150);
circle(35, -33, 7);
fill(0);
text(this.txt, 0, 62);
pop();
}
function drawHandwasher() {
push();
translate(this.x, this.y);
fill(200);
quad(-50, 0, 50, 0, 35, 40, -35, 40);
arc(0, 0, 100, 25, 0, PI);
arc(0, 0, 100, 15, PI, 2*PI);
noStroke();
fill(58, 101, 74);
quad(-30, -7, -15, -8, -15, 10, -32, 8);
fill(200, 100, 150);
quad(-20, -8, -7, -9, -5, 10, -25, 10);
fill(100, 140, 240);
beginShape();
vertex(-45, 6);
vertex(-45, 5);
curveVertex(-36, 5);
curveVertex(-27, 6);
curveVertex(-18, 5);
curveVertex(-9, 6);
curveVertex(0, 5);
curveVertex(9, 6);
curveVertex(18, 5);
curveVertex(27, 6);
curveVertex(36, 5);
vertex(45, 5);
curveVertex(29, 10);
curveVertex(0, 12);
curveVertex(-29, 10);
vertex(-45, 5);
vertex(-45, 6);
endShape();
fill(200, 215, 255);
stroke(100, 140, 240);
strokeWeight(.25);
for (var i=0; i<30; i++) {
bubs[i].show()
}
fill(0);
strokeWeight(1);
text(this.txt, 0, 62);
pop();
}
function drawBubble() {
circle(this.x, this.y, this.sz);
}
function drawWaterbottle() {
stroke(0);
strokeWeight(1);
fill(240);
rect(this.x, this.y-45, 15, 10);
fill(225, 230, 255);
arc(this.x, this.y-18, 42, 47, radians(290), radians(250), OPEN);
beginShape();
vertex(this.x+21, this.y-15);
vertex(this.x+21, this.y-15);
curveVertex(this.x+20, this.y+6);
curveVertex(this.x+23, this.y+30);
curveVertex(this.x+19, this.y+50);
curveVertex(this.x, this.y+50);
curveVertex(this.x-19, this.y+50);
curveVertex(this.x-23, this.y+30);
curveVertex(this.x-20, this.y+6);
vertex(this.x-21, this.y-15);
vertex(this.x-21, this.y-15);
endShape();
stroke(190);
for (var l=0; l<14; l+=2) {
line(this.x-6 + l, this.y-41, this.x-6 + l, this.y - 47);
}
fill(75, 125, 200);
noStroke();
beginShape();
vertex(this.x+21, this.y-15);
vertex(this.x+21, this.y-15);
vertex(this.x+20, this.y-2);
vertex(this.x+20, this.y+8);
vertex(this.x+22, this.y+20);
vertex(this.x-22, this.y+20);
vertex(this.x-20, this.y+8);
vertex(this.x-20, this.y-2);
vertex(this.x-21, this.y-15);
vertex(this.x-21, this.y-15);
endShape();
stroke(190, 210, 250);
noFill();
arc(this.x, this.y-18, 30, 47, radians(-65), radians(-10));
arc(this.x, this.y-18, 10, 47, radians(-80), radians(-20));
arc(this.x, this.y-18, 10, 47, radians(200), radians(260));
arc(this.x, this.y-18, 30, 47, radians(190), radians(245));
arc(this.x, this.y+23, 70, 9, radians(10), radians(170));
arc(this.x, this.y+30, 60, 10, radians(10), radians(170));
arc(this.x, this.y+37, 55, 11, radians(10), radians(170));
strokeWeight(2);
stroke(90, 145, 220);
beginShape();
vertex(this.x+15, this.y+10);
vertex(this.x+15, this.y+10);
curveVertex(this.x+10, this.y);
curveVertex(this.x-8, this.y-5);
vertex(this.x-15, this.y-10);
vertex(this.x-15, this.y-10);
endShape();
beginShape();
vertex(this.x+15, this.y+10);
vertex(this.x+15, this.y+10);
curveVertex(this.x+8, this.y+5);
curveVertex(this.x-10, this.y);
vertex(this.x-15, this.y-10);
vertex(this.x-15, this.y-10);
endShape();
fill(0);
strokeWeight(1);
text(this.txt, this.x, this.y+62);
}
function drawReusebottle() {
stroke(0);
strokeWeight(1);
fill(100, 155, 230);
stroke(90, 145, 220);
beginShape();
vertex(this.x-23, this.y-18);
vertex(this.x-23, this.y-18);
curveVertex(this.x-17, this.y-19);
curveVertex(this.x-10, this.y-18);
curveVertex(this.x, this.y-19);
curveVertex(this.x+10, this.y-18);
curveVertex(this.x+17, this.y-19);
vertex(this.x+23, this.y-18);
vertex(this.x+23, this.y-18);
endShape();
noStroke();
beginShape();
vertex(this.x+23, this.y-18);
vertex(this.x+23, this.y-18);
curveVertex(this.x+24, this.y+30);
curveVertex(this.x+19, this.y+50);
curveVertex(this.x-19, this.y+50);
curveVertex(this.x-24, this.y+30);
vertex(this.x-23, this.y-18);
vertex(this.x-23, this.y-18);
endShape();
noStroke();
fill(200, 100, 150, 100);
arc(this.x, this.y-18, 46, 45, radians(185), radians(-5), OPEN);
noFill();
stroke(0);
arc(this.x, this.y-18, 46, 45, radians(290), radians(0), OPEN);
arc(this.x, this.y-18, 46, 45, radians(180), radians(250), OPEN);
fill(200, 100, 150, 100);
beginShape();
vertex(this.x+23, this.y-20);
vertex(this.x+23, this.y-20);
curveVertex(this.x+24, this.y+30);
curveVertex(this.x+19, this.y+50);
curveVertex(this.x-19, this.y+50);
curveVertex(this.x-24, this.y+30);
vertex(this.x-23, this.y-20);
vertex(this.x-23, this.y-20);
endShape();
stroke(190, 90, 140, 200);
for (var u=0; u<12; u+=1) {
line(this.x-15, this.y-15+(u*5), this.x-22, this.y-15+(u*5));
}
stroke(0);
strokeWeight(.5);
fill(250, 225, 0);
push();
translate(this.x+16, this.y+20);
rotate(radians(32));
arc(0, 0, 20, 20, radians(8), radians(287), OPEN);
arc(0, 0, 13, 13, radians(10), radians(170));
strokeWeight(1);
line(-2, 0, -2, -2);
line(2, 0, 2, -2);
pop();
push();
fill(225, 125, 255);
translate(this.x+9, this.y+36);
rotate(radians(-20));
let rot = 0;
for (var r=0; r<7; r++) {
push();
rotate(radians(rot));
ellipse(6, 0, 8, 4);
pop();
rot += 360/7;
}
fill(175, 200, 100);
circle(0, 0, 5);
pop();
noFill();
strokeWeight(2);
stroke(200);
arc(this.x+14, this.y-50, 29, 25, radians(200), radians(90));
stroke(0)
strokeWeight(1);
arc(this.x+14, this.y-50, 28, 23, radians(200), radians(90));
arc(this.x+14, this.y-50, 33, 27, radians(200), radians(90));
fill(200);
rect(this.x, this.y-52, 15, 5, 2);
rect(this.x, this.y-45, 25, 15, 2);
stroke(225);
strokeWeight(6);
line(this.x, this.y-40, this.x, this.y-45);
line(this.x-8, this.y-40, this.x-8, this.y-45);
line(this.x+8, this.y-40, this.x+8, this.y-45);
stroke(0);
strokeWeight(1);
rect(this.x, this.y-38, 28, 2, 3);
fill(0);
text(this.txt, this.x, this.y+62);
}
function drawCar() {
let carcol = color(150, 0, 0);
let detailcol = color(100, 0, 0);
fill(120);
noStroke();
rect(this.x+60, this.y+27, 5, 3);
stroke(detailcol);
fill(carcol);
beginShape();
vertex(this.x-40, this.y);
vertex(this.x-40, this.y+1);
curveVertex(this.x-20, this.y-22);
curveVertex(this.x+25, this.y-22);
curveVertex(this.x+48, this.y);
curveVertex(this.x+57, this.y+3);
curveVertex(this.x+58, this.y+10);
curveVertex(this.x+59, this.y+25);
curveVertex(this.x+45, this.y+30);
curveVertex(this.x-60, this.y+30);
curveVertex(this.x-65, this.y+8);
vertex(this.x-40, this.y+1);
vertex(this.x-40, this.y+1);
endShape();
stroke(150, 160, 200);
fill(150, 160, 200);
beginShape();
vertex(this.x-35, this.y+1);
vertex(this.x-35, this.y+1);
curveVertex(this.x-15, this.y-19);
curveVertex(this.x+20, this.y-19);
curveVertex(this.x+40, this.y-1);
curveVertex(this.x+30, this.y+1);
vertex(this.x-35, this.y+1);
vertex(this.x-35, this.y+1);
endShape();
fill(carcol);
stroke(carcol);
strokeWeight(4);
line(this.x+2, this.y+2, this.x+2, this.y-22);
strokeWeight(2);
line(this.x+33, this.y+2, this.x+33, this.y-16);
noStroke();
fill(230, 230, 175);
push();
translate(this.x-62, this.y+9);
rotate(radians(-35));
ellipse(0, 0, 10, 7);
ellipse(-7, 1, 3, 3);
pop();
rect(this.x+57, this.y+21, 5, 7, 2);
rect(this.x+57, this.y+15, 2, 4, 2);
stroke(detailcol);
line(this.x-5, this.y+7, this.x, this.y+7);
line(this.x+4, this.y+7, this.x+9, this.y+7);
fill(25);
stroke(0);
ellipse(this.x+35, this.y+30, 25, 25);
ellipse(this.x-40, this.y+30, 25, 25);
let wrot = 0;
for (var j=0; j<5; j++) {
push();
translate(this.x+35, this.y+30);
rotate(radians(wrot));
line(-10, 0, 10, 0);
pop();
push();
translate(this.x-40, this.y+30);
rotate(radians(wrot));
line(-10, 0, 10, 0);
pop();
wrot+=360/10;
}
fill(0);
strokeWeight(1);
text(this.txt, this.x, this.y+62);
}
function drawBus() {
let buscol = color(50, 75, 255);
let busdetails = color(20, 40, 200);
fill(120);
noStroke();
rect(this.x+50, this.y-27, 3, 5);
fill(buscol);
stroke(busdetails);
strokeWeight(2);
rect(this.x, this.y, 120, 50, 2);
line(this.x-45, this.y+8, this.x+55, this.y+8);
strokeWeight(1);
line(this.x-45, this.y+10, this.x+55, this.y+10);
stroke(150, 160, 200);
strokeWeight(2);
fill(150, 160, 200);
rect(this.x-57, this.y-5, 5, 25);
for (var r=0; r<10; r++) {
rect(this.x-41+(10*r), this.y-3, 7, 15);
}
fill(25);
stroke(0);
ellipse(this.x+38, this.y+30, 15, 15);
ellipse(this.x+22, this.y+30, 15, 15);
ellipse(this.x-45, this.y+30, 15, 15);
ellipse(this.x-29, this.y+30, 15, 15);
strokeWeight(1);
let wrot = 0;
for (var j=0; j<5; j++) {
push();
translate(this.x+38, this.y+30);
rotate(radians(wrot));
line(-7, 0, 7, 0);
pop();
push();
translate(this.x+22, this.y+30);
rotate(radians(wrot));
line(-7, 0, 7, 0);
pop();
push();
translate(this.x-45, this.y+30);
rotate(radians(wrot));
line(-7, 0, 7, 0);
pop();
push();
translate(this.x-29, this.y+30);
rotate(radians(wrot));
line(-7, 0, 7, 0);
pop();
wrot+=360/10;
}
noStroke();
fill(230, 230, 175);
ellipse(this.x-58, this.y+15, 7, 10);
rect(this.x-59, this.y+15, 5, 10, 3);
rect(this.x+57, this.y+21, 5, 7, 2);
fill(0);
strokeWeight(1);
text(this.txt, this.x, this.y+62);
}
function drawOnline() {
fill(200);
stroke(0);
push();
translate(this.x, this.y)
arc(-9, 10, 150, 16, radians(90), radians(270));
push();
translate(-25, 13);
rotate(radians(31));
arc(-6, 0, 40, 14, radians(270), radians(90));
circle(-6, 0, 14);
pop();
arc(55, 35, 45, 10, radians(90), radians(270));
push();
rotate(radians(31));
arc(10, 0, 150, 40, radians(175), radians(357));
rotate(radians(-6));
arc(10, 0, 150, 40, radians(4), radians(185));
noStroke();
ellipse(-60, -3, 10, 14);
stroke(0);
line(-65, -1, -65, -6);
rotate(radians(6));
strokeWeight(.5);
fill(150, 160, 200);
quad(-61, -6, -65, -1, -40, -1, -40, -6);
for (var r=0; r<10; r++) {
ellipse((10*r)-30, -7, 6, 7);
}
pop();
stroke(0);
fill(200);
push();
translate(52, 13);
rotate(radians(22));
beginShape();
vertex(0, 0);
vertex(0, 0);
curveVertex(15, -3);
vertex(30, -15);
vertex(30, 16);
vertex(30, 16);
endShape();
pop();
arc(70, 35, 45, 10, radians(260), radians(100));
arc(12, 8, 175, 20, radians(220), radians(0));
arc(12, 8, 175, 15, radians(0), radians(50));
push();
translate(25, 13);
rotate(radians(31));
arc(-10, 0, 40, 14, radians(270), radians(90));
circle(-10, 0, 14);
pop();
fill(0);
strokeWeight(1);
text(this.txt, 0, 62);
pop();
}
function drawLocal() {
square(this.x, this.y, 100);
noFill();
push();
translate(this.x, this.y);
fill(150, 170, 150);
stroke(0);
rect(0, 15, 100, 70);
stroke(125, 145, 125);
for(var l=0; l<11; l++) {
line(-49, -15+(l*6), 49, -15+(l*6));
}
stroke(0);
fill(150, 100, 50);
quad(-60, -20, 60, -20, 50, -50, -50, -50);
stroke(15, 75, 15);
fill(15, 75, 15);
rect(0, 37, 16, 25);
arc(0, 25, 16, 30, radians(180), radians(0));
stroke(0);
line(7, 30, 2, 30);
strokeWeight(.5);
fill(150, 160, 200);
rect(-30, 15, 30, 40);
rect(30, 15, 30, 40);
for (var m=0; m<3; m++) {
line(-38+(m*8), 35, -38+(m*8), -5);
line(38-(m*8), 35, 38-(m*8), -5);
line(-45, 5+(m*10), -15, 5+(m*10));
line(45, 5+(m*10), 15, 5+(m*10));
}
fill(180);
line(15, 15, 30, 25);
line(45, 15, 30, 25);
rect(30, 25, 15, 8);
line(-15, 15, -30, 25);
line(-45, 15, -30, 25);
rect(-30, 25, 15, 8);
noStroke()
fill(150, 0, 0);
textAlign(CENTER);
textSize(4);
text('OPEN!', -30, 26);
fill(0);
textSize(3);
text('Hours:', 28, 25);
stroke(0);
line(26, 26, 35, 26);
line(26, 27, 35, 27);
fill(100);
fill(0);
textSize(13);
strokeWeight(1);
text(this.txt, 0, 62);
pop();
}
My program depicts an iceberg that is melting, and presents the player with common choices that people have to make on a regular basis. The canvas reacts to the decisions that the player makes. The choices all have varying environmental impacts, and they correspond to the melting of the iceberg. If the player picks the environmentally more harmful choice, more of the ice falls into the ocean. If the player chooses an environmentally friendly option, the ice continues to melt at the same rate. This interactive program is not a winnable game. The ice will always melt. As it melts, a splash sound is played. **
I chose this design as my project because I wanted to highlight the way that industries pressure individuals to make good personal choices while producing products that only cause more damage. Individual choices will not stop climate change. To help preserve our planet, we need to rethink the entire system of the global enocomy.
The program must use a local server to run, and two sound files should be included in the folder to make the splashing noises when the ice melts. There are instructions included on the opening page.
I am really happy with how this project turned out. I only have a few choice that are presented to the player, but my goal was to make at least four sets of options, and that is what I have done. I screen recorded a majority of my process, and I have included a time-lapsed video at the bottom of this post.
** for the WordPress upload, my splash sound file was not working so I used a substitute file with a similar sound.