Final Project

wpf-final.js
//Patrick Fisher, section B, wpf assignment - 13

var bear; //object for the bear
var icebergs = []; //array of objects of icebergs
var middleIce; //variable the stores the position of the platform that is under the bear
var clouds = []; //array of objects of clouds
var score = 0; //score counter based on frame count and the amount of platforms passed

function setup() {
    createCanvas(480,480);
    background(113,147,231);
    bear = makeBear();
    var ib = newBerg(-60,0,120) //creates the starting platform which is the same everytime
    icebergs.push(ib);

    for(var i = 1; i <= 5; i++){ //creates new, random platofrms,
        icebergs.push(newBerg(-60 + (i * 250),floor(random(-20,0)),random(90,150)))
    }

    for(var i = 0; i <= 7; i++){ //aesthetic clouds at the top
        clouds.push(makeCloud(-60 + (i * 250)));
    }
    middleIce = {end: 60, y: 0}; //starting info for the platform that will have colision
}

function draw() {
    background(113,147,231); //sky
    fill(63,181,207);
    rect(0,300,width,height); //ocean

    fill(255,246,2); //sun
    circle(100,75, 50);
    
    push();
    fill(0);
    translate(width/2-75, 300);
    for(var i = 0; i <= 5; i ++){ //for loop to draw the icebergs
        if(icebergs[i].x <= 30 & icebergs[i].end >= -30){ //checks to see if theres a platform under the bear and if so stores it as middle ice
            middleIce.y = floor(icebergs[i].y);
            middleIce.end = floor(icebergs[i].end);
        }

        icebergs[i].draw();
    

        if(icebergs[i].x <= -600){ //deletes a iceberg from the array when it gets too far off screen and makes a new one
            icebergs.shift();
            icebergs.push(newBerg(900,random(-20,0),random(90,150)));

        }

    }
    if(middleIce.end <= -25){ //gets rid of middle ice after its gone past the bear
        middleIce.y = 200;
        score ++;

    }

    for(var i = 0; i <= 7; i++){ //draws clouds
        clouds[i].draw();
    }

    if(clouds.x <= -600){ //deletes a cloud from the array when it gets too far off screen and makes a new one
            clouds.shift();
            clouds.push(makeCloud(600));

        }

    if (bear.y >= 200) { //checks to see if the bear has fallen and if so starts the game over sequence
        bear.isAlive = false;
    }

    if(frameCount < 240){ //4 seconds of the text
        text("Press Space to Jump", 10, 30);
    }

    bear.draw(); 
    pop();

    if(bear.isAlive == false){ //game over sequencse
        background(0);
        fill(63,181,207);
        stroke(255);
        textSize(50);
        textAlign(CENTER);
        text("GAME OVER", width/2, height/2);
        textSize(40);
        text("SCORE: " + score.toString(), width/ 2, height/2 + 75);
        noLoop();
    }
}

function newBerg(bx,by,bw) { //constructor funtion to create icebergs
    var b = {x: bx, y: by, w: bw, end: bx+bw, half: bx + (bw / 2), draw: drawIce, speed: iceSpeed};
    return b;
}

function makeBear() { //constructor to make the bear
    var b = {x: 0, y: 0, dy: 0, isAlive: true, vestOn: false, draw: drawBear}
    return b;
}

function drawBear(){
    push();
    
    this.y += this.dy; //moves the bear down
    if(this.y >= middleIce.y - 3 & this.y <= middleIce.y){ //checks if the bear is over a platform
        this.dy = 0;
    }
    else{ 
        this.dy ++;
    }

    fill(214,207,193); //draws the bear
    legAni(this.x,this.y);
    ellipse(this.x,this.y-17,50,30);
    legAni(this.x + 2,this.y);
    ellipse(this.x+20,this.y-38,5,10);
    ellipse(this.x+30,this.y-38,5,10);
    circle(this.x+25,this.y-30,20);

    
    fill(0);
    circle(this.x+30,this.y-32,5);

    pop();
}

function drawIce() { //draws the ice
    push();
    fill(95,145,150);
    triangle(this.x,this.y,this.end,this.y,this.half, this.y + 160);
    fill(228,224,221);
    triangle(this.x,this.y,this.end,this.y,this.half, this.y - 90);
    push();
    strokeWeight(5);
    line(this.x,this.y,this.end,this.y);
    pop();
    pop();

    this.speed();

}

function keyPressed() { // press spacebar to jump
    if(keyCode ==  32){
        bear.dy = -10;
    }
}

function iceSpeed() { //function that moves and continually speeds up the icebergs every 30 seconds
    var o = floor(frameCount / (30*60));

    this.x -= o+1;
    this.end -= o+1;
    this.half -= o+1;
}

function makeCloud(cx){ //constructor for the clouds
    var c = {x: cx, y: (-350,-250), draw: drawCloud}
    return c;
}

function drawCloud(){ //function to draw the clouds
    push();
    fill(255);  //series of ellipses that draws the cloud
    ellipse(this.x,this.y,60,50);
    ellipse(this.x+30,this.y-10,60,50);
    ellipse(this.x+80,this.y,60,50);
    ellipse(this.x+20,this.y+20,60,50);
    ellipse(this.x+60,this.y+15,60,50);
    push();
    noStroke();
    ellipse(this.x+40,this.y+10,100,55)
    pop();
    pop();

    if(frameCount % 2 == 0){
        this.x --;
    }
}

function legAni(x,y){ //simple leg moving animation
    
    if(frameCount % 4 == 0){
        ellipse(x-18,y-8,10,20);
        ellipse(x+22,y-8,10,20);
    }

    if(frameCount % 4 == 1){
        ellipse(x-18,y-8,10,20);
        ellipse(x+21,y-8,10,20);
    }

    if(frameCount % 4 == 2){
        ellipse(x-17,y-8,10,20);
        ellipse(x+20,y-8,10,20);
    }

    if(frameCount % 4 == 3){
        ellipse(x-15,y-8,10,20);
        ellipse(x+19,y-8,10,20);
    }
}


For my project what inspired me was the polar ice caps melting and seeing pictures of polar bears literally having to jump across water to get to safety. So I decided to create a platform game that was that. It’s pretty simple, just press space to repeatedly jump and land on the next iceberg. The collision detection for the icebergs is very hit or miss, unfortunately. If I had more time I would want to figure out what is going wrong with it as when debugging I could see that the values for the bear and the iceberg I was comparing were equal and yet the bear did not stop falling. Additionally, I had more time I would add a sort of extra life feature, described in my design documents as a life preserver, make the icebergs sink once landed on, and make the bear fully controllable rather than the game being an auto scroller.

Final Project – conniek

My program is a game that covers the theme of climate change. The player gets to freely control an iceberg across a body of water that will try to collect 7 renewable energy to increase in size and win. However, if it hits a fossil fuel in the form of pollution, it will break resulting in the player losing. I was inspired by the snake game, but I decided to change some elements. Instead, there is an obstacle, the pollution, that bounces around the canvas, the iceberg gets bigger than longer, and the iceberg gets to move freely rather than straight lines. If I had more time, I would’ve added different types of renewable energy, so that whenever it spawns or respawns it would be a different renewable energy. I just have the water renewable energy that represents hydropower energy in my program. I would have also added a moving and animating element in the water to make it seem like the ocean was moving, I would have made the iceberg have more detail like ripples as it moves across the water, and also maybe some sounds. If I could, I would also have included more secure randomization in the movement of the obstacle.

Final Project

sketchDownload

//Yanina Shavialenka
//Section B

var numPressed = 1; //Counts number pressed
var r = 174;
var g = 198;
var b = 207;
var cycle = false; //records whether a cycle has occured

//Picture variables
var earth;
var hand;
var airplane;
var car;
var beach;
var factory;
var smoke;
var deforestation;

//Array of pictures and objects
var thermometer = [];
var loadTherm = [];
var planes = [];
var hands = [];
var loadHand = [];
var loadSmokes = [];
var texts = [];

//Function that preloads images
function preload() {
    hand = loadImage("https://i.imgur.com/yj0wtAM.png");
    earth = loadImage("https://i.imgur.com/kHdVss0.png");
    airplane = loadImage("https://i.imgur.com/5UTfPON.png");
    car = loadImage("https://i.imgur.com/FFnoxXk.png");
    beach = loadImage("https://i.imgur.com/vpAjq6W.jpg");
    factory = loadImage("https://i.imgur.com/UAwSjh7.png");
    arrow = loadImage("https://i.imgur.com/QALHzw2.png");
    smoke = loadImage("https://i.imgur.com/RH9Ikd8.png");
    deforestation = loadImage("https://i.imgur.com/ybzFc92.jpg");

    var thermFiles = [];
    thermFiles[0] = "https://i.imgur.com/Gbbbv1a.png";
    thermFiles[1] = "https://i.imgur.com/SFaNzVE.png";
    thermFiles[2] = "https://i.imgur.com/FqY5tgi.png";
    thermFiles[3] = "https://i.imgur.com/BR7AC3a.png";
    thermFiles[4] = "https://i.imgur.com/tsBaLsK.png";
    thermFiles[5] = "https://i.imgur.com/QQs5VxM.png";

    for(var i = 0 ; i < thermFiles.length ; i++) {
        thermometer[i] = loadImage(thermFiles[i]);
    }

    var handFiles = [];
    handFiles[0] = "https://i.imgur.com/V3shALS.png";
    handFiles[1] = "https://i.imgur.com/qWRT7Nb.png";
    handFiles[2] = "https://i.imgur.com/obwct4k.png";
    handFiles[3] = "https://i.imgur.com/GwpjItB.png";
    handFiles[4] = "https://i.imgur.com/ip5YRk2.png";
    handFiles[5] = "https://i.imgur.com/sYgwV8p.png";

    for(var i = 0 ; i < handFiles.length ; i++) {
        hands[i] = loadImage(handFiles[i]);
    }
}

//Functions that make objects to specific images
function makeThermometer(num) {
    var c = { x: 85, y: 150, imageNum: num,
            drawFunction: drawThermometer
    }
    return c;
}

function makeHand(num) {
    var c = { x: 265, y: 350, imageNum: num,
            drawFunc: drawHand
    }
    return c;
}

function makeSmoke(x1,y1) {
    var c = { x: x1, y: y1,
            drawFun: drawSmoke,
            stepFun: stepSmoke
    }
    return c;
}

//Functions that draw objects
function drawThermometer() {
    image(thermometer[this.imageNum],this.x,this.y);
}

function drawHand() {
    image(hands[this.imageNum],this.x,this.y);
}

function drawSmoke() {
    image(smoke,this.x,this.y);
}

//Function that moves smoke at specific intervals
function stepSmoke() {
    if(numPressed == 2){
        this.x += 0.1;
        this.y += 1;
    }
    if(numPressed == 3){
        this.y += 1;
    }
    if(numPressed == 4){
        this.x -= 0.15;
        this.y += 1;
    }
    if(numPressed == 5){
        this.x -= 0.5;
        this.y += 1;
    }
}

//Loads canvas and initial objects
function setup() {
    createCanvas(600, 600);
    background(r,g,b);
    loadTherm.push(makeThermometer(0));
    loadHand.push(makeHand(0));
    initialSmokes();
}

function draw() {
    imageMode(CENTER);

    //Resizes objects
    airplane.resize(140,125);
    car.resize(80,45);
    factory.resize(145, 65);
    deforestation.resize(80, 80);
    beach.resize(100, 80);
    smoke.resize(40,100);

    //Square that helps with not stacking new objects over initial
    fill(174,198,207);
    square(0,0,600);
    noFill();

    //Resizes all Thermometers
    for(var i = 0 ; i < thermometer.length ; i++) {
        thermometer[i].resize(300,300);
    }

    //Draws functions
    for(var i = 0 ; i < loadTherm.length ; i++) {
        loadTherm[i].drawFunction();
        loadTherm.splice(0,loadTherm.length-1); //Deletes previous thermometers to not overlap
    }

    //Draws hand
    for(var i = 0 ; i < loadHand.length ; i++) {
        loadHand[i].drawFunc();
    }

    //Remakes initial smoke objects if cycle is completed
    if(cycle) {
        initialSmokes();
        cycle = false;
    }
    
    image(earth,300,420);
    image(airplane, 140, 100);
    image(car, 210, 80);
    image(factory, 300, 55);
    push();
    rotate(radians(7));
    image(deforestation, 400, 20);
    image(beach, 500, 100);
    pop();
    fill(0);
    textSize(18);
    texts.push(text('4 Main Components:',430,450));
    noFill();

    //Draws smokes objects
    for(var i = 0 ; i < loadSmokes.length ; i++) {
        loadSmokes[i].drawFun();
    }

    //Moves smoke and text based on number pressed condition
    if(numPressed == 2) {
        fill(0);
        textSize(16);
        texts.push(text('•Transportation',430,470))
        noFill();
        while( loadSmokes[numPressed - 2].y < 340 ){
            loadSmokes[numPressed - 2].stepFun();
            loadSmokes[numPressed - 2].drawFun();
        }
    }
    if(numPressed == 3) {
        fill(0);
        textSize(16);
        texts.push(text('•Factories',430,480))
        noFill();
        while( loadSmokes[numPressed - 2].y < 320 ){
            loadSmokes[numPressed - 2].stepFun();
            loadSmokes[numPressed - 2].drawFun();
        }
    }
    if(numPressed == 4) {
        fill(0);
        textSize(16);
        texts.push(text('•Deforestation',430,490))
        noFill();
        while( loadSmokes[numPressed - 2].y < 330 ){
            loadSmokes[numPressed - 2].stepFun();
            loadSmokes[numPressed - 2].drawFun();
        }
    }
    if(numPressed == 5) {
        fill(0);
        textSize(16);
        texts.push(text('•Other livelihoods',430,500))
        noFill();
        while( loadSmokes[numPressed - 2].y < 370 ){
            loadSmokes[numPressed - 2].stepFun();
            loadSmokes[numPressed - 2].drawFun();
        }
    }
}
function keyTyped() {
    //Resets smokes and changes cycle to true to show that a cycle has occured
    if(numPressed == 0){
        loadSmokes.splice(0,loadSmokes.length);
        cycle = true; 
    }
    //Changes thermometer and hand to next image
    if(key == 'g' || key == 'G') {
        print(numPressed);
        loadTherm.push(makeThermometer(numPressed));
        loadHand.push(makeHand(numPressed));
        loadTherm.splice(0,loadTherm.length-1); //Deletes previous thermometers to not overlap
        numPressed++;
    }
    //Resests after cycle
    if(numPressed == 6){
        numPressed = 0;
    }
}

//Function to draw initial smokes
function initialSmokes() {
    loadSmokes.push(makeSmoke(210,140));
    loadSmokes.push(makeSmoke(295,130));
    loadSmokes.push(makeSmoke(380,145));
    loadSmokes.push(makeSmoke(460,240));
}

This final project’s theme is climate change and I decided to show in my work, an interactive image, how human actions affect the Earth and cause climate change. In the image, you can see a picture of a human palm inside of which there’s our planet Earth – this represents the idea that everything is in our hands and that everything we do affects our planet: we can either save it and give it protection or kill it. Either way, everything depends on us. On the first four fingers, from pointer to pinky, we can see the smoke of evaporation coming down from top to middle towards the Earth and each finger in this group of four represents four components that cause global climate change: transportation such as cars and planes, factories, deforestation, and other livelihoods of a person such as construction works, food, the garbage that isn’t getting recycled, increased use of electricity, etc. Starting from the pointer finger, an interactive image will start working when a user clicks on a key “g” or “G” which stands for “Go”, the first smoke will go down towards the Earth and the arrow on the thumb will make a small step towards the thermometer which increases in temperature. Moreover, with every click we can see the name of each component pop up on the screen to tell the user what it is. Then when the user clicks on the key again, the second smoke will slide down towards the Earth, the arrow makes another step, and the temperature gets higher. The same thing will happen to the third and fourth click. However, when the user clicks on the key fifth time, the arrow on the thumb will make the final step from the Earth towards to top of the finger which will make the temperature on the thermometer fill to the top which represents the maximum hotness. This project shows that those four human components affect the Earth in a negative way and when we combine them all together, it increases the speed with which the temperature gets higher.
I was inspired to do this project because as a little girl I always liked winters due to a big amount of snow: I would go snow sliding to the hills with my family every year and it was so much fun! However, in the past few winters, there were only a few days when it snowed meaning our Earth is getting warmer day by day and we cannot do some of our favorite winter activities anymore.
If I had more time to do this project then I would have added more pictures such as I would do more research to find more components that affect the Earth but so far I decided to stick with 4 big, main, and obvious factors.

Week 14: Final Project: Trash Removal

My Final Project Modified for WordPress

//Chuong Truong;
//cbtruong;
//FINAL PROJECT;
//Modified for WordPress;

//array that holds all existing trash objects;
var trashPieces = [];

//this array holds all of the indices of trash objects that have been clicked on - removed;
//then it uses the splice method of arrays to remove that object 
//and erase it from the trashPieces array;
//and the screen as well;
//this effectively removes it;
var trashPiecesRemoval = [];

//gameOver condition that is used for the game overall;
//when true it ends the game and transfers the screen to facts;
var gameOver = false;

//number of current trash objects on screen;
var trashNumCurrent = 0;

//number of trash objects removed;
var trashGone = 0;

//variables that holds the time;
//numSecondsPast is how many seconds have passed;
var numSecondsPast = 0;
//while numSecondsAllowed is how many seconds are left for the player;
//the initial number of seconds allowed for the player is 120 or 2 minutes;
//the reason for two seperate variables is more flexibility for time as a feature;
var numSecondsAllowed = 120;
//the frameCount variable needed for the timer Function that counts time;
var frameCount = 0;

//the variable that determines how many trash objects can be drawn at a time;
var spawnNum = 20;

function setup() {
    //modified canvas size;
    createCanvas(600, 600);
    //creates sea background;
    background(91, 161, 176);
    
    //creates the first initial trash objects;
    for (var l = 0; l < 20; l++){
        makeTrash(random(80, 520), random(80, 520), floor(random(5)), 
            floor(random(0,8)), floor(random(0,8)), random(360), true);
    }


    //sets the frameRate to 30;
    frameRate(30);
    
}

function draw() {
    //calls the display function;
    displays();
    
    //print method used for debugging, it shows how many seconds have passed;
    print(numSecondsPast);
    //increases the frameCount every iteration;
    frameCount++;

    //calls the countTime function that counts the time;
    countTime(frameCount);
    
    //This is the main checker for whether the game is over or not;
    //Namely, it checks for if the time left is 0 or not by way of comparing;
    //the number of seconds allowed - numSecondsAllowed;
    //and the number of seconds that have passed - numSecondsPast;
    //if there is still time, then gameOver is false;
    //And the game runs as usual;
    if (numSecondsAllowed > numSecondsPast){
        gameOver = false;
        //draws all of the existing trash objects;
        for (var m = 0; m < trashNumCurrent; m++){
            var pT = trashPieces[m];
            pT.drawFunction();
        }
    
        //removes any trash objects deemed nonexistant;
        //also uses background to reset the drawing board and removed previous 'drawings' of the object;
        for (var r = 0; r < trashPiecesRemoval.length; r++){
            background(91, 161, 176);
            trashGone++;
            trashPieces.splice(trashPiecesRemoval[r], 1);
        }

        //completely wipes out the trashPiecesRemoval array to allow it to be filled with indices again;
        while (trashPiecesRemoval.length > 0){
           trashPiecesRemoval.shift();
        }
        
        //calls the spawnMoreTrash function;
        spawnMoreTrash();
        }
        //if the time left is 0, then it calls the factScreen function that ends the game;
        else {
            factScreen(facts(floor(random(0, 9))));
    }

    //prints out the current trashPieces array length for debugging;
    trashNumCurrent = trashPieces.length;
    print(trashPieces.length);
    
    //this switch and case checks for the total amount of trash removed;
    //if it passes certain milestones, the spawnNum of trash increases with a one time added bonous of more time;
    switch (trashGone){
        case 40: spawnNum = 25; numSecondsAllowed + 60; break;
        case 80: spawnNum = 30; numSecondsAllowed + 50; break;
        case 120: spawnNum = 35; numSecondsAllowed + 40; break;
        case 1600: spawnNum = 40; numSecondsAllowed + 30; break;
    }

}

//draws the scoreboards, title, time left, and directions;
function displays (){
    stroke(1);
    strokeWeight(0.5);

    //code for top left display of trash removed and trash left;
    fill(255);
    rect(10, 10, 150, 45);

    fill(0);
    var trashNumDisplay = 'Trash Left: ' + trashNumCurrent;
    text(trashNumDisplay, 15, 45);
    var scoreDisplay = 'Trash Removed: ' + trashGone;
    text(scoreDisplay, 15, 25);

    //code for upper middle display of the title of the game;
    fill(240, 133, 11);
    rect(276.5, 15, 100, 35);
    
    fill(0);
    text("Trash-Pick-Up", 285.5, 35);

    //code for upper right display of time left for trash removal;
    fill(255);
    rect(510, 10, 80, 35);

    fill(0);
    var timeLeftDisplay = 'Time: ' + (numSecondsAllowed - numSecondsPast);
    text(timeLeftDisplay, 520, 32.5);

    //code that gives the game directions;
    fill(200, 186, 234);
    rect(60, 555, 480, 40);

    fill(0);
    var directions = 'Click on the red dots to remove the trash before time runs out!  Watch out for misclicks!';  
    var directions2 = 'If you do not see any trash but the trash left is not 0, hit any key to respawn them!';
    text(directions, 65, 570);
    text(directions2, 65, 585);
}


//All of the code below was originally in seperate files to ensure readability and ease of access;
//Due to WordPress, I had to combine all 4 files into 1;

//file that creates the trash objects;

//constructor for the trash object;
//it takes 6 numbers and a boolean value;
//xPost and yPos is the object's main position as it is the first vertex in a given object;
//each object is a randomly constructed shape made with the beginShape() and endShape() function;
//it then takes cPre, a random number that determines its color;
//After that comes the "random points" - which are random numbers added or subtracted to the starting vertex;
//These numbers are stored in an array;
//There are 2 sets of 8 different arrays, one for x and one for y;
//ang is the angling of each object;
//existBol is the boolean value that determines if the object still exists or not;
//it has a drawFunction, drawTrash which handles the drawing;
//it also has a changeFunction. mousePressed, which changes its state as an instance still on the screen;
//and as an existant object within any of the arrays;
function makeTrash (xPos, yPos, cPre, pointsPresetX, pointsPresetY, ang, existBol){
    var t = {x: xPos, y: yPos, col: cPre, 
        pXA: pointsPresetX, pYA: pointsPresetY,
        a: ang, e: existBol, 
        drawFunction: drawTrash, changeFunction: mousePressed};
    trashPieces.push(t);
}

//the drawTrash function is the drawFunction of each trash object;
function drawTrash (){
    //this initial condition decides if it is still on screen (being drawn);
    if (this.e == true){
        stroke(0);

        //switch and case for the color of a given trash object;
        switch (this.col) {
            case 0: fill(228, 200, 98); break;
            case 1: fill(169, 142, 144); break;
            case 2: fill(156, 161, 117); break;
            case 3: fill(135, 206, 250); break;
            case 4: fill(255, 255, 255); break;
        }
  
        //this creates each object, by using beginShape() and endShape(), with numbers that are added to the original vertex;
        //a 7 pointed shape is made;
        //Due to the presence of 8 arrays and a seperate number that determines which array is for x and for y, there are 64 possible combinations;
        //The numbers for each array set is entered and it returns an array to be used for each specific trash object;

        //for the x values added to the original vertex;
        switch(this.pXA){
            case 0: var x = [20, -30, 10, 50, -60, 70]; break;
            case 1: var x = [30, -40, 40, 20, 30, 50]; break;
            case 2: var x = [50, -60, 25, 65, -35, 40]; break;
            case 3: var x = [-30, 70, -30, 40, -25, 65]; break;
            case 4: var x = [20, 30, 10, -50, 60, 30]; break;
            case 5: var x = [60, -20, 35, 20, 45, -20]; break;
            case 6: var x = [-20, 30, 10, -50, 60, 30]; break;
            case 7: var x = [60, -20, 35, 20, 45, -20]; break;
        }
        //for the y values added to the original vertex;
        switch(this.pYA){
           case 0: var y = [40, 30, 10, -25, 30, 20]; break;
           case 1: var y = [35, 25, 10, 50, -70, -40]; break;
           case 2: var y = [20, -0, 10, -10, 40, 20]; break;
           case 3: var y = [-30, 50, 20, 25, 25, -30]; break;
           case 4: var y = [20, 35, -25, -35, 20, 10]; break;
           case 5: var y = [30, -45, 20, -45, 35, 40]; break;
           case 6: var y = [40, 35, 30, -40, 60, -50]; break;
           case 7: var y = [-50, -10, 20, 35, 40, 30]; break;
        }
    
        //with the color and vertex arrays determined, the actual shape is made;
        //it is put within a push and pop for extra variation by way of rotation;
        //the actual tricks for rotation are then applied;
        push();
        translate(this.x, this.y);
        rotate(radians(this.a));
        beginShape();
        vertex(0, 0);
        for (var i = 0; i < 8; i++){
            vertex(0 + x[i], 0+ y[i]);  
        }
        endShape(CLOSE);
        //an additional red circle is added at the original vertex to make it easier to click on;
        fill(255, 0, 0);
        circle(0, 0, 5);
        pop();
    }
}

//this function is the function that changes each object;
//it decides whether each object still exists or not after each click;
function mousePressed() {
    //I made the mouseX and mouseY coordinates into mX and mY respectively for easier typing;
    var mX = mouseX;
    var mY = mouseY;
    
    //the flag variable that becomes true if the player clicks on anything but a trash object's red dot;
    //it is false at the beginning to ensure that a new click is not automatically a misclick;
    var secondOff = false;

    //as the player clicks the mouse, a for loop checks the entire trashPieces array - which;
    //holds all of the existing trashPieces;
    //it checks whether mX and mY are close to the original x and y of any given trash;
    //if the distance is less than 30, then it sets the specific trash object to false;
    //it then pushes the object's index into the trashPiecesRemoval array;
    //this array holds all of the indices of trash objects that have been clicked on - removed;
    //then it uses the splice method of arrays to remove that object and erase it from the trashPieces array;
    //and the screen as well;
    //this effectively removes it;
    for (var i = 0; i < trashPieces.length; i++){
        var rI = i;
        pT = trashPieces[i];
        if (dist(mX, mY, pT.x, pT.y) < 10){
            pT.e = false;
            trashPiecesRemoval.push(rI);
        }
        //if the player clicks and does not remove a piece of trash, it sets the flag variable called secondOff;
        //this in turn makes the following if statement outside of the for loop execute, taking a second off the clock;
        else {
            secondOff = true;
        }
    }
    
    //this function takes a second off of the clock for misclicks;
    if (secondOff == true){
        numSecondsPast++;
    }
}

//this function spawns more trash everytime all of the trash has been removed and the trashPieces array is empty;
function spawnMoreTrash (){
    //it checks to see if the game is over;
    //if true it executes the rest of the code;
    if (gameOver != true){
        //it checks if trashPieces is empty;
        //if true, it creates more trash according to the spawnNum variable;
        if (trashPieces.length == 0){
            for (var l = 0; l < spawnNum; l++){
                makeTrash(random(80, 620), random(80, 520), floor(random(5)), 
                floor(random(0,8)), floor(random(0,8)), random(360), true);
            }
            //this adds more time once a new set of trash has been spawned;
            numSecondsAllowed = numSecondsAllowed + (spawnNum - 10);
            //this gives a change of randomly increasing the spawnNum as well;
            if (floor(random(51)) > 25){
                spawnNum += 2;
            }
        }
    }
}

//a vital function, the keyPress function resets the board;
//Once any key is pressed, the board is redrawn with the same amount of trash pieces left;
//as well as the same amount of time left;
//this is key as there are times where a glitch occurs where all but one or two trash pieces;
//are drawn - meaning they cannot progress as the time winds down;
//Due to not being drawn, the player unfairly loses due to the glitch;
//this keyPress function prevents this by redrawing the board with the same amount of time and trash;
function keyPressed(){
    //this variable is the total amount of trash that has to be redrawn, it is made 0;
    //to ensure that everytime it is called, the number of trash that needs to be redrawn is allowed to change;
    var trashLeftReset = 0;

    //This for loop does the same thing as the loop that removes clicked-on trash;
    //instead of specifically clicked on trash, it removes all of them;
    //It counts how many were removed;
    //Due to this being intended for trash objects that do not appear;
    //It initiates the first step of redrawing them on the board;
    //Therefore, if used for any other purpose, such as cheating, it does nothing but reset the board;
    for (var i = 0; i < trashPieces.length; i++){
        pT = trashPieces[i];
        trashPiecesRemoval.push(pT);
        //this variable offsets the fact that everytime trash is removed, the trash removal counter goes up;
        //this is to prevent cheating as well as the trashGone variable is key for other conditions;
        trashGone--;
        
        //for each piece of trash removed, the counter for trash that needs to be redrawn goes up as well;
        //this is for the following for loop that draws any undrawn trash objects;
        trashLeftReset++;
    }

    //this for loop does the second step of redrawing the board, namely drawing any unremoved and undrawn trash pieces;
    //albiet as a different object altogether;
    for (var l = 0; l < trashLeftReset; l++){
        makeTrash(random(80, 620), random(80, 520), floor(random(5)), 
        floor(random(0,8)), floor(random(0,8)), random(360), true);
    }
}

//separate code file that deals with writing out the facts after the player loses;

//the facts function itself takes a random number and then uses a case and switch for;
//the corresponding fact related to pollution in the ocean;
//I chose to use case and switch due to its simplicity;
function facts (inputNum){
    var factString = "";
    switch(inputNum) {
        case 0: factString = "We dump 8 million tons or 17.6 billion pounds of \nplastic into oceans every year."; return factString; break;
        case 1: factString = "Plastics are responsible for over 80% of the negative \neffects on sea animals."; return factString; break;
        case 2: factString = "By 2050, estimations say that there will be more \nplastic than fish in the ocean when it comes to \nweight alone."; return factString; break;
        case 3: factString = "Over 100,000 marine animals die from eating plastic \nor being trapped by it every year."; return factString; break;
        case 4: factString = "Plastic takes approximately 400 years to degrade\n - when it does in the ocean, more harmful chemicals\n are released."; return factString; break;
        case 5: factString = "Around 70% of ocean garbage are uncleanable \nbecause they sink into the seabed."; return factString; break;
        case 6: factString = "90% of seabirds have plastics in their stomachs."; return factString; break;
        case 7: factString = "300 million tons of plastic is created \nevery year - about 50% is single use."; return factString; break;
        case 8: factString = "Microplastics have been found in Arctic sea ice."; return factString; break;
    }     
}

//related to facts, it takes the fact string and uses it as text;
//this function is the function that causes the game to end;
//it draws the relevant screen and ends the game with a noLoop() call;
function factScreen (factInput){
    background(53, 56, 57);
    fill(255);
    strokeWeight(2);
    stroke(255, 0, 0);
    rect(200, 270, 300, 60);
    stroke(0);
    strokeWeight(0.5);
    fill(0);
    text(factInput, 210, 290);
    stroke(255);
    noLoop();
}


//facts cited from:
//https://www.conservation.org/stories/ocean-pollution-11-facts-you-need-to-know
//https://www.rubicon.com/blog/ocean-pollution-facts/
//https://www.conserve-energy-future.com/various-ocean-pollution-facts.php
//https://www.condorferries.co.uk/marine-ocean-pollution-statistics-facts
//https://www.ehn.org/ocean-plastic-pollution-2654378379/what-can-be-done


//code for the timer that is utilized in the game as a condition for losing;
//the function takes the input of the frameNumber - which is the count of;
//every iteration of the draw loop (the main loop of the game);
//everytime the frameNumber hits 60, numSecondsPast is increased by 1;
//the function also takes the a boolean variable called resetBoolean;
//if the boolean entered is true, it resets the global variable numSecondsPast to 0;
//this is to ensure that everytime a new timer is set, the number of seconds passed 
//is also reset;

function countTime (frameNumber){
    if ((frameNumber % 60) == 0){
        numSecondsPast++;
    }
}


//I got the inspiration for the timer from a program called "countdown timer"
//by user marynotari on the p5js.org site;
//the link for the code: https://editor.p5js.org/marynotari/sketches/S1T2ZTMp-

[Note, I have modified my Project to make it functional for WordPress, the original Canvas size was meant to be 700 by 600, but had to be changed to 600 to 600, therefore, many values regarding specific spots on the canvas has been changed.]

For inspiration, I ran through what I knew about climate change.
Rather than focusing on ways to combat it, I really wanted to tell the effects of it. So, I decided to make an interactive game that showed the depressing facts about ocean pollution. Most of the facts deal with plastics, which are the main objects of the game, the trash objects are supposed to represent.

The game is a simple score as high as possible before time runs out.
The player is given initially 20 trash pieces on a screen and must click on them (the red dots that is their origin as they are shapes made with the beginShape() function). By clicking on them, they are removed and once the number of trash that needs to be removed hits 0, a new set is spawned (if any are undrawn, clicking a key will spawn them in by redrawing the board). Furthermore, there is a timer, so if time runs out (and it always will) the player loses. If any of their clicks are not on the red origin of a trash object, then they have a second deducted from their time. Once losing, they face a black screen with a single text block that tells a fact about ocean pollution.

The fact that the trash is hard to click on is meant to show how hard it is to clean up/fight ocean pollution once it has made its way fully into the ocean. Furthermore, the time limit and countdown are meant to show that we really need to fix ocean pollution now. Finally, the spawning of trash (with the number of a set increasing certain times) is meant to show how the problem is becoming worse and worse. Overall, the program is meant to show that ocean pollution is something that we must fix now because the problem is truly getting worse and harder to solve.

If I had more time, I would have added extra features like making it so that trash can “dissappear” meaning that they are no longer removable/clean-upable, just like in real life as trash in the ocean sink to the seafloor and are impossible to remove. I would’ve also found a way for “true” randomization of the trash, as right now the trash is 7-point polygons that have a set number of versions (64). True randomization is a variable number of points in each polygon and where those points are relation to the original vertex.

I hope you enjoyed my project!

I got the ocean pollution facts from:
https://www.conservation.org/stories/ocean-pollution-11-facts-you-need-to-know
https://www.rubicon.com/blog/ocean-pollution-facts/
https://www.conserve-energy-future.com/various-ocean-pollution-facts.php
https://www.condorferries.co.uk/marine-ocean-pollution-statistics-facts
https://www.ehn.org/ocean-plastic-pollution-2654378379/what-can-be-done

Capitalism is Killing the Planet

sketch

Hey! My idea for this project was to make a few digital climate action “posters”. I had a lot of fun with these and ended up making three that shuffle as you click the mouse:

Make Polluters Pay:

This poster generates smoke objects with random size and transparency from chimnies (that also represent bar graphs to show increasing global temperatures). The smoke obscures the message that shows who is responsible for polluting the earth, while leaving a greenwashed corporate message still visible.

Capitalism is Killing the Planet:

The second poster is supposed to show advanced capitalism’s ability to mask crises behind the veil of economic stability. As you move the mouse towards the top right-hand corner one of the triangles becomes more chaotic while the second one in front remains still. I included a Joseph Schumpeter line that captures this pretty well.

California Wildfires:

The last poster reads from a csv file of the 2020 CA wildfires. Each location is mapped to the canvas and then randomly generated circles flash around it to create the fires.

I hope you enjoy!!

var numPosters = 3;
var poster = 0;
var firstClick;

//smoke vars
var smoke = [];

var dx = 5;
var dy = 7;

var impact;

//fire vars
    //data variables
var fires;
var numRows;

var bgx = []; //background coordinates
var bgy = [];

    //rectangle in center
var margin;
var rectX;
var rectY;

    //canvas
var marginT;
var marginS;

    //colors
var tanColor;
var textRed;

//capitalism vars
var triangleRand;

var barcode
var barcodeWidth = 100;

var bottomTextCA;
var mainTextCA;
var topTextCA;

var bottomBottomTextCap;
var topTextCap;

var smokeBG;

function preload() {
    //uncomment for local
    //used fonts in original file, replaced with images for wordpress bcs of file issues
    /*
    dosis = loadFont('fonts/Dosis-ExtraBold.ttf');
    dosisL = loadFont('fonts/Dosis-Light.ttf');
    gothic = loadFont('fonts/LetterGothicStd.otf');
    akkordeon = loadFont('fonts/Akkordeon.otf');
    impact = loadFont('fonts/impact.ttf');
    

    fires = loadTable('data/2021cafires2.csv', 'header');

    bottomTextCAImg = loadImage('img/CAfiresBottomText.png');
    mainTextCAImg = loadImage('img/CAfiresMainText.png');
    topTextCAImg = loadImage('img/CAfiresTopText.png');

    bottomMainTextCapImg = loadImage('img/CapBotttomMainText.png');
    topTextCapImg = loadImage('img/capTopText.png');

    smokeBG = loadImage('img/smokeBG.png');
    */
    //uncomment for WP

    fires = loadTable('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/2021cafires2.csv', 'header');
    barcode = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/barcode.png');
    bottomTextCAImg = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/CAfiresBottomText.png');
    mainTextCAImg = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/CAfiresMainText.png');
    topTextCAImg = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/CAfiresTopText.png');

    bottomMainTextCapImg = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/CapBotttomMainText.png');
    topTextCapImg = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/capTopText.png');

    smokeBG = loadImage('https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/smokeBG.png');

}

function setup() {
    firstClick = true;

    //smoke
    createCanvas(400,600);
    background(220);

    //fires
    noStroke();
    numRows = fires.getRowCount();
    background('black');
    //frameRate(16);

    marginS = 15;
    marginT = 1.5*marginS;
    rectX = width-2*marginS;
    rectY = 500;

    tanColor = color(230, 226, 220);
    textRed = color(255,50,0);

    //storeBackground();
}

function draw() {
    switch (poster) {
        case 0:
            push();
            smokePoster();
            pop();
            break;
        case 1:
            push();
            capitalismPoster();
            pop();
            break;
        case 2:
            push();
            cafiresPoster();
            pop();
            break;
    }

    if (firstClick) {
        push();
        fill(0, 0, 0, 200);
        rectMode(CENTER);
        rect(width/2, height-10, width, 30);
        fill(textRed);
        textSize(22);
        textAlign(CENTER, CENTER)
        text('click to browse through the posters', width/2, height-10);
        pop();
    } else {
        return;
    }
}

function mousePressed() {
    poster += 1;
    if (poster == numPosters) {
        poster = 0;
    }
    firstClick = false;
    print(firstClick.toString());
}

//smoke functions untill line 112
function drawBars() {
    fill('black');
    var w = 60;
    var h;
    for (var i = 0; i < 5; i++) {
        h = map(exp(i), 0, exp(4), 0, height*0.8);
        rect(22+75*i, height - h, w, h);
    }
}

function writeText() {
    var textRed = color(138, 76, 76);
    var textGreen = color(128, 194, 129);

    image(smokeBG, 0, 0);

    /*
    push();
    //translate(0, 0.3*height);
    textSize(64);
    fill(textRed);
    //textFont(impact);
    text('CORPORATIONS', 10, 60);
    text('WARM OUR', 10, 120);  fill(textGreen); text('WE ARE', 300, 120);      fill(textRed);
    text('PLANET!', 10, 180);   fill(textGreen); text('ARE PURSUING', 220, 180);fill(textRed);
    text('MAKE', 10, 240);      fill(textGreen); text('ACTIVELY', 170, 240);    fill(textRed);
    text('POLLUTERS', 10, 300); fill(textGreen); text('WORKING', 300, 300);     fill(textRed);
    text('PAY!', 10, 360);      fill(textGreen); text('TO REDUCE', 140, 360);
    text('OUR CARBON FOOTPRINT', 10, 420);
    text('FOOTPRINT BY EXPLORING', 10, 480);
    text('EXPLORING FREE', 10, 540);
    text('MARKET SOLUTIONS', 10, 600);

    //textSize(30);
    //text('CARBON DIVIDEND NOW', 10, 240)
    pop();
    */
}

function makeSmoke(birthX, birthY) {
    var smoke = {x: birthX,
                y: birthY,
                r: 5,
                t: random(0, 70),
                speedX: random(1,3),
                speedY: random(3,5),
                move: smokeMove,
                display: smokeDisplay}
    return smoke;
}

function smokeDisplay() {
    push();
    translate(this.x, this.y);
    noStroke();
    fill(100, 100, 100, this.t);
    ellipse(0, 0, this.r);
    pop();
}

function smokeMove() {
    this.x -= this.speedX;
    this.y -= this.speedY;
    this.r += random(this.speedX, this.speedY)-1;
}

function newSmoke(colX, colY) {
    var prob = 0.3;
    if (random(0,1) < prob) {
        smoke.push(makeSmoke(random(colX, colX+60), colY+10));
    }
}

function removeSmoke(){
    var smokeToKeep = [];
    for (var i = 0; i < smoke.length; i++){
        if (smoke[i].x > -100) {
            smokeToKeep.push(smoke[i]);
        }
    }
    smoke = smokeToKeep;
}

function updateAndDisplaySmoke(){
    for (var i = 0; i < smoke.length; i++){
        smoke[i].move();
        smoke[i].display();
    }
}

function smokePoster() {
    background(220);

    writeText();

    updateAndDisplaySmoke();
    removeSmoke();
    for (var i = 2; i < 5; i++) {
        h = map(exp(i), 0, exp(4), 0, height*0.8);
        newSmoke(25+75*i, height - h);
    }

    drawBars();
}

//CA fires functions
function drawCircles(lat, long, size) {
    for (var j = 0; j < 2; j++) {
        fill(255, random(0, 140), 0);
        ellipse(lat + random(-3, 3),
                long - random(0, 7),
                random(0, 12));
    }
    //filter(BLUR,5);
    //fill('red');
    //ellipse(lat, long, size);
}

function topText() {
    image(topTextCAImg, 0, 0);

    /*
    //textFont('dosis');
    textSize(10);
    fill(255,50,0);

    textAlign(LEFT, CENTER);    text('2020', marginS, marginT/2);
    textAlign(CENTER, CENTER);  text('CALIFORNIA WILDFIRES', width/2, marginT/2)
    textAlign(RIGHT, CENTER);   text('WFIGS', width-marginS, marginT/2);
    */
}

function mainText() {
    image(mainTextCAImg, marginS, marginT + rectY - mainTextCAImg.height);
    /*
    textSize(60);
    //textFont('akkordeon');
    textStyle(NORMAL);
    fill(tanColor);
    textAlign(LEFT, BOTTOM);

    push();

    translate(marginS, marginT+rectY);

    var offset = 0;

    text("WHOSE", 10, -3*45);
    text("LAND", 10, -2*45);
    text("ARE WE", 10, -45);
    text("BURNING?", 10, 0);

    pop();
    */
}

//not used
function movingText() {
    push();
    //rotate(radians(90));

    textSize(30);
    textFont('impact');
    fill('red');
    text("thoughts and prayers", xText1, 40);
    text("thoughts and prayers", xText2, 40);
    xText1 -= 1;
    xText2 -= 1;

    if (xText1 < -265) {
        xText1 = width;
    } //if (xText2 < -265) {
//        xText2 = width;
//    }

    pop();
}

function drawFlag(x, y, s) {

    push();
    translate(x, y);
    scale(s);
    rectMode(CORNER);
    fill(textRed);

    rect(0, 130, 250, 20);
    drawStar(50, 40, 2);

    noFill();
    stroke(textRed);
    strokeWeight(10*s);
    rect(0, 0, 250, 150);
    noStroke();

    pop();

}

function drawStar(x, y, s) {
    var rOut = 10;
    var rIn = 5;

    push();
    translate(x,y);
    scale(s);
    rotate(radians(180));

    beginShape();
    for (var i = 0; i < 5; i++) {
        vertex( rOut*cos((2*PI*i/5)+(PI/2)),
                rOut*sin((2*PI*i/5)+(PI/2)));
        vertex( rIn*cos((2*PI*i/5)+(PI/2)+(2*PI/10)),
                rIn*sin((2*PI*i/5)+(PI/2)+(2*PI/10)));
    }
    endShape(CLOSE);

    pop();
}

function bottomText() {
    image(bottomTextCAImg, width - bottomTextCAImg.width, height - bottomTextCAImg.height);
    /*
    var lines = "NO BAILOUT\nDEMOCRATIZE POWER\nPEOPLE OVER PROFITS";

    noStroke();
    textStyle(ITALIC);
    textAlign(RIGHT, TOP);
    fill(textRed);
    textSize(14); //14
    textLeading(18);
    //textFont('dosis');

    text(lines, marginS+rectX, marginT+rectY+15);
    */

}

//not used
function storeBackground() {
    for (var x = 0; x < width; x++) {
        for (var y = 0; y < height; y++) {
            if (random(0,1) < 0.1) {
                bgx.push(x);
                bgy.push(y);
            }
        }
    }
}

//not used
function drawBackgound() {
    for (var i = 0; i < bgx.length; i++) {
        stroke('black');
        point(bgx[i], bgy[i]);
        noStroke();
    }
}

function cafiresPoster() {
    //drawBackgound();

    push();
    translate(width/2, rectY/2 + marginT);

    background(tanColor);
    fill('black');
    rectMode(CENTER);
    rect(0, 0, rectX, rectY);

    rotate(radians(-90));
    scale(0.7);

    for (var i = 0; i < numRows/3; i+=3) {
        var lat = fires.getNum(i, "X");
        var lon = fires.getNum(i, "Y");

        //var size = fires.getNum(i, "poly_GISAcres")

        var mappedLat = map(lat, -124, -114, -width/2, width/2);
        var mappedLon = map(lon, 32.55, 42, -height/2, height/2);
        //var mappedSize = map(size, 0, 223180, 20, 30);
        drawCircles(mappedLon, mappedLat, 5);
    }

    pop();

    topText();
    mainText();

    bottomText();
    noFill(); stroke(textRed);
    //drawStar(300, marginT + rectY + 40, 3);
    noStroke();
    //movingText();

    drawFlag(marginS+1, marginT+rectY+17, 0.3);
}

//capitalism is killing the planet
function drawTriangle(x, y, s, n) { //dont look at this function :///

    push();
    translate(x,y);
    scale(s);
    noFill();

    beginShape();

    vertex(-50 + random(n), 50+random(n));//point
    for (var i = -49; i < 49; i+=10) {
        vertex(i + random(n), 50 + random(n));
    }
    vertex(50 + random(n), 50 + random(n)); //point
    vertex(43.75 + random(n),39.375 + random(n));
    vertex(37.5 + random(n), 28.75 + random(n));
    vertex(31.25 + random(n), 18.125 + random(n));
    vertex(25 + random(n), 7.5 + random(n));
    vertex(12.5 + random(n), -13.5 + random(n));
    vertex(6.25 + random(n), -24.25 + random(n));
    vertex(3.125 + random(n), -29.625 + random(n));
    vertex(0 + random(n), -35 + random(n)); //point
    vertex(-3.125 + random(n), -29.625 + random(n));
    vertex(-12.5 + random(n), -13.5 + random(n));
    vertex(-25 + random(n), 7.5 + random(n));
    vertex(-31.25 + random(n), 18.125 + random(n));
    vertex(-37.5 + random(n), 28.75 + random(n));
    vertex(-43.75 + random(n),39.375 + random(n));

    endShape(CLOSE);

    pop();
}

function drawConcentricTriangles(x, y, n) {
    push();
    for (var i = 0; i < 6; i++) {
        strokeWeight(i);
        drawTriangle(x, y, 0.8*(6-i), n);
    }
    pop();
}

function mainTextCap() {
    image(bottomMainTextCapImg, 0, height - bottomMainTextCapImg.height);
    /*
    textSize(40);
    fill('black');
    noStroke();
    //textFont(gothic);
    textAlign(LEFT, TOP);
    text('capitalism is', 10, height/2 + 30);
    text('killing', 10, height/2 + 30 + 45);
    text('the planet', 10, height/2 + 30 + 2*45);
    */
}

function topTextCap() {
    image(topTextCapImg, 0, 0);
    /*
    textSize(12);
    fill('black');
    noStroke();
    //textFont(dosisL);
    textAlign(LEFT, TOP);
    text('CAN CAPITALISM SURVIVE?', 10, 10);
    text('NO, I DO NOT THINK IT CAN.', 10, 22);

    textAlign(RIGHT, TOP);
    text('ITS VERY SUCCESS UNDERMINES', width - 10, 10);
    text('THE SOCIAL INSTITUTIONS WHICH', width - 10, 22);
    text('PROTECT IT', width - 10, 34);
    */
}

function bottomTextCap() {
    textSize(12);
    fill('black');
    noStroke();
    //textFont(dosisL);
    textAlign(RIGHT, BOTTOM);
    text('1942', width - 10, height - 10 - 12 - 12);
    text('JOSEPH SCHUMPETER', width - 10, height - 10 - 12);
    text('CAPITALISM, SOCIALISM AND DEMOCRACY', width - 10, height - 10);
}

function capitalismPoster() {
    background('orange');
    noFill();

    mainTextCap();
    topTextCap();

    stroke('black');

    //silent at bottom left corner
    while (mouseX < 0 & mouseY < 0) {
        triangleRand = 0;
    }

    triangleRand = max(mouseX, height - mouseY)/100;

    stroke(tanColor); //tan
    drawConcentricTriangles(5*width/9, 120, triangleRand);

    stroke(255, 204, 64); //yellow
    drawConcentricTriangles(4*width/9, 120, 0);

    //image(barcode, 15, height-barcodeWidth-10, 30, barcodeWidth);
    //bottomTextCap()
}

Final Project

How to play: In order to win the game, the player must move the polar bear to its home (the iceberg) while avoiding the obstacles. The polar bear can be moved in four directions using the arrow keys. When the polar bear comes into contact with an obstacle, the number of lives will decrease and the background will slightly turn blue (representing ice melting). There’s a total of 60 lives to start with, and there’s also a timer that counts down from a minute. If the number of lives or time runs out before the polar bear reaches home, then the game is over.

final project
// variables for images
var bear; 
var home; 
var factory;
var fire;
var bottle;

//variable for bear & obstacles
var bearx = 90;
var beary = 550;
var fires = [];
var factories = [];
var bottles = [];

// variables for background color
var colorR = 255;
var colorG = 253;
var colorB = 240;
var stepR;
var stepG;
var stepB;

// variable for timer
var timer = 60;

// variable for lives
var lives = 60; 

// variables for winning
var victory = false;
var angle = 0;

function preload() {
    bear = loadImage("https://i.imgur.com/P6jBMLN.png");
    home = loadImage("https://i.imgur.com/GZBJAQt.png");
    factory = loadImage("https://i.imgur.com/8uJDtMZ.png");
    fire = loadImage("https://i.imgur.com/P8Og7bN.png");
    bottle = loadImage("https://i.imgur.com/Q3Qch7G.png");
}

function setup() {
    createCanvas(500, 600);
    imageMode(CENTER);
    home.resize(170, 0);
    bear.resize(100, 0);
    fire.resize(60, 0);
    factory.resize(60, 0);
    bottle.resize(60, 0);
    // get dimensions of images
    print("fire width" + " " + fire.width);
    print("fire height" + " " + fire.height); 
    print("bear width" + " " + bear.width);
    print("bear height" + " " + bear.height);
    print("factory width" + " " + factory.width);
    print("factory height" + " " + factory.height); 
    print("bottle width" + " " + bottle.width);
    print("bottle height" + " " + bottle.height); 
    
    // make obstacles 
    for (var i = 0; i < 3; i ++) {
        var startposition = random(0, width/5)*5;
        var startspeed = random(0, 3);
        fires.push(makeFire(startposition, 0, startspeed));
    }

    for (var i = 0; i < 3; i ++) {
        var startposition = random(0, width/5)*5;
        var startspeed = random(0, 3);
        factories.push(makeFactory(startposition, 0, startspeed));   
    }

    for (var i = 0; i < 3; i ++) {
        var startposition = random(0, width/5)*5;
        var startspeed = random(0, 3);
        bottles.push(makeBottle(startposition, 0, startspeed));   
    }
}

function draw() {
    background(colorR, colorG, colorB); // initial cream color

    // game over melted ice will be blue => (177, 224, 230)
    stepR = (255 - 177) / 60;
    stepG = (253 - 224) / 60;
    stepB = (240 - 230) / 60;

    // timer 
    textSize(20);
    textAlign(CENTER);
    text("Timer: " + timer, 430, 580);
    text("Lives: " + lives, 330, 580);
        
    if (frameCount % 60 == 0 & timer > 0) {
        timer -= 1; // counts down 
    } 
    if (timer == 0) { // if times run out, game ends
        gameover();
    }

    image(home, width/2, 70); 
    image(bear, bearx, beary);

    // controlling bear's position through arrow keys 
    if (keyIsPressed & victory == false) {
        if (keyCode === LEFT_ARROW && bearx >= 50) {
            bearx -= 2;
        }
        if (keyCode === RIGHT_ARROW & bearx <= width - 50) {
            bearx += 2;
        }
        if (keyCode === UP_ARROW & beary >= 28.5) {
            beary -= 2;
        }
        if (keyCode === DOWN_ARROW & beary <= height - 28.5) {
            beary += 2;
        }
    }
    
    if (bearx >= width/2 - 20 & bearx <= width/2 + 20 && beary >= 50 && beary <= 90) { // if bear reaches home
        win();
    }

    obstacles(fires, 44);
    obstacles(factories, 35);
    obstacles(bottles, 26.5);
}

// function to show & update obstacles + interaction 
function obstacles(array, size) {
    for (var i = 0; i < array.length; i++) {
        array[i].show();
        array[i].update();
        if ((bearx >= array[i].x - 80 & bearx <= array[i].x + 80) && (beary >= array[i].y - size && beary <= array[i].y + size)) {
            if (colorR >= 177 || colorG >= 224 || colorB >= 230) {
                colorR -= stepR;
                colorG -= stepG;
                colorB -= stepB;
                lives -= 1;
            } else {
                gameover(); break;
            }
        } 
    }
}


// fire object
function makeFire(fx, fy, fspeed) {
    var fireobject = {x: fx, y: fy, speed: fspeed, show: fireShow, update: fireUpdate};
    return fireobject;
}

function fireShow() {
    image(fire, this.x, this.y);
}

function fireUpdate() {
    this.y += this.speed;
    if (this.y - 44 >= height) {
        this.y = -44;
    }
}

// factory object 
function makeFactory(facx, facy, facspeed) {
    var factoryobject = {x: facx, y: facy, speed: facspeed, show: factoryShow, update: factoryUpdate};
    return factoryobject;
}

function factoryShow() {
    image(factory, this.x, this.y);
}

function factoryUpdate() {
    this.y += this.speed;
    if (this.y - 35 >= height) {
        this.y = -35;
    }
}

// bottle object
function makeBottle(bx, by, bspeed) {
    var bottleobject = {x: bx, y: by, speed: bspeed, show: bottleShow, update: bottleUpdate};
    return bottleobject;
}

function bottleShow() {
    image(bottle, this.x, this.y);
}

function bottleUpdate() {
    this.y += this.speed;
    if (this.y - 26.5 >= height) {
        this.y = -26.5;
    }
}

// game over function
function gameover() {
    background(212, 36, 17); // red background if game over
    textSize(45);
    text("GAME OVER!", width/2, height/2);
    //stopping everything else
    fires = [];
    factories = [];
    bottles = [];
    victory = true;
    noLoop();
}

// you win function 
function win() {
    background(149, 217, 143); // green background if win
    textSize(45);
    text("YOU WIN!", width/2, height/2);
    // rotating the bear if win
    push();
    translate(width/2, 200);
    rotate(radians(angle));
    imageMode(CENTER);
    image(bear, 0, 0);
    pop();
    angle += 5;
    //stopping everything else
    fires = [];
    factories = [];
    bottles = [];
    victory = true;
}

Since the theme of our final project was climate change, I wanted to incorporate different causes of climate change through the form of an interactive game where the polar bear symbolizes the victims of global warming. The polar bear has to avoid obstacles including pollution from a factory, plastic waste in the ocean, and forest fires, in order to safely reach home. It’s difficult to win the game, which symbolizes how we’ve neglected this issue for so long that it’s now quite impossible to reverse the impact.

If I had more time to work on this project, I might add positive objects such as renewable energy sources that the bear can touch and will increase the number of lives or the remaining time, representing potential actions to reverse or reduce climate change.

Final Project: Iceberg

sketchDownload

// ICE VAR
var terraine = [];          // array for ice terraine y coordinates
var noiseParam = 0;         // x value of noise func
var noiseStep = .02;        // how much x increases by
var icesize = noiseStep*2500;

// OBJECT VAR
var washer;
var handwasher;
    var bubble;
var bubs = [];
var waterbottle;
var reusebottle;
var car;
var bus;
var shoponline;
var shoplocal;

var allobj = [];            // holds all objects once they are created
var len;                    // length of allobj array
var n = 0;                  // initial spot in allobj array
var q;
var isMouseClicked = -1; // boolean for click

// AUDIO VAR
var waterdrop;  
var watersplash;      


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


// PRELOAD FOR AUDIO FILES
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");
}

// SETUP
function setup() {
    createCanvas(400, 400);
    strokeWeight(2);
    rectMode(CENTER);
    textAlign(CENTER);
    textFont('Georgia');
    textSize(13);
    useSound();

    // fill terraine array w coordinates for ice:
    for (var i=0; i<icesize; i++) {
        var n = noise(noiseParam);      // n is between 0 and 1
        var value = map(n, 0, 1, height/3, height);     // draws onto canvas nicely
        terraine.push(value);           // value is the y coordinate at x=i
        noiseParam += noiseStep;
    }

    // create objects:
    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;
}

// SOUND SETUP
function soundSetup() { // setup for audio file
    waterdrop.setVolume(0.5);
    watersplash.setVolume(0.5);
}


// DRAW
function draw() {

    // blue sky:
    background(100, 175, 240);

    // ice:
    drawIce();

    // it melts:
    meltIce();

    // draw objects:
    if (terraine.length > 1) {
        q = n%(len);        // loops through array by 2s
        allobj[q].show();
        allobj[q+1].show();
    }
}

// WHEN USER CLICKS
function mousePressed() {
    let onObj = checkClick();
    if (onObj == true) {
        isMouseClicked = -isMouseClicked;
        n += 2;                 // loops through array by 2s
        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;
    }
}


// DRAW ICE
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();

    // check if completely melted:
    checkIce();
}

// MELT ICE constantly
function meltIce() {
    // when ice is melted, 'game' over
    if (terraine.length == 1) { return }
    // as ice melts, water drop audio is played
    if (frameCount%250==0) {
        terraine.pop();
        waterdrop.play();
    }
}

// MELT MORE! when environmentally more harmful choice is picked
function meltMore(obj) {
    for (var k=0; k<obj.melt; k++) {
        terraine.pop();
    }
    if (obj.melt == 1) { waterdrop.play() }
    else { watersplash.play() }
}

// CHECK IF COMPLETELY MELTED
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();
    }
}

// DRAW OBJECTS:
// washer
function drawWasher() {
    push();
    translate(this.x, this.y);

    fill(220);
    square(0, 0, 100, 5);

    fill(150);
    circle(0, 0, 75);

    // water in washer:
    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();

    // door partially see-through:
    stroke(0);
    fill(175, 200, 255, 175);
    circle(0, 0, 60);

    // glare on glass door
    noStroke();
    push();
    rotate(radians(40));
    fill(200, 215, 255);
    ellipse(0, -15, 30, 5);
    ellipse(0, -20, 15, 3);
    pop();

    // bottons + stuff

    fill(200, 0, 0);
    circle(40, -40, 3);
    fill(75);
    circle(35, -40, 3);
    circle(30, -40, 3);
    fill(150);
    circle(35, -33, 7);

    // text
    fill(0);
    text(this.txt, 0, 62);

    pop();
}

// handwash basin
function drawHandwasher() {
    push();
    translate(this.x, this.y);

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

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

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

    // suds + bubbles
    fill(200, 215, 255);
    stroke(100, 140, 240);
    strokeWeight(.25);
    for (var i=0; i<30; i++) {
        bubs[i].show()
    }

    // text
    fill(0);
    strokeWeight(1);
    text(this.txt, 0, 62);
    pop();
}

// bubble
function drawBubble() {
    circle(this.x, this.y, this.sz);
}

// plastic bottle
function drawWaterbottle() {
    // cap
    stroke(0);
    strokeWeight(1);
    fill(240);
    rect(this.x, this.y-45, 15, 10);

    // body of bottle
    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();

    // lines on cap
    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);
    }

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

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

    //wrapper details
    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();

    // text
    fill(0);
    strokeWeight(1);
    text(this.txt, this.x, this.y+62);
}

// reusable bottle
function drawReusebottle() {
    stroke(0);
    strokeWeight(1);   

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

    // body of bottle
    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();

    // lines on body of bottle
    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));
    }

    // stickers!
    // smiley face
    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();

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

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

    // text
    fill(0);
    text(this.txt, this.x, this.y+62);
}

// car
function drawCar() {
    let carcol = color(150, 0, 0);
    let detailcol = color(100, 0, 0);

    // exhaust pipe
    fill(120);
    noStroke();
    rect(this.x+60, this.y+27, 5, 3);

    // body of car
    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();

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

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

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

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

    // text
    fill(0);
    strokeWeight(1);
    text(this.txt, this.x, this.y+62);
}

// bus
function drawBus() {
    let buscol = color(50, 75, 255);
    let busdetails = color(20, 40, 200);

    // exhaust pipe
    fill(120);
    noStroke();
    rect(this.x+50, this.y-27, 3, 5);

    // bus body
    fill(buscol);
    stroke(busdetails);
    strokeWeight(2);
    rect(this.x, this.y, 120, 50, 2);

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

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

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

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

    // text
    fill(0);
    strokeWeight(1);
    text(this.txt, this.x, this.y+62);
}

// plane
function drawOnline() {
    fill(200);
    stroke(0);

    push();
    translate(this.x, this.y)
    //back wing
    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();
    //small tail wing back
    arc(55, 35, 45, 10, radians(90), radians(270));
    push();
    rotate(radians(31));
    //body
    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));
    // windows
    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();
    //back fin thingy
    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();
    //small tail wing front
    arc(70, 35, 45, 10, radians(260), radians(100));
    //front wing
    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();  

    // text
    fill(0);
    strokeWeight(1);
    text(this.txt, 0, 62);    
  
    pop();
}

// store
function drawLocal() {
    square(this.x, this.y, 100);
    noFill();
    push();
    translate(this.x, this.y);

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

    //roof
    stroke(0);
    fill(150, 100, 50);
    quad(-60, -20, 60, -20, 50, -50, -50, -50);

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


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

    //signs in windows
    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);

    // text
    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.

Time lapse of my process

Final Project 14

Game Code

let noiseY;
let noiseSpeed = 0.07;
let noiseHeight = 20;
let bubbles = [];
let enemies = [];
let score = 0;






function setup() {
    createCanvas(600, 600);
    //background(10, 50, 255);
    noiseY = height * 3.2 / 4;
    
//}

    
    // spawn the enemies or in this case trash/waste
    for (let e = 0; e < 15; e++) {
        let enemy = {
            x: random(0, width),
            y: random(-600, 0),
            c: color(random(255), random(255), random(255))
        };
        enemies.push(enemy);
    }

}

function drawOceanWaves() {
    // draw ocean waves
    for (let i = 0; i < 4; i++) {
        let offsetY = i * 90;
        noFill();
        //fill('blue')
        stroke(255, 20);
        strokeWeight(height / 2);
        beginShape();
        curveVertex(2, height / 2);
        for (let x = 0; x < width; x += 40) {
            let y = noise(frameCount * noiseSpeed + x + i) * noiseHeight + noiseY + offsetY;
            curveVertex(x, y);
        }
        curveVertex(width, height / 4);
        endShape();
    }
}








function draw() {
    

    background(10, 20, 200);

    // draw ocean waves
    
    drawOceanWaves ();

    fill('blue');
    strokeWeight(0);
    // draw player
    rectMode(CENTER);
    ellipse(mouseX, height - 20, 20);


    // draw bubbles update
    for (let bubble of bubbles) {
        bubble.y -= 15;
        circle(bubble.x, bubble.y, 20);
        //fill('blue');
    }
        fill(255);

    // draw enemies update
    for (let enemy of enemies) {
        enemy.y += 4;
        fill(enemy.c);
        square(enemy.x, enemy.y, 40);
        if (enemy.y > height) {
            fill(255);
            text("Game Over!", width / 2.5, height / 2);
            noLoop();
        }
    }

    // collisions
    for (let enemy of enemies) {
        for (let bubble of bubbles) {
            if (dist(enemy.x, enemy.y, bubble.x, bubble.y) < 80) {
                enemies.splice(enemies.indexOf(enemy), 1);
                bubbles.splice(bubbles.indexOf(bubble), 1);
                let newEnemy = {
                    x: random(0, width),
                    y: random(-800, 0),
                    c: color(random(255), random(255), random(255))
                };
                enemies.push(newEnemy);
                // each hit counts as 1
                score += 1;
            }
        }
    }
    fill(255);
    textSize(30);    
    text(score, 20, 30);

}
    // shoot bubbles
function keyPressed() {
    if (key ===  " ") {
        let bubble = {
        x: mouseX,
        y: height - 50,
    };
    bubbles.push(bubble);

    }


    
}

So originally I was going to create an image with trash being left out in the ocean to represent ocean pollution. I dropped that idea since I felt like it was too simple and I couldn’t run a local server in the past. I finally decided that I wanted to code a game. The idea was to represent squares as waste being thrown in the ocean and there’s a player who has to shoot down as many waste before it reaches past the canvas. I re wrote all of my code and started from scratch. I watched tutorials on youtube and looked up on google on how to use for of loop on JavaScript. When coding the game I had a lot of issues especially with the text and textsize syntax. I found out later that my brackets were off and were interfering with my other parameters. I finally got the game to work and I’ve never felt this satisfied with myself since coding for me is a whole different language and a very difficult skill to learn. How the game works is that you have to shoot as many squares (trash) before it reaches past the canvas. You drag MouseX to move around the canvas. There is also a score on the top left. Each hit counts as 1. You press spacebar to shoot the bubbles. If the squares go past the canvas “Game Over!”. If I had more time to work on this game I would want to add a healthbar for the player or randomize the speed of the squares. Its a simple game but I am proud of the results.

14 – Final Project

sketch

//bgoeke Sec. B Final Project

var gravity = 0.3;   // downward acceleration
var spring = 0.7; // how much velocity is retained after bounce
var drag = 0.0001;    // drag causes particles to slow down
var np = 0;      // how many particles
var rpx = [];
var rpy = [];
var rpc = 10000;
var count = 0;

function preload() {
	gas = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/greenhousegas.png")
	plant = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/plant1.png")
	bin = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/rcbin2.png")

}
 
function particleStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > width - 80 & this.y > height - 100) { // bounce off right wall
        this.x = (width - 80) - (this.x - (width-80));
        this.dx = 0;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx * spring;
    }

    if (this.x < width - 180 & this.y > height - 100) { // bounce off right wall
        this.x = (width) - (this.x - (width));
        this.dx = 0;
    }


    if (this.y > height-20) { // bounce off bottom
        this.y = (height-20) - (this.y - (height-20));
        this.dy = 0;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy * spring;
    }

    //deals with repeler
    var rpx = mouseX
    var rpy = mouseY
    	var dp = dist(this.x, this.y, rpx, rpy);
    	var f = rpc / (Math.pow(dp , 2));
    	var dirx = (this.x - rpx) / dp;
    	var diry = (this.y - rpy) / dp;
    	this.x += f * dirx;
    	this.y += f * diry;

    	this.dy = this.dy + gravity; // force of gravity
    // drag is proportional to velocity squared
    // which is the sum of the squares of dx and dy
    var vs = Math.pow(this.dx, 2) + Math.pow(this.dy, 2);
    // d is the ratio of old velocty to new velocity
    var d = vs * drag;
    // d goes up with velocity squared but can never be
    // so high that the velocity reverses, so limit d to 1
    d = min(d, 1);
    // scale dx and dy to include drag effect
    this.dx *= (1 - d);
    this.dy *= (1 - d);
}


 
 
function particleDraw() {
    image(bin,180,290,210,120);
    image(gas, this.x, this.y, 40, 40);
}
 
 
// create a "Particle" object with position and velocity
function makeParticle(px, py, pdx, pdy) {
    p = {x: px, y: py,
         dx: pdx, dy: pdy,
         age: 0,
         stepFunction: particleStep,
         drawFunction: particleDraw
        }
    return p;
}




    function countParticle() {
        count ++
        //count = (count);
    }

    function gameOver() {
        if (int(count/1000) > 80) {
            rect(width/2, height/2, width, height);
            textSize(60);
            text('YOU WIN !', 10, height/2)
            textSize(40);
            text(int((millis())/1000), 100, 250);
            text('seconds', 155, 250);
            noLoop();
    }

    }



 
var particles = [];
 
 
function setup() {
    createCanvas(400, 400);
    frameRate(10);

}
 
 
// draw all particles in the particles array
//
function draw() {
    background('lightblue');
    noStroke();
    fill(80);
    ellipse(80,100,160,50);
    ellipse(250,20,350,60);
    ellipse(100,100,100,50);
    stroke(0);
    strokeWeight(1);
    fill(255,10,5);
    textSize(15);
    text('How Fast Can You Get Rid Of The Gas?', 120,20)
    fill(0,255,0);
    rectMode(CENTER);
    textSize(50);
    text(int(count/1000), 10, height/2);

    image(plant,mouseX,mouseY,80,80);
    var newp = makeParticle(50, 50,
                                random(-10, 10), random(-10, 0));
        particles.push(newp);

    stroke(0);
    strokeWeight(10);
    newParticles = [];


    //if (mouseIsPressed) {
        //var newp = makeParticle(mouseX, mouseY,
                                //random(-10, 10), random(-10, 0));
        //particles.push(newp);
    //}
 
    // newParticles will hold all the particles that we want to
    // retain for the next call to draw() -- we will retain particles
    // if the age is < 200 (frames). Initially, newParticle is empty
    // because we have not found any "young" particles yet.

    for (var i = 0; i < particles.length; i++) { // for each particle
        var p = particles[i];
        p.stepFunction();
        p.drawFunction();

        if (p.y > height - 80 & p.x > width-180 && p.x < width-80) {
            newParticles.push(p);
            countParticle()
        }

        // since we are "looking" at every particle in order to
        // draw it, let's use the opportunity to see if particle[i]
        // is younger than 200 frames. If so, we'll push it onto the
        // end of newParticles.
        if (p.age < 3000) {
            newParticles.push(p);
        }
    }

    gameOver();
   
    // now, newParticles has EVERY particle with an age < 200 frames.
    // these are the particles we want to draw next time, so assign
    // particles to this new array. The old value of particles, i.e.
    // the entire array, is simply "lost" -- Javascript will reclaim
    // and reuse the memory since that array is no longer needed.
    particles = newParticles;



}

For my program I wanted to create a falling game where you can manipulate multiple objects to get them in some sort of cup or final destination. In this game you use the plant as a repeler to direct the bad greenhouse gasses into the recycling bin. The goal is to get the counter to eighty and there’s some bonuses when you use the plant to bounce the gas around quicker. At eighty the game stops and gives you the time it took to finish the game. The ultimate competition in the game is to get the time as quickly as you can. The best time I got was 15 seconds. If I had some more time I wanted to make it so the recycling bin actually gets filled up with gases and overfills. I would’ve also liked to make more levels where there are existing obstacles that you have to get around with the plant.

sketch
//Amalia Kutin
//15-104 B
var bergSize;
var polar;
var pieces = [];
var afterNoon;
var skyColor;
var clouds = [];
var skyOrb;
var skyOrbColor;


function setup() {
    createCanvas(500, 500);
    background(158, 198, 255);
    bergSize = 400;
    skyColor = 125;
    skyOrb = 0;
    skyOrbColor = false;
    noStroke();
    polar = {x: 250, y: 350, dx: 0};
    for(let i = 0; i < 10; i++) clouds[i] = {x: random()*500, y: random()*180};
}

function draw() {
    background(158, 198, 255);
    fill(61, 120, 204);
    rect(0, 200, 500, 300);
    fill(143, 185, 191);
    beginShape();
    vertex(250-(bergSize/2), 350);
    vertex(250-(bergSize/4), 350-(bergSize/4));
    vertex(250+(bergSize/4), 350-(bergSize/4));
    vertex(250+(bergSize/2), 350);
    vertex(250+(bergSize/4), 350+(bergSize/4));
    vertex(250-(bergSize/4), 350+(bergSize/4));
    endShape(CLOSE);
    for(let i = 0; i < pieces.length; i++) drawIce(pieces[i]);
    drawSky();
    for(let i = 0; i < clouds.length; i++) drawClouds(clouds[i]);
    drawBear(polar);
}

function drawBear(b) {
    fill(255);
    beginShape();
    vertex(b.x-20, b.y-20);
    vertex(b.x+10, b.y-30);
    vertex(b.x+20, b.y-25);
    vertex(b.x+15, b.y-10);
    vertex(b.x+20, b.y+10);
    vertex(b.x+10, b.y+10);
    vertex(b.x, b.y);
    vertex(b.x-10, b.y+5);
    vertex(b.x-10, b.y+10);
    vertex(b.x-20, b.y+10);
    vertex(b.x-30, b.y+5);
    vertex(b.x-35, b.y-5);
    endShape(CLOSE);
    fill(156, 96, 114);
    circle(b.x+20, b.y-25, 5);
    fill(0);
    circle(b.x+10, b.y-22, 5);
    circle(b.x+13, b.y-27, 5);
    b.x += random()*6 - 3;
    b.y += random()*6 - 3;
    if(b.x < 260-bergSize/2) b.x += 10;
    if(b.x > 240+bergSize/2) b.x -= 10;
    if(b.y < 360-bergSize/4) b.y += 10;
    if(b.y > 340+bergSize/4) b.y -= 10;
}

function drawIce(i) {
    fill(143, 185, 191);
    beginShape();
    vertex(i.x-(i.s/2), i.y);
    vertex(i.x-(i.s/4), i.y-(i.s/4));
    vertex(i.x+(i.s/4), i.y-(i.s/4));
    vertex(i.x+(i.s/2), i.y);
    vertex(i.x+(i.s/4), i.y+(i.s/4));
    vertex(i.x-(i.s/4), i.y+(i.s/4));
    endShape(CLOSE);
    if(i.c % 8 < 2) i.x++;
    else if(i.c % 8 < 4) i.y++;
    else if(i.c % 8 < 6) i.x--;
    else i.y--;
    i.c++;
}

function drawSky() {
    if(afterNoon) skyColor-=0.25;
    else skyColor+=0.25;
    fill(skyColor, skyColor, 120+skyColor/2);
    rect(0, 0, 500, 200);
    if(skyColor == 200) afterNoon = true;
    if(skyColor == 50) afterNoon = false;
    if (skyOrbColor) fill(219, 252, 255);
    else fill(235, 196, 68);
    circle(skyOrb, 100, 60);
    skyOrb+=(0.25*500/150);
    if (skyOrb > 500) {
        skyOrb = 0;
        if (skyOrbColor) skyOrbColor = false;
        else skyOrbColor = true;
    }
}

function drawClouds(c) {
    fill(255);
    ellipse(c.x%500, c.y, 50, 30);
    c.x++;
}

function mousePressed() {
    if(bergSize > 150) bergSize -= 10;
    var newPiece;
    for(let i = 0; i < 20; i++) newPiece = {x: random()*500, y: 200+random()*300, s: random()*60, c: 0};
    pieces[pieces.length] = newPiece;
}

My project revolved around a polar bear and melting ice. There is an iceberg that the user melts by clicking, and a polar bear stuck on it. Small pieces of ice are generated as the main piece melts. The sky has clouds that move across the sky. There is also a sun/moon that moves across the sky as well. The polar also randomly moves around, but it’s constrained by the size of the iceberg. This project demonstrates the small scale effects of climate change.

If I had more time, I would have considered adding a second polar bear. The issue is that it would need to stay on the iceberg while also not bumping into its friend.