Final Project

fp luca

var s = 0;//score
var trasharr = [];//store trash into array
var buildingsarr = [];
var speed;

function setup() {
    createCanvas(400, 400);
    rectMode(CENTER);
    noStroke();
    frameRate(10);

    for (var i = 0; i < 3; i++){
        trasharr[i] = initializeTrash();
    }

    for (var i = 0; i < 15;i++){
        buildingsarr[i] = initializeBuildings();
    }
}


function draw() {

    background(0);

    //establish scene

    sky();

    scene();

    for (var i = 0; i < 3; i++){
        drawTrash(trasharr[i]);
        moveTrash(trasharr[i], speed)
    }

    for (var i = 0; i < 15; i++){

        drawBuildings(buildingsarr[i],i);
    }

    fill(0,255,0);
    text("Player Score:" + s,20,20);

    

}

function initializeTrash(){
    var trash = {x:60,y:random(250,400),
             w:30,h:30,
             r:random(0,255),g:random(0,255),
             b:random(0,255)};

    return trash;//store trash       
             
}

function drawTrash(trash){
    
    fill(trash.r,trash.g, trash.b);
    rect(trash.x,trash.y, trash.w, trash.h);

    speed = 5;

    if (trash.x >= 350){
        trash.x = 60
        speed = -speed;
    }
}


function moveTrash(trash, speed){
    trash.x += speed;
}

function scene(){
    //sea
    fill(69, 123, 157);
    rect(200,300,400,200);
}

function initializeBuildings(){
    //cityscape

    var buildings = {x:random(-30,50),y:0,w:50,h:random(30,180)}

    return buildings;//store buildings
}

function drawBuildings(buildings,i){//including forloop "i" for building x para.

    push();
    rectMode(CORNER);
    translate(width/2,height/2);
    rotate(radians(180));

    fill(0);
    rect(i*buildings.x,buildings.y,buildings.w,buildings.h);
    pop();

}

function sky(){
    //fill changes according to time of day.
    var hr = hour();

    if (hr >= 0 & hr < 4){
        fill(1,8,79);
    } else if (hr >= 4 & hr < 8){
        fill(0,173,255);
    } else if (hr >= 8 & hr < 12){
        fill(255,255,112);
    } else if (hr >= 12 & hr < 16){
        fill(255,221,64);
    } else if (hr >= 16 & hr < 20){
        fill(255,121,84);
    } else if (hr >= 20 & hr < 23){
        fill(107, 73, 132);
    } else if (hr >= 23){
        fill(99,30,80);
    }

    rect(200,100,400,200);
}

function mousePressed(trash){
    if (dist(mouseX,mouseY,trash.x,trash.y)<30){
        //remove trash
        trash.y = 450;
        s = s + 1;
    }
}

I want to focus on the problem of plastic pollution in our ocean ecosystem in this project. This issue inspires me because plastic containers and packaging are essential to our daily lives, and we rarely recycle them correctly. Many plastic wastes end up incinerated, buried in landfills, or floating in the ocean. Our mistakes and carelessness are causing harm to the planet’s natural ecosystems, which is getting increasingly common in the Anthropocene. In my project, I added visual elements to show that humans cause this problem, such as the city in the background. If I had more time to work on this project, I would use vertices to create my trash to give them a more realistic look. Also, I would make the trash move more randomized so the game could be more engaging and unpredictable. Many of the interactions and visual effects that I plan to achieve did not work as expected, primarily because of my time management on this project. In hindsight, I should make edits to my program more regularly to give myself more time to reflect and improve.

Final Project

For my final project, I wanted to show that climate change is not just a singular concept, but rather a buildup of many different factors and situations, as well as how they are related to one another. First, trees are cut down to clear space for more buildings, people in these buildings require electricity which requires the burning of fossil fuels, and the release of carbon dioxide into the air exacerbates global warming and melts glaciers that increase ocean levels.

The user goes through these 3 scenes and interacts with them, worsening the situation. At the end of each scene, they are presented with statistics of each action and they realize those consequences. Perhaps the polar bear is a metaphor for humans and at the end when the polar bear “drowns”, the user is asked “Are you sorry now?” telling them to rethink their actions before it is too late.

If I had more time, I would have liked to make my graphics more detailed. I would have also liked to include sound but I was having too many problems with looping the sounds so I decided not to include them.

sketch

//Catherine Liu
//jianingl@andrew.cmu.edu
//Section D
//Final Project

//An interactive narrative consisting of 3 scenes

var scene = 1;
var frameNum = 0;

var trees = []; //array to hold objects for trees
var treeCount = 0; //keeping track of framecount specifically for trees
var buildings = []; //array to hold objects for buildings

var lightSwitch = false; //tracking if switch is on or off
var smokeTrail1 = []; //array for holding smoke trail
var smokeTrail2 = []; //array for holding smoke trail

var seaHeight; //tracking height of sea
var gameFail = 0; //tracking if polar bear has drowned
var finalFrame = false; //tracking framecount to show final frame
var finalCount = 0; //tracks count of final frame

//making sine wave for ocean (code refrenced from p5js.org)
var xspacing = 5; // Distance between each horizontal location
var w; // Width of entire wave
var theta = 0.0; // Start angle at 0
var amplitude = 25.0; // Height of wave
var period = 500.0; // How many pixels before the wave repeats
var dx; // Value for incrementing x
var yvalues; // Using an array to store height values for the wave

function setup() {
    createCanvas(600,400);

    //adds trees to array
    for (i = 0; i < 5; i++) {
        var rx = random(width);
        trees[i] = makeTree(rx);
    }

    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }

    //sets up smoke object
    for (i = 170; i > 50 ; i-=15) {
        smoke1 = { x: 400 + random(-10,10),
                  y: i,
                  size: random(30,50)
                }
        smokeTrail1.push(smoke1)

        smoke2 = {x: 500 + random(-10,10),
                  y: i,
                  size: random(30,50)
                }
        smokeTrail2.push(smoke2)
    }

    //setting up sine wave 
    w = width + 16;
    dx = (TWO_PI / period) * xspacing;
    yvalues = new Array(floor(w / xspacing));
}

function draw() {

    //tracking framecount for scenes to show up
    frameNum += 1

    if (frameNum == 200){
        scene = 1.5
    }

    if (frameNum == 250){
        scene = 2;
    }

    if (frameNum == 450){
        scene = 2.5
    }

    if (frameNum == 500) {
        scene = 3;
    }

    if (finalFrame) {
        finalCount += 1;
    }

    //Scene 1: Cutting down trees
    if (scene == 1) {
        background(230,230,250);
        noStroke();
        fill(0,100,0);
        rect(0,height-50,width,50)

        //show trees until a certain point and switch to buildings
        if (treeCount <= 120) {
            textSize(20);
            textAlign(CENTER);
            text("Try cutting down trees with the saw", width/2, 30);
            updateAndDisplayTrees();
            removeTrees();
            addNewTree();
            treeCount += 1
        }
        if (treeCount > 120) {
            fill(50);
            rect(0,height-50,width,50)
            text("There's no more trees to cut...", width/2, 30);
            updateAndDisplayBuildings();
            removeBuildings();
            addNewBuildings(); 
        }

        //function for making saw
        drawSaw(); 
    }

    if (scene == 1.5) {
        background(0);
        textSize(20);
        textAlign(CENTER);
        fill(255);
        text("More than 3.5 billion trees are cut down annually",width/2,height/2);
        text("for human needs and urban development", width/2, height/2+30)
    }

    //Scene 2: Factory producing smoke
    if (scene == 2) {
        //function for creating smoke
        factorySmoke();

        fill(255)
        text("Click the light switch...", 120,90);
        text("watch the window",120,120);
    }

    if (scene == 2.5) {
        background(0);
        textSize(20);
        textAlign(CENTER);
        fill(255);
        text("62% of our electricity comes from fossil fuels",width/2,height/2);
        text("1.5 million metric tons of C02 are released annually",width/2,height/2+30)
    }

    //Scene 3: rising ocean levels and melting glaciers
    if (scene == 3) {
        noStroke();
        frameRate(10);
        background(70,130,180);
        textSize(20);
        textAlign(CENTER);
        fill(255);
        text("Keep the polar bear above the water, or else...",width/2,30)

        //drawing mountains
        fill(100,146,198);
        triangle(0,height,150,50,300,height);
        triangle(450,height,550,100,650,height);
        fill(135,206,235);
        triangle(100,height,300,150,500,height);

        //draw polar bear that follows mouse
        polarBear();

        //drawing wave
        seaHeight = map(frameNum,500,700,height,-10);
        fill(193,223,255);
        calcWave();
        renderWave(seaHeight);
        
        // if polar bear drowns too many times or ocean rises canvas top, scene ends
        if (gameFail>=10 || seaHeight <= 0) {
            background(0);
            fill(255);
            text("The ocean is expected to rise 15-25cm by 2050",width/2,height/2);
            finalFrame = true;
        }
    }

    if (finalCount>20) {
        background(0);
        text("Are you sorry now?", width/2, height/2);
    }
}

function treeDisplay() {
    //draw each tree
    //checking for saw intersection with tree
    treeUpdate();

    frameRate(10);
    
    //tree spawns initially but if saw intersects with tree, only draw trunk
    if (this.intersect == false) {
        noStroke();
        fill(194, 178, 128);
        push();
        translate(this.x,height-40);
        rect(0,-this.vert,this.hor,this.vert);
        fill(0,this.color,100);
        ellipse(this.hor,-this.vert,this.crown1,this.crown2);
        pop();
    } else if (this.intersect == true) {
        fill(101,67,33);
        push();
        translate(this.x,height-40);
        rect(0,-this.vert/2,this.hor,this.vert/2);
        pop();
    }
}

function treeMove() {
    this.x += this.speed;
}

function makeTree(treeX) {
    var tree= {x:treeX,
                hor: random(10,20),
                vert: random(150,250),
                speed: -3,
                color: random(255),
                crown1: random(80,100),
                crown2: random(50,80),
                intersect: false,
                move: treeMove,
                display: treeDisplay,
                update: treeUpdate,
            }
    return tree
}

function updateAndDisplayTrees() {
    for (var i = 0; i < trees.length; i++){
    trees[i].update();
    trees[i].display();
    trees[i].move();
    }
}

function removeTrees() {
    //if tree goes off canvas, remove it
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].crown2 > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep; 
}

function addNewTree() {
    //add new trees after trees move off canvas
    var newTreeLikelihood = 0.06; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

function drawSaw() {
    fill(100);
    rect(mouseX, mouseY,80,20);
    for (i = mouseX+5; i < mouseX + 85; i += 10) {
         circle(i, mouseY+20, 10);
    }
    fill("red")
    rect(mouseX-30,mouseY,40,20,20);

}

function updateAndDisplayBuildings(){
    // Update the building's positions, and display them.
    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

function removeBuildings(){
    //remove buildings as they go off screen
    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep; // remember the surviving buildings
}

function addNewBuildings() {
    // With a very tiny probability, add a new building to the end.
    var newBuildingLikelihood = 0.007; 
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}

function buildingMove() {
    this.x += this.speed;
}

function buildingDisplay() {
    // draw the building and some windows
    var floorHeight = 40;
    var bHeight = this.nFloors * floorHeight; 
    fill(this.wallCol); 
    noStroke() 
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    fill(this.windowCol); 
    for (var i = 0; i < this.nFloors; i++) {
        rect(5, -15 - (i * floorHeight), this.breadth - 10, 10);
    }
    pop();
}

function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 50,
                speed: -3,
                nFloors: round(random(2,8)),
                windowCol: random(200,255),
                wallCol: random(100,150),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function factorySmoke() {

    //tracking height of smoke so it moves down every frame
    var smokeLevel = map(frameNum,250,450,0,150); 

    if (lightSwitch == false) { //if light is off
        frameRate(20);
        noStroke();
        background(176,196,222);

        fill(100);
        //moving smoke up the canvas by adding random dx and dy
        for (i = 0; i < smokeTrail1.length; i++) {
            var randomDx = (random(5));
            var randomDy = (random(-5,0));
            smokeTrail1[i].x += randomDx;
            smokeTrail1[i].y += randomDy;
            //reset x and y position if smoke leaves canvas
            if (smokeTrail1[i].y <= 10) {
                smokeTrail1[i].x = 400 + random(-10,10);
                smokeTrail1[i].y = 150;
            }
            circle(smokeTrail1[i].x, smokeTrail1[i].y, 50)
        }

        for (i = 0; i < smokeTrail2.length; i++) {
            var randomDx = (random(5));
            var randomDy = (random(-5,0));
            smokeTrail2[i].x += randomDx;
            smokeTrail2[i].y += randomDy;
            //reset x and y position if smoke leaves canvas
            if (smokeTrail2[i].y <= 10) {
                smokeTrail2[i].x = 500 + random(-10,10);
                smokeTrail2[i].y = 200;
            }
            circle(smokeTrail2[i].x, smokeTrail2[i].y, 50)
        }

        //smoke funnels
        fill(10);
        rect(370,160,50,150);
        rect(470,210,50,120);

        //drawing smoke accumulating at top of window
        calcWave();
        fill(100);
        beginShape();
        vertex(width,0);
        vertex(0,0);
        for (let x = 0; x <= yvalues.length; x++) {
            vertex(x * xspacing,  smokeLevel+ yvalues[x])
        }
        endShape(CLOSE);

        //walls
        fill(178,157,105);
        rect(0,0,width,30);
        rect(0,0,width-370,height);
        rect(0,width,-10,height);
        rect(0,height,width,-(height-310));

        //light switch
        fill(255);
        rect(70,140,70,100);
        fill(210);
        rect(75,190,60,45);

    }else if (lightSwitch == true) { //if light is turned on
        frameRate(20);
        noStroke();
        background(176,196,222);

        fill(50);
        //moving smoke up the canvas by adding random dx and dy
        for (i = 0; i < smokeTrail1.length; i++) {
            var randomDx = (random(5));
            var randomDy = (random(-5,0));
            smokeTrail1[i].x += randomDx;
            smokeTrail1[i].y += randomDy;
            //reset x and y position if smoke leaves canvas
            if (smokeTrail1[i].y <= 10) {
                smokeTrail1[i].x = 400 + random(-10,10);
                smokeTrail1[i].y = 150;
            }
            circle(smokeTrail1[i].x, smokeTrail1[i].y, 100)
        }

        for (i = 0; i < smokeTrail2.length; i++) {
            var randomDx = (random(5));
            var randomDy = (random(-5,0));
            smokeTrail2[i].x += randomDx;
            smokeTrail2[i].y += randomDy;
            //reset x and y position if smoke leaves canvas
            if (smokeTrail2[i].y <= 10) {
                smokeTrail2[i].x = 500 + random(-10,10);
                smokeTrail2[i].y = 200;
            }
            circle(smokeTrail2[i].x, smokeTrail2[i].y, 100)
        }

        //smoke funnels
        fill(10);
        rect(370,160,50,150);
        rect(470,210,50,120);

        //drawing smoke accumulating at top of window
        calcWave();
        fill(50);
        beginShape();
        vertex(width,0);
        vertex(0,0);
        for (let x = 0; x <= yvalues.length; x++) {
            vertex(x * xspacing,  smokeLevel+ yvalues[x])
        }
        endShape(CLOSE);

        //walls
        fill(247,224,169);
        rect(0,0,width,30);
        rect(0,0,width-370,height);
        rect(0,width,-10,height);
        rect(0,height,width,-(height-310));

        //lightswitch
        fill(255);
        rect(70,140,70,100);
        fill(210);
        rect(75,145,60,45);
    }
}

function treeUpdate() {
    //if saw intersects with tree, change the state of variable to true
    if (mouseX+40 > this.x & mouseX+40< this.x + this.hor) {
       this.intersect = true;
    }
}

function mousePressed() {
    //turn light switch on and off if mouse is pressed on lightswitch
    if (mouseX>70 & mouseX<140 && mouseY>190 && mouseY<240) {
        lightSwitch = true;
        skySmoke = 1;
    } else if (mouseX>70 & mouseX<140 && mouseY>140 && mouseY<190) {
        lightSwitch = false;
        skySmoke = 0;
    }
}

function polarBear() {
    //draws polar bear
    fill(255);
    ellipse(mouseX,mouseY,100,70);
    circle(mouseX-50,mouseY-30,50);
    circle(mouseX-70,mouseY-50,20);
    circle(mouseX-35,mouseY-50,20);
    rect(mouseX-40,mouseY+20,10,20,10);
    rect(mouseX+30,mouseY+20,10,20,10);
    fill(70,130,180);
    circle(mouseX-60,mouseY-30,5);
    circle(mouseX-40,mouseY-32,5);
    ellipse(mouseX-50,mouseY-25,10,5)

    //if polar bear moves below ocean surface, increase count of fails
    if (mouseY-70 >= seaHeight) {
        gameFail +=1;
    }
}

function calcWave() {
  // Increment theta (try different values for
  // 'angular velocity' here)
  theta += 0.2;

  // For every x value, calculate a y value with sine function
  let x = theta;
  for (let i = 0; i < yvalues.length; i++) {
    yvalues[i] = sin(x) * amplitude;
    x += dx;
  }
}

function renderWave(yPos) {
  noStroke();
  beginShape();
  vertex(0,height);
  // A simple way to draw the wave with an ellipse at each location
  for (let x = 0; x <= yvalues.length; x++) {
    vertex(x * xspacing, yPos + yvalues[x])
  }
  vertex(width,height);
  endShape(CLOSE);
}










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 14

My final project is both about light pollution and the aurora borealis. The details are revealed through the facts displayed when you click on the moon. The facts related to the aurorae detail how the same phenomenon that causes aurorae also cause ozone layer depletion. Additionally, the electron precipitation introduced during aurora enters the Earth’s thermosphere may cause further depletion of the ozone layer. (https://www.innovationnewsnetwork.com/evidence-of-earths-auroras-causing-mesospheric-ozone-layer-depletion/14279/). To talk about aurorae, we must also talk about light pollution. Particularly in cities, it’s difficult to see such views or any stars at all in the night sky. Pittsburgh has dealt with both these subjects; you can’t see stars at night, and recently aurorae was visible just north of the city.

sketch
//Julianna Bolivar
//jbolivar@andrew.cmu.edu
//Section D
//Final Project

var buildings = [];
var buildingsShowing = [];
var stars = [];
var starsShowing = [];
var counter = 0;
var starsCounter = 0;
var moonAngle = 0;

//gradient variables
const X_AXIS = 2;
let c1, c2;

var facts = ["Light pollution impacts animal behaviors, such as migration patterns, wake-sleep cycles, and habitat formation.", 
"Increased amounts of light at night lowers melatonin production, resulting in sleep deprivation, stress, anxiety, etc.", 
"Nocturnal light interrupts sleep and confuses the circadian rhythm in humans and animals.",
"Astronomers are concerned with light pollution as it reduces their ability to view celestial objects.", 
"The phenomena that causes aurorae also causes ozone layer depletion.",
"The ozone layer protects life on Earth from damaging UV light.",
"The electron precipitation that escapes into the thermosphere during aurora may cause further ozone layer depletion.",
"The aurora borealis was recently visible as low as in Pittsburgh."];
var index = 0;





var moonImg;
function preload(){
  //load image
  moonImg = loadImage("https://i.imgur.com/1lsi57S.png");
}

function setup() {
    createCanvas(640,240);
    frameRate(30);

    //lerp color for aurorae sky
    c1 = color(98, 6, 137); //purple
    c2 = color(1, 153, 82); //green
    
    //buildings
    for (var i = 0; i < 20;i++){
        var bldngs = random(width);
        buildings[i] = makeBuildings(bldngs);
    }

    //stars
    for (var i = 0; i < 20;i++){
        var strs = random(width);
        stars[i] = makeStars(strs);
    }
}

function draw() {
    fill(6, 11, 49);
    rect(0,0, 640, 240);

    //if mouse is at top, stars and aurorae appear
    if (mouseY<height/2){
        setGradient(0, 0, 710, 400, c2, c1, X_AXIS); 
        updateAndDrawStars();
        removeStarsOffScreen();
        addNewStars();
    }

    //moon spins
    push();
    translate(50, 50);   
    rotate(moonAngle);
    imageMode(CENTER);
    image(moonImg, 0, 0, 50, 50);
    pop();
    moonAngle+=.05;
   
    noStroke();
    updateAndDrawBuildings();
    removeBuildingsOffScreen();
    addNewBuildings();

    //facts cycle
    push();
    fill(255);
    textAlign(CENTER);
    textSize(9);
    textFont("Georgia");
    text(facts[index], width/2, 50);
    pop();
}

//gradient for new background
function setGradient(x, y, w, h, c1, c2, axis) {
  noFill();
    // Left to right gradient
    for (let i = x; i <= x + w; i++) {
      let inter = map(i, x, x + w, 0, 1);
      let c = lerpColor(c1, c2, inter);
      stroke(c);
      line(i, y, i, y + h);
    }
  }

function updateAndDrawBuildings(){
    for(var i=0; i < buildingsShowing.length; i++){
        buildingsShowing[i].move();
        buildingsShowing[i].draw();
    }

}

function removeBuildingsOffScreen(){
    var buildingsToKeep = [];
    for (var i = 0; i < buildingsShowing.length; i++){
        if (buildingsShowing[i].x+20 > 0) {
            buildingsToKeep.push(buildingsShowing[i]);
        }
    }
    buildingsShowing = buildingsToKeep; // remember showing buildings
}

function addNewBuildings(){
    counter+=1;
    if (counter % 65 == 0){
        buildingsShowing.push(makeBuildings(width, 0));
    }
}

//building object
function makeBuildings(bx, by){
    var buildings = {x:bx, y:by, 
        breadth: 50,
        nFloors: round(random(2,8)),
        bColor: random(50,125),
        speed: -1.0,
        move: buildingsMove,
        draw: drawBuildings }
    return buildings;

}

//building characteristics
function drawBuildings(){
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(this.bColor); 
    push();
    translate(this.x, height);
    noStroke();
    rect(0, -bHeight, this.breadth, bHeight);
    for (var i = 0; i < this.nFloors; i++) {
        fill(mouseY/height*200);
        rect(5, -15 - (i * floorHeight), this.breadth - 10, 10);
    }
    pop();

}

function buildingsMove(){
    this.x += this.speed;
}


//stars 
function updateAndDrawStars(){
    for (var i = 0; i < starsShowing.length; i++) {
        starsShowing[i].move();
        starsShowing[i].draw();
    }
}

function removeStarsOffScreen(){
    var starsToKeep = [];
    for (var i = 0; i < starsShowing.length; i++){
        if (starsShowing[i].starsX + 10 > 0) {
            starsToKeep.push(starsShowing[i]);
        }
    }
    starsShowing = starsToKeep;
}

function addNewStars(){
  starsCounter+=1;
    if (starsCounter % 5 == 0){
        starsShowing.push(makeStars(random(width), random(height)));
    }
}

//stars object
function makeStars(sx, sy){
    var s = {starsX: sx,
             starsY: sy,
             starsSpeed: -1,
             move: starsMove,
             draw: starsDraw}
    return s;
}

function starsMove(){
    this.starsX += this.starsSpeed;
}

function starsDraw(){
    fill(255);
    noStroke(); 
    circle(this.starsX, this.starsY, random(1,2));
}



//click on moon to flip through facts
function mousePressed(){
    if (mouseX<75&mouseX>25&&mouseY<75&&mouseY>25){
        index = floor(random(facts.length));
        if (index == facts.length) {
            index = 0;
        }
    }
}

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.

Final Project

I wanted to raise awareness about melting icebergs due to global warming so I created a game where a polar bear must jump on multiple floating icebergs to reach a safer large iceberg. I was inspired by games like frogger and crossy road and wanted to create an interactive easy game that would help users understand global warming better. To play the game user must press the space button to continue and press up to navigate. Land on the iceberg and you will be safe, if you land in the ocean, you will die. Make sure to move up before you drift off into the ocean. Also note that there are some weak icebergs that will break if you are unlucky. If I had more time I would work on creating levels with more iceberg rows and increasing speed of the icebergs, and maybe add more obstacles like a sea lion or natural predators of polar bears.

sketch

//code for screen changes
var currentScreen = "start";

//for the icebergs
var icebergs1 = [];
var icebergs2 = [];
var icebergs3 = [];
var icebergs4 = [];
var icebergs5 = [];
var x;

//for the movement of the game
var py = 0;
var count = 0;
var safe = true;

//for the melting icebergs
var beginIceberg = [];
var noiseParam = 0;
var noiseStep= 0.05;
var endingIceberg = [];
var noiseParam = 0;
var noiseStep= 0.05;

//for the baby polar bear location
var positionX = 250;
var positionY = 450;


function setup() {
    createCanvas(500, 500);
    text("p5.js vers 0.9.0 test.", 10, 15);
    start();
    //the initial icebergs
      for (var i = 0; i < 5; i++){
        x = 100*i;
        y = -50;
       icebergs1[i]=makeIceberg(x,y); 
      }
      for (var i = 0; i < 5; i++){
        x = 100*i;
        y = 50;
       icebergs2[i]=makeIceberg(x,y); 
      }
      for (var i = 0; i < 5; i++){
        x = 100*i;
        y = 150;
       icebergs3[i]=makeIceberg(x,y); 
      }
      for (var i = 0; i < 5; i++){
        x = 100*i;
        y = 250;
       icebergs4[i]=makeIceberg(x,y); 
      }
       
      for (var i = 0; i < 5; i++){
        x = 100*i;
        y = 350;
       icebergs5[i]=makeIceberg(x,y); 
      }
    //for the starting iceberg
      for (var i=0; i < width/5; i++){
        n=noise(noiseParam);
        value = map(n,0,1,400,450);
        beginIceberg.push(value);
        noiseParam += noiseStep;
    }

    //for the ending iceberg
     for (var i=0; i < width/5; i++){
      n=noise(noiseParam);
      value = map(n,0,1,-150,-100);
      endingIceberg.push(value);
      noiseParam += noiseStep;
    }
    
    frameRate(10);
}

function draw() {
  translate(0,py);
  //the blue ocean
  background(0,0,200);

  //the start screen
  if (currentScreen == "start"){
    start();
    if (keyIsPressed){
      currentScreen = "game";
    }
  }
  
  //plays the game screen
  else if (currentScreen == "game"){
    gameScreen();
  }
  
  //plays the lose screen
  else if (currentScreen == "lose"){
    elimination();
  }
  
  //playes the win screen
  else if (currentScreen == "win"){
    win();
  }
  

}

//Game Scene 

function gameScreen(){
  //the starting scene of the melting large iceberg
  meltingIceberg();
  
  //the icebergs
  updateAndDisplayIceberg();
  addNewIcebergs(); 
  
  //the movement of the game - to continuosly check if its on an iceberg
  if (count == 1){
      for (var i = 0; i < icebergs1.length; i++){
        if (positionX >= icebergs1[i].x & positionX + 20 <= icebergs1[i].x + icebergs1[i].width){
          positionX += 3;
          safe = true;
          break;;
        }
      }
    }
  if (count == 2){
      for (var i = 0; i < icebergs2.length; i++){
        if (positionX >= icebergs2[i].x & positionX + 20 <= icebergs2[i].x + icebergs2[i].width){
          positionX += 3;
          safe = true;
          break;
        }
      }
    }
  if (count == 3){
      for (var i = 0; i < icebergs3.length; i++){
        if (positionX >= icebergs3[i].x & positionX + 20 <= icebergs3[i].x + icebergs3[i].width){
          positionX += 3;
          safe = true;
          break;
        }
      }
    }
  if (count == 4){
      for (var i = 0; i < icebergs4.length; i++){
        if (positionX >= icebergs4[i].x & positionX + 20 <= icebergs4[i].x + icebergs4[i].width){
          positionX += 3;
          safe = true;
          break;
        }
      }
    }
  if (count == 5){
      for (var i = 0; i < icebergs5.length; i++){
        if (positionX >= icebergs5[i].x & positionX + 20 <= icebergs5[i].x + icebergs5[i].width){
          positionX += 3;
          safe = true;
          break;
        }
      }
    }
    
  if (positionX+20 > width){
    safe = false;
  }
    
  
    //if safe = false - game over
    if (safe == false){
      currentScreen = "lose";
      //noLoop()
    }
   
  //endgame
  if (count == 6){
    //display winning scene
    currentScreen = "win";
  }
 meltingIceberg2();
 
  //the baby polar bear 
  babyPolarBear();
}

//The large icebergs

function meltingIceberg(){
  fill("white");
  stroke("white");
  beginShape();
  vertex(0,height);
  
  for(i=0; i<width/5;i++){
    vertex(i*5,beginIceberg[i]);
  }
  
  vertex(width+50,height);
  endShape(CLOSE); 
  n=noise(noiseParam);
  value = map(n,0,1,400,450);
  beginIceberg.shift();
  beginIceberg.push(value);
  noiseParam += noiseStep;
}

function meltingIceberg2(){
 //The ending scene is a melting iceberg with the mother polar bear
  fill("white");
  stroke("white");
  beginShape();
  vertex(0,-600);
  
  for(i=0; i<width/5;i++){
    vertex(i*5,endingIceberg[i]);
  }
  
  vertex(width+50,-600);
  endShape(CLOSE); 
  n=noise(noiseParam);
  value = map(n,0,1,-150,-100);
  endingIceberg.shift();
  endingIceberg.push(value);
  noiseParam += noiseStep;
}


//code to do the jumps

//to draw baby polar bear and its respective movements (initally just a square, will later create details) 

function babyPolarBear(){
  fill("red");
  rect(positionX, positionY, 20,20); //might need to fix size later 
}

function keyPressed(){
  if (keyCode == UP_ARROW & currentScreen == "game"){
      py+=100;
      positionY -= 100;
      count++;
      safe = false;
      gameScreen();
    }
}

//object creation of the icebergs

function makeIceberg(x,y){
  var ice = {
    x,
    y,
    height: 25,
    width: floor(random(40,60)),
    speed: 3, 
    display: displayIceberg,
    move:moveIceberg
  }
  return ice;  
  }
 
 function displayIceberg(x,y){
   fill("white");
   rect(this.x,this.y,this.width,this.height);
 }   
 
 function moveIceberg(x){
   this.x+=this.speed;
 } 
 
 function updateAndDisplayIceberg(){
   for(var i = 0; i < icebergs1.length; i++){
     icebergs1[i].move();
     icebergs1[i].display();
   }
   for(var i = 0; i < icebergs2.length; i++){
     icebergs2[i].move();
     icebergs2[i].display();
   }
   for(var i = 0; i < icebergs3.length; i++){
     icebergs3[i].move();
     icebergs3[i].display();
   }
   for(var i = 0; i < icebergs4.length; i++){
     icebergs4[i].move();
     icebergs4[i].display();
   }
   for(var i = 0; i < icebergs5.length; i++){
     icebergs5[i].move();
     icebergs5[i].display();
   }
 }
   
 function addNewIcebergs(){ //should I change this to different logic?
   var newIcebergLikelihood = 0.05;
   var x = -40;
   if (random(0,1) < newIcebergLikelihood){
     icebergs1.push(makeIceberg(x,350));
   }
   if (random(0,1) < newIcebergLikelihood){
     icebergs2.push(makeIceberg(x,250));
   }
   if (random(0,1) < newIcebergLikelihood){
     icebergs3.push(makeIceberg(x,150));
   }
   if (random(0,1) < newIcebergLikelihood){
     icebergs4.push(makeIceberg(x,50));
   }
   if (random(0,1) < newIcebergLikelihood){
     icebergs5.push(makeIceberg(x,-50));
   }
 }
 

//Code to implement width

function icebergWidth(){
  return this.x + this.width;
}



//starting scene - instructions stuff - press space to continue
function start(){
  fill("green");
  rect(0,0,width,height);
  textSize(15);
  fill("white");
  text("Welcome to Save the POLAR BEAR from Global Warming", 50 ,200);
  textSize(15);
  fill("white");
  text("Press Space to Continue", 50,260);
  textSize(15);
  fill("white");
  let word = 'Instructions: Press the up key to move the polar bear (the red square) forward. Land on the iceberg and you will be safe, if you land in the ocean, you will die. Make sure to move up before you drift off into the ocean. Also note that there are some icebergs that are hidden if you are lucky and some weak icebergs that will break if you are unlucky. Can you reach the safe iceberg?'
  text(word,50,280, 400,200);
}

//The winning scene
function win(){
  fill("yellow");
  rect(0,0 - 100* count,width,height);
  textSize(50);
  fill("black");
  text("You have Won", 50 ,250 - 100* count);
  textSize(20);
  fill("black");
  text("Reload page to play again", 250,290 - 100* count);
}

// elimination scene 

function elimination(){
  fill("black");
  rect(0 ,0 - 100* count,width,height);
  textSize(50);
  fill("white");
  text("You have LOST", 50 ,250 - 100* count);
  textSize(20);
  fill("white");
  text("Reload page to play again", 250,290 - 100* count);
  
}


Final Project

sketch

var lines = []; // array of lines
var PGHannualAvg = [50.0, 50.4, 51.7, 49.0, 51.9, 53.8, 53.6, 52.6, 54.2, 54.5, 53.2, 52.3, 54.2, 51.2, 52.9, 54.1, 51.7, 53.4, 54.1, 53.8, 52.1, 51.6, 54.5, 52.3, 53.3, 53.3, 54.6, 53.6, 54.7, 52.6, 53.2, 52.9, 51.2, 52.0, 52.8, 50.7, 53.2, 52.2, 51.9, 53.7, 50.9, 53.6, 51.7, 52.0, 51.9, 49.3, 52.7, 53.3, 51.4, 55.4, 52.6, 50.3, 52.4, 50.8, 52.8, 51.6, 51.7, 53.1, 54.7, 53.5, 53.6, 52.6, 52.1, 51.0, 51.0, 53.0, 52.8, 49.6, 52.3, 51.6, 50.7, 52.0, 51.6, 53.6, 51.4, 52.4, 54.2, 51.1, 52.3, 52.9, 53.0, 51.8, 51.7, 51.0, 51.5, 48.8, 51.8, 49.1, 50.0, 49.4, 48.2, 51.1, 50.4, 50.1, 50.3, 49.1, 49.7, 50.7, 50.8, 49.9, 52.5, 51.4, 51.1, 48.0, 49.3, 49.7, 49.4, 49.5, 49.1, 50.4, 50.5, 50.4, 50.6, 51.7, 52.3, 51.0, 50.2, 53.3, 54.2, 50.9, 51.8, 51.6, 51.8, 50.3, 50.0, 54.0, 52.0, 50.8, 52.2, 52.6, 50.3, 51.6, 51.6, 52.3, 52.0, 50.9, 51.0, 51.9, 52.8, 54.2, 51.5, 50.0, 52.5, 54.2, 53.6, 52.3, 52.4, 53.3]
var Year = [];
var numLines = PGHannualAvg.length; // number of lines total
var lineWidth = 800/numLines; // width of lines

function preload() { // loads font info
    helveticaBold = loadFont('HelveticaNeueBold.ttf');
    helveticaUltraLight = loadFont('HelveticaNeueUltraLight.ttf');
    helveticaUltraLightObl = loadFont('HelveticaNeueUltraLightItal.ttf');
    helveticaLight = loadFont('HelveticaNeueLight.ttf');
    for (var i = 0; i < numLines; i++) { // pushes consecutive year info to year array
        Year.push(1872 + i);
    }
}

function setup() {
    createCanvas(800, 400);
    background(220);
    useSound();
}

function soundSetup() { // oscillator setup
    osc = new p5.Oscillator();
    osc.amp(0.25);
    osc.setType(sin);
    osc.start();
}

function makeLines() { // line object constructor
    for (i = 0; i < numLines; i++) {
        lines[i] = { x: i*lineWidth, y: height,
        temp: PGHannualAvg[i], draw: drawLines, c: chooseColor }
    }
}

function drawLines(line) { // function to draw lines
    noStroke();
    fill(this.c());
    rect(this.x, 0, lineWidth, this.y);
}

function chooseColor() { // if statements choosing colors based on temp array value
    if (this.temp <= 49.0) {
        return (color(0, 116, 255));
    }
    if (this.temp > 49.0 & this.temp <= 49.5) {
        return (color(5, 4, 254));
    }
    if (this.temp > 49.5 & this.temp <= 50.0) {
        return (color(82, 82, 254));
    }
    if (this.temp > 50.0 & this.temp <= 50.5) {
        return (color(126, 125, 253));
    }
    if (this.temp > 50.5 & this.temp <= 51.0) {
        return (color(183, 183, 255));
    }
    if (this.temp > 51.0 & this.temp <= 51.5) {
        return (color(251, 245, 133));
    }
    if (this.temp > 51.5 & this.temp <= 52.0) {
        return (color(249, 221, 13));
    }
    if (this.temp > 52.0 & this.temp <= 52.5) {
        return (color(254, 202, 5));
    }
    if (this.temp > 52.5 & this.temp <= 53.0) {
        return (color(254, 88, 2));
    }
    if (this.temp > 53.0 & this.temp <= 53.5) {
        return (color(234, 2, 0));
    }
    if (this.temp > 53.5) {
        return (color(133, 0, 0));
    }
}

function playSound() { // chooses oscillator frequency based on mouse index line
    var mInd = int(mouseX / lineWidth);
    osc.freq(chooseSound(PGHannualAvg[mind]));
}

function chooseSound(temp) { // if statements based on temperature index
    if (temp <= 49.0) {
        return (70);
    }
    if (temp > 49.0 & temp <= 49.5) {
        return (80);
    }
    if (temp > 49.5 & temp <= 50.0) {
        return (120);
    }
    if (temp > 50.0 & temp <= 50.5) {
        return (160);
    }
    if (temp > 50.5 & temp <= 51.0) {
        return (200);
    }
    if (temp > 51.0 & temp <= 51.5) {
        return (240);
    }
    if (temp > 51.5 & temp <= 52.0) {
        return (280);
    }
    if (temp > 52.0 & temp <= 52.5) {
        return (320);
    }
    if (temp > 52.5 & temp <= 53.0) {
        return (360);
    }
    if (temp > 53.0 & temp <= 53.5) {
        return (400);
    }
    if (temp > 53.5) {
        return (440);
    } 
}

function drawTitle() { // draws black bar and title text
    rect(0, 325, 800, 100);
    fill(255);
    textSize(18);
    textFont(helveticaBold);
    text("1872", 10, 350);
    text("2020", 748, 350);
    stroke(255);
    line(61, 343, 738, 343);
    line(732, 337, 738, 343);
    line(732, 349, 738, 343);
    noStroke();
    text("Annual Average Temperatures: Pittsburgh", 235, 375);
}

function showMouseInfo() { // black hover rectangle with bar info
    var mInd = int(mouseX / lineWidth);
    noStroke();
    fill(255);
    if ((mouseY < 325) & (mouseX > 0) && (mouseX < width) && (mouseY > 0)) {
        noFill();
        stroke(255);
        strokeWeight(2);
        rect(mInd*lineWidth, 0, lineWidth, 325);
        if (mouseX < 725) {
            noStroke();
            fill(0);
            rect(mouseX + 20, mouseY, 65, 40);
            fill(255);
            textFont(helveticaBold);
            text(Year[mInd], mouseX+25, mouseY+18);
            textFont(helveticaLight);
            text(PGHannualAvg[mInd]+"°F", mouseX+25, mouseY+34);
        }
        else {
            noStroke();
            fill(0);
            rect(mouseX - 70, mouseY, 65, 40);
            fill(255);
            textFont(helveticaBold);
            text(Year[mInd], mouseX- 65, mouseY+18);
            textFont(helveticaLight);
            text(PGHannualAvg[mInd]+"°F", mouseX-65, mouseY+34);            
        }
    }
}

function draw() { // main draw function
    background(0);
    noStroke();
    makeLines();
    for (i = 0; i < numLines; i++) {
        lines[i].draw();
        fill(0);
    }
    drawTitle();
    showMouseInfo();
    var mInd = int(mouseX / lineWidth);
    osc.freq(chooseSound(PGHannualAvg[mInd]));
}

My program is a data visualization of Pittsburgh’s fluctuating average annual temperatures over time. I took data from the historical records of the Pittsburgh International Airport weather station from 1872 through 2020. Each of the colored bars represent a year and its average temperature. The colors represent the temperatures–the warmer the color, the hotter the temperature, and vice versa. The user can use their mouse cursor to hover over the bars and view information for that particular one–the year and temperature from that year. There is also an aspect of sound–the temperatures relate to a frequency level that plays when the user hovers over the bar. The higher the temperature, the higher the frequency that is played.

Note: I used external fonts uploaded via local files and displayed using a local server, but I’m not sure how to upload those so that WordPress can run them. I tried Imgur but they don’t support TrueType font files.

Final Project

sketch

//jlococo
//Jacky Lococo

var xp = 0;
var yp = 40;
var dxp = 5;
var bird = [ ];
var xcir = 350;
var ycir = 200;
var angle = 0;
var smoke = [ ];
var cloud = [ ];
var tree = [ ];
function setup() {
    createCanvas(700, 400);

    for (var i = 0; i <5; i++){ //for loop for the bird array
        bird[i] = new Object();
        bird[i].x = width;
        bird[i].y  = random(100, 200);
        bird[i].dx = random(-2, -4.5);
        bird[i].c = color(21, 76, 114);
    }

    for (var i = 0; i < 11; i++){ //for loop for the smoke array
        smoke[i] = new Object();
        smoke[i].x = random(40, 140);
        smoke[i].y  = random(0, 100);
        smoke[i].dx = 4;
        smoke[i].s = random(20, 35);
        smoke[i].c = 150;
    }

    for (var i = 0; i < 9; i++){ //for loop for the clouds
        cloud[i] = new Object();
        cloud[i].x = random(width/2 + 60, width);
        cloud[i].y  = random(0, height/2 - 30);
        cloud[i].dx = 4;
        cloud[i].s = random(70, 120);
        cloud[i].c = 230;
    }

    for (var i = 0; i < 20; i++){ //for loop for the trees
        tree[i] = new Object();
        tree[i].x = random(width/2 + 60, width);
        tree[i].y  = random(height/2 + 135, height);
        tree[i].s = random(70, 120);
    }

    frameRate(15);
}



function draw() {
    background(230);
 
 //------------------ CITY ------------------
    //background of city
    noStroke();
    fill(230);
    beginShape();
    vertex(0,0);
    vertex(0, height);
    vertex(width/2-20, height);
    vertex(width/2+20, 0);
    endShape();

    //smokestacks
    fill(200);
    rect(50, 100, 25, 300);
    rect(100, 100, 25, 300);

    //drawing the smoke
    for (var i = 0; i < 11; i++){
        draw_smoke(smoke[i]);
    }

    //2nd row of buildings
    fill(170);
    rect(50, 220, 100, 300);
    rect(140, 200, 100, 300);
    rect()

    //buildings front row
    noStroke()
    fill(90);
    rect(0, 200, 100, 420);
    rect(100, 240, 75, 420);
    rect(175, 180, 45, 300);
    rect(220, 200, 50, 300);
    rect(260, 300, 80, 200);

    //windows
    if(mouseX < width/2){ //makes the lights turn on and off
        fill(241, 216, 3, 150);
    } else {
        fill(230); //fills them with the background when mouse is on right
    }
    rect(220, 220, 10, 20);
    rect(247, 270, 10, 20);
    rect(220, 340, 10, 20);
    rect(150, 300, 10, 20);
    rect(110, 275, 10, 20);
    rect(45, 370, 10, 20);
    rect(33, 230, 10, 20);


    //moving plane in the background
    airPlane(xp, yp, dxp);
    xp +=dxp;


//--------------- FOREST -------------------
    //background of forest
    noStroke();
    fill(185, 220, 236);
    beginShape();
    vertex(width/2-20, height);
    vertex(width/2+20, 0);
    vertex(width, 0);
    vertex(width, height);
    endShape();

    //clouds
    for (var i = 0; i < 9; i++){
        draw_cloud(cloud[i]);
    }

    //MOUNTAINS
    fill(137, 184, 206);
    //first larger shape
    beginShape();
    vertex(width/2+30, height);
    vertex(550, 150);
    vertex(600, 150);
    vertex(700, 300);
    vertex(700, height);
    endShape();
    //second shape shorter mountain
    beginShape();
    vertex(width/2-20, height);
    vertex(430, 240);
    vertex(480, 240);
    vertex(550, height);
    endShape();
    //circles rounding mountains
    ellipse(575, 161, 54, 54);
    ellipse(455, 250, 53, 52);

    //HILL behind - darker shade
    beginShape()
    fill(88, 106, 36);
    vertex(width/2-20, height);
    vertex(width/2-10, 280);
    vertex(600, 400)
    endShape()

    //HILL - quarter of circle
    fill(127, 148, 68);
    ellipse(670, height+70, 730, 350);

    //trees
    for (var i = 0; i < 20; i++){ //for loop for the trees
        draw_tree(tree[i]);
    }

    //birds
    for (var i = 0; i < 5; i++) {
        draw_bird(bird[i]);
        if (bird[i].x < width/2){ //changing bird location after they reach midpoint
            bird[i].x = width +100;
        }
        bird[i].x += bird[i].dx; //making birds move

        if (mouseX < width/2){ //making the birds stop when mouse is on city half
            bird[i].dx = 0
        }else{
            bird[i].dx = random(-1, -4.5);
        }
        if(mouseIsPressed & dist(mouseX, mouseY, xcir, ycir) < 30){ //making birds stop with circle pressed
            bird[i].dx = 0;
        }
    }

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

    //FOREST OPACITY FILLS
    if(mouseX < width/2){
        noStroke();
        fill(0, 100);
        beginShape();
        vertex(width/2-20, height);
        vertex(width/2+20, 0);
        vertex(width, 0);
        vertex(width, height);
        endShape();
    }

    //masking shape
    fill(230);
    beginShape();
    vertex(width/2+10, 80);
    vertex(width/2-5, 230);
    vertex(300, 230);
    vertex(300, 80);
    endShape();

    //OPACITY FILLS CITY AND VELOCITY STOPS
    if(mouseX > width/2){
        noStroke();
        fill(0, 100);
        beginShape();
        vertex(0,0);
        vertex(0, height);
        vertex(width/2-20, height);
        vertex(width/2+20, 0);
        endShape();
        dxp = 0;
    } else {
        dxp = 5;
    }
    if(xp > width/2 +30){
        xp = 0 - 50;
    }


    //Lines and circle
    fill(100, 150);
    stroke(255);
    strokeWeight(4);
    line(width/2+20, 0, width/2-20, 400);
    ellipse(xcir, ycir, 60, 60);
    noStroke();
    fill(255);
    textSize(10);
    text('P R E S S', xcir-23, ycir+4);


    //CURSOR - icons following the mouse
    if(mouseX > width/2){ //mouse is flower on forest section
        noStroke();
        flower();
    } else { //mouse is three little grey smoke dots
        noStroke();
        fill(50, 100);
        ellipse(mouseX + 9, mouseY +5, 11, 11);
        ellipse(mouseX - 9, mouseY+5, 11, 11);
        ellipse(mouseX, mouseY - 8, 11, 11);
    }

    //CIRCLE MOUSE PRESSED - if mouse is pressed on cirlce fact shows up
    if(mouseIsPressed & dist(mouseX, mouseY, xcir, ycir) < 30){
        fill(0, 150);
        rect(0, 0, 700, 400);
        dxp = 0;
    fill(255)
        textSize(15)
        text('Urban areas and urbanization is a major contributor of climate change,', 140, 100)
        text('making up baout 75% of CO2 emissions from global energy use.', 150, 130)
    }
}



//------------ FUNCTIONS -----------
function flower(){ //creates cursor flower
    fill(233, 199, 10, 200);
    ellipse(mouseX, mouseY, 15, 15);
    fill(255, 154, 154, 200);
    ellipse(mouseX+10, mouseY, 8, 8);
    ellipse(mouseX-10, mouseY, 8, 8);
    ellipse(mouseX, mouseY-10, 8, 8);
    ellipse(mouseX, mouseY+10, 8, 8);
    ellipse(mouseX+7, mouseY+7, 8, 8);
    ellipse(mouseX-7, mouseY-7, 8, 8);
    ellipse(mouseX-7, mouseY+7, 8, 8);
    ellipse(mouseX+7, mouseY-7, 8, 8);
}

function airPlane(xp, yp, dxp){ //creates airplane moving in the background
    fill(200);
    rect(xp, yp, 40, 10);
    ellipse(xp+40, yp+5, 15,10);
    ellipse(xp, yp, 5, 20);
    fill(175);
    ellipse(xp+ 15, yp+7, 23, 5);
    strokeWeight(2);
    stroke(220, 180);
    line(xp, yp+10, xp-150, yp+10);
}

function draw_tree(t){
    fill(0);
    rect(t.x, t.y, 5, 10);
    fill(63, 111, 85);
    triangle(t.x +2, t.y-10, t.x - 5, t.y+5, t.x+10, t.y+5);
}

function draw_bird(b){
    fill(b.c);
    ellipse(b.x, b.y, 10, 10);
    fill(214, 216, 3);
    ellipse(b.x -6, b.y, 4, 4);
    fill(13, 39, 56);
    ellipse(b.x + 4, b.y, 7, 5);
}

function draw_smoke(s){
    fill(s.c, 160);
    circle(s.x, s.y, s.s);
}

function draw_cloud(c){
    fill(c.c, 150);
    circle(c.x, c.y, c.s);
}


    







``