Final Project

sketch

// Name: Aysha Zackria
// AndrewID: azackria
// Section D

var firelocationx = [];
var firelocationy = [];
var smoke = {
    locationx:[], 
    locationy:[], 
    size: 75
}
var counter = 1;
var xoff = 0;
var firesize = 12;
var treelocationx = [];
var treelocationy = [];
var r = 133;
var g = 214;
var b = 139;
var waterr = 131;
var waterg = 228;
var waterb = 234;
var smokecolor = 240;

function setup() {
    createCanvas(500, 500);
    for (var i = 0; i < 25; i++) {
        firelocationx.push(random(20, 480));
        firelocationy.push(random(45, 330));
        treelocationx.push(random(20, 480));
        treelocationy.push(random(35, 330));
    }
}

function draw() {
    background(r, g, b);
    r = map(firelocationx.length, 25, 100, 133, 43);
    g = map(firelocationx.length, 25, 100, 214, 24);
    b = map(firelocationx.length, 25, 100, 139, 8);
    noStroke();
    fill(0);
    if (firelocationx.length < 30) {
        text("Slowly drag the fire into the water to put it out.", 10, 15);
    } else if (firelocationx.length >= 30 & firelocationx.length <= 35) {
        text("Drag the fire into the water to put it out.", 10, 15);
    } else if (firelocationx.length > 35 & firelocationx.length < 40) {
        text("Drag the fire into the water.", 10, 15);
    } else if (firelocationx.length >= 40) {
        text("Put the fire out.", 10, 15);
    }
    noStroke();
    fill(waterr, waterg, waterb);
    waterr = map(firelocationx.length, 25, 100, 131, 25);
    waterg = map(firelocationx.length, 25, 100, 228, 54);
    waterb = map(firelocationx.length, 25, 100, 234, 92);
    rect(0, 350, 500, 150); // water
    let nx = noise(xoff) * 600;
    let ny = noise(xoff+10) * 500;
    if ((counter % 20) == 0) {
        smoke.locationx.push(nx);
        smoke.locationy.push(ny);
    }
    for (var i = 0; i < treelocationx.length; i++) {
        drawtree(i);
    }
    for (var i = 0; i < firelocationx.length; i++) {
        drawfire(i);
        if (mouseIsPressed & dist(firelocationx[i], firelocationy[i], 
            mouseX, mouseY) < 12) {
            firelocationx[i] = mouseX;
            firelocationy[i] = mouseY;
        }
        if (firelocationy[i] > 350) {
            firelocationy.splice(i, 1);
            firelocationx.splice(i, 1);
        }
    }
    fill(smokecolor, 100);
    smokecolor = map(firelocationx.length, 25, 100, 240, 100);
    for (var i = 0; i < smoke.locationx.length; i++) {
        circle(smoke.locationx[i], smoke.locationy[i], smoke.size);
    }
    counter += 1;
    xoff += 0.1;
    if ((counter % 100) == 0) {
        firelocationx.push(random(20, 480));
        firelocationy.push(random(35, 330));
    }
}

function drawtree(i) {
        strokeWeight(4);
        stroke(165, 115, 75);
        line(treelocationx[i], treelocationy[i] - 2, 
            treelocationx[i], treelocationy[i] - 10);
        stroke(50, 100, 50);
        fill(50, 100, 50);
        triangle(treelocationx[i], treelocationy[i] - 15, treelocationx[i] - 3, 
            treelocationy[i] - 10, treelocationx[i] + 3, treelocationy[i] - 10);
        triangle(treelocationx[i], treelocationy[i] - 10, treelocationx[i] - 3, 
            treelocationy[i] - 5, treelocationx[i] + 3, treelocationy[i] - 5);
}

function drawfire(i) {
    fill(255, 100, 0); 
    noStroke();
    push();
    translate(firelocationx[i], firelocationy[i]);
    scale(firelocationx.length / 15);
    circle(0, 0, firesize);
    triangle(-(firesize / 2), -1, (firesize / 2), -1, 0, -20);
    pop();
}

My program is a game that includes fire and smoke appearing at regular intervals on a background of grass and trees. The fire can be extinguished by dragging it into the water area. The game is designed to not be winnable to reflect my growing feeling of hopelessness in regards to the climate crisis. The smoke ultimately obscures a good portion of the screen while the colors of the background and water grow darker to mimic soot buildup. The text direction in the top left corner also changes to convey a sense of urgency as the user gets more frustrated. I didn’t end up implementing any separate sound or image files, so the program can be run normally. If I had more time, I would probably add simple sounds to accompany the fires appearing and disappearing.

Final Project

sketch

// gnmarino
// Gia Marino
// section D

var cords = [];
function setup() {
    createCanvas(223.2, 223.2);

    // need counter so there doesn't need to be another loop
    var counter = 0;

    // stores in an array all the cordinate points of the squares
    for(var x = 0; x < 93; x++){
        for(var y = 0; y < 93; y++){
            cords[counter]= new Object();
            cords[counter].x = (x * 2.4);
            cords[counter].y = (y * 2.4);
            counter += 1
        }
    }
}
var squares = [];   // array stores makeSquare

function draw() {
    background(20);

    if(cords.length == 1){
        fill(255);
        textSize(10);
        text('Every square represents 24 metric tons',10, 15);
        text('of CO2 emissions produced from the US daily', 10, 30);
        for(var i = 0; i < 8649; i++){
            squares[i].moveSqr();
        }
        noLoop();
    }

    // makes a new array with every square object with a random xy cordinate
    squares.push(makeSquare(int(random(cords.length))));

    // displays a new square with the previous old squares
    // and displays new opactities
    for(var i = 0; i < squares.length; i++){ 
        squares[i].display();
        squares[i].changeOpacity();
    }
}

function moveSquares(){

    // scales visualization down and moves it
    for(var i = 0; i < 8649; i++){
        push();
        scale(.5);
        translate(112, 150);
        squares[i].display();
        pop();
        if(this.x < width/2 & this.x > 5){
            this.x --
        }
        if(this.x > width/2 && this.x < width-5){
            this.x ++ 
        }

    }
    noLoop();
}

function changeColor(){
    // once a square has been in frame for 15 seconds 
    // it starts to lower opacity to 40
    this.age ++
    if(this.age > 15 & this.opacity > 40){
        this.opacity -= 1;
    }

    // at the end all the squares return to opacity 230
    if(cords.length == 2){
        this.opacity = 230;
    }
}

function displaySquare(){
    fill(this.red, this.green, this.blue, this.opacity);
    noStroke();
    rect(this.x, this.y, 2.4, 2.4);
}

function makeSquare(cordNum){
    var square = {x: cords[cordNum].x,
                  y: cords[cordNum].y,
                  red: random(255),
                  blue: random(255),
                  green: random(255),
                  opacity: 255, 
                  age: 0,
                  display: displaySquare,
                  changeOpacity: changeColor,
                  moveSqr: moveSquares}

   // once a square cord is extracted from the array
   // it is removed so it isn't reused
    cords.splice(cordNum, 1);
    return square;
}

For my final project I made a data visualization of the daily carbon emissions in the US. I found a statistic that stated “Passenger cars produced 762.3 million metric tons of CO2 in 2019 [in the US]” (https://www.statista.com/statistics/1235091/us-passenger-car-ghg-emissions-by-vehicle-type/). I was overall inspired by how much the US’s lack of public transportation contributes to CO2 emissions.

I did the math and found that the US produces 24 metric tons of CO2 per second (52,910 lbs). So I figured out how to fit this perfectly on a square canvas with squares and found that if I had a canvas with the size of 223.2 x 233.3 and each square was 2.4, then it would be the correct ratio.

I decided to not make my visualization actually run second by second because it would look kinda boring. So, I sped it up, however each square does proportional represent one second of c02 emissions.

I decided to make my squares fade each time so you could see all the new squares popping in more clearly, because the point of the visualization is to see how many squares there are to represent really how much CO2 is produced each day!

Then at the end I minimize so you can see it all together and then you see the statistic so you know what the pretty animation represented.

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










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

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

var x= 30;
var xPos = 0;
var y = 60
var r = [55, 98, 145, 195] //radius of visualization 1
var angle =10
var cycle = 1; //cycle through the different visualizations
var transparent =100 //used for key
var value = 0
var yr = 1980

//precipitation data
var precip1 = [39.46, 37.5, 32.01, 41.41, 35.32, 38.51, 37.4, 39.2, 
            27.09, 42.51]

var precip2 = [52.24, 32.02, 36.65, 38.26, 41.34, 28.89, 45.47, 34.21,
            36.21, 40.12]

var precip3 = [35.73, 32.33, 41.04, 57.41, 41.23, 34.90,40.70, 39.69, 32.84, 
            37.85]

var precip4 = [44.24, 41.74, 36.65, 36.84, 40.56, 35.01, 42.15, 57.83, 52.46, 39.33]
//used for text in vizualization 1
precipData = [39.46, 37.5, 32.01, 41.41, 35.32, 38.51, 37.4, 39.2, 
            27.09, 42.51, 52.24, 32.02, 36.65, 38.26, 41.34, 28.89, 45.47, 34.21,
            36.21, 40.12,35.73, 32.33, 41.04, 57.41, 41.23, 34.90,40.70, 39.69, 32.84, 
            37.85, 44.24, 41.74, 36.65, 36.84, 40.56, 35.01, 42.15, 57.83, 52.46, 39.33]

var precipitation = []
var precipitation2 = []
var precipitation3 = []
var precipitation4 = []

//temperature data
var temp = [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, 54, 52, 50.8, 52.2, 52.6, 50.3, 51.6, 51.6, 52.3,
            52, 50.9, 51, 51.9, 52.8, 54.2, 51.5, 50, 52.5, 54.2, 53.6, 52.3, 52.4, 53.3 ]

//images
var skyline;
var backdrop;
var buildings;

var snow = []

function preload() {
    skyline = loadImage("https://i.imgur.com/U7UJvXu.png")
    backdrop = loadImage("https://i.imgur.com/vShIEDi.png")
    buildings = loadImage("https://i.imgur.com/dfPYkth.png")
}

function setup() {
    createCanvas(480, 480);
    background(220);

     for (var i = 0; i < 10; i++) {
        precipitation[i] = new Object();
        precipitation[i].x = r[0] * sin(angle);
        precipitation[i].y = r[0] * cos(angle);
    }

    for (var i = 0; i < 10; i++) {
        precipitation2[i] = new Object();
        precipitation2[i].x = r[1] * sin(angle);
        precipitation2[i].y = r[1] * cos(angle);
    }

     for (var i = 0; i < 10; i++) {
        precipitation3[i] = new Object();
        precipitation3[i].x = r[2] * sin(angle);
        precipitation3[i].y = r[2] * cos(angle);
    }

     for (var i = 0; i < 10; i++) {
        precipitation4[i] = new Object();
        precipitation4[i].x = r[3] * sin(angle);
        precipitation4[i].y = r[3] * cos(angle);
    }

       for (var i = 0; i < 500; i++) {
        snow[i] = new Object();
        snow[i].x = random(30, width-30)
        snow[i].y = random(60, 300)
        snow[i].dy = 1;
    }

}

function draw() { //cycles through the different climate patterns
    if (cycle == 1) {
        introduction()
    } else if (cycle == 2) {
        drawPrecipitation()
    } else if (cycle ==3) {
        drawTemp()
    } else if (cycle == 4) {
        drawSnowRecord()
    } else {
         cycle = 1
    }
}
function introduction() { //first slide
    background(0)
    fill(255)
    textSize(15)
    text("Data Visualizations on Climate Patterns in Pittsburgh", 10, height/2)
    textSize(12)
    text("Click mouse to change data", 10, height/2+20)
}
function drawPrecipitation() {
    background(255, 229, 227)
    fill(0)
    textSize(15)
    text("Average Precipitation in Pittsburgh (1980-2020)", 10, 25)
    frameRate(int(1.5))
    noStroke()

//bottom left key
    fill(214, 132, 84, 100)
    rect(10, 420, 30, 10)

    fill(214, 132, 84, 100-15)
    rect(10, 431, 30, 10)

    fill(214, 132, 84, 100-30)
    rect(10, 442, 30, 10)

    fill(214, 132, 84, 100-45)
    rect(10, 453, 30, 10)
       
    textSize(8)
    fill(0)
    text("1980-1990", 45, 427)
    text("1990-2000", 45, 427+11)
    text("2000-2010", 45, 427+22)
    text("2010-2020", 45, 427+33)

    translate(width/2, height/2+15)

    fill(214, 132, 84, 60)
    noStroke()
    circle(0, 0, 150)
    circle(0, 0, 240)
    circle(0, 0, 337)
    circle(0, 0, 440)
    fill(214, 132, 84, 50)
    circle(0, 0, 70)


//ring of ellipses
    for (var i=0; i<precip1.length; i++) {
        noStroke()
        fill(0, 255-precip1[i]*3, precip1[i]*4)
        rotate(radians(360/10))
        circle(precipitation[i].x, precipitation[i].y, precip1[i]/1.4)
    }

      for (var i=0; i<precip2.length; i++) {
        var x = r[1] * sin(angle);
        var y = r[1] * cos(angle);
        noStroke()
        fill(0, 255-precip2[i]*3, precip2[i]*4)
        rotate(radians(360/10))
        circle(precipitation2[i].x, precipitation2[i].y, precip2[i]/1.4) //change to object
    }

      for (var i=0; i<precip3.length; i++) {
        var x = r[2] * sin(angle);
        var y = r[2] * cos(angle);
        noStroke()
        fill(0, 255-precip3[i]*3, precip3[i]*4)
        rotate(radians(360/10))
        circle(precipitation3[i].x, precipitation3[i].y, precip3[i]/1.4)
    }

      for (var i=0; i<precip4.length; i++) {
        var x = r[3] * sin(angle);
        var y = r[3] * cos(angle);
        noStroke()
        fill(0, 255-precip4[i]*3, precip4[i]*4)
        rotate(radians(360/10))
        circle(precipitation4[i].x, precipitation4[i].y, precip4[i]/1.4)
    }

    
    textSize(10)
    text(precipData[value], -10, 10)
    value+=1

    if (value>40) {
        value=0
    }
    textSize(15)
    text(yr, -15, 0)
    yr+=1

    if (yr >2020) {
        yr=1980
    }
}


function drawTemp() {
    background(235, 88, 52)
    textSize(15)
    fill(0)
    text("Average Temperature in Pittsburgh (1980-2020)", 10, 25)
    frameRate(25)

    translate(width/2,height/2)
    //background circles
    fill(255, 255, 255, 70)
    circle(0, 0, 400, 400)
    fill(235, 88, 52)
    circle(0, 0, 150, 150)
    //rotating circle data
    for (var i =0; i<temp.length; i++) {
        rotate(radians(angle))
        // xPos=(300/2 * cos(temp[i]))
        fill(temp[i]*3,0,0, 80)
        circle(xPos, 100, temp[i]/2)
        angle+=.01
    }
}


function drawSnowRecord() {
    background(10,31,50)
    fill(255)
    text("Greatest Snowfall in One Day in Pittsburgh", 10, 25)
    push()
    textSize(10)
    text("Hover over the snowballs", 10, 40)
    pop()

    image(backdrop, 20, 92)
    circle(420, 290, 60)
    image(skyline, 30, 150)
    fill(250, 250, 250)
    circle(260, 300, 40)
    circle(150, 305, 30)
    image(buildings, 30, 272)
    circle(80, 300, 50)
    circle(330, 290, 80)
    pop()
    //data appears when hovering over snowballs

      if ((dist(330, 290, mouseX, mouseY) < 80/2)) {
        text("March 13, 1993: 23.6 inches of snow", 130, 400)
    }

      if ((dist(420, 290, mouseX, mouseY) < 60/2)) {
        text("December 17, 1890: 22 inches of snow", 130, 400)
    }

      if ((dist(80, 300, mouseX, mouseY) < 50/2)) {
        text("January 8, 1884: 16.5 inches of snow", 130, 400)
    }

      if ((dist(260, 300, mouseX, mouseY) < 40/2)) {
        text("March 3, 1942: 16.3 inches of snow", 130, 400)
    }

      if ((dist(150, 305, mouseX, mouseY) < 30/2)) {
        text("March 5, 1902: 15 inches of snow", 130, 400)
    }
    //snow
      for (var i=0; i<500; i++) {
        noStroke()
        fill(255)
        circle(snow[i].x, snow[i].y, 2)
    }


}


function mousePressed() { //changes visualzation when mouse clicked
    cycle += 1;
}


        
    






   

Final Project

For my final project, I was inspired by the capitalist need for consumption over all else. Specifically, I’ve been concerned with over-fishing (I even wrote one of my essays to apply to CMU about fishing net pollution). So, I created a game that simulates capitalist motives in regards to fishing.

In the game, your cursor becomes a fishing hook which you can use to click on the fish and catch them. This will momentarily make the screen flash green and increase the amount of money you’ve made. However, once all the fish are caught, the coral dies off and the ocean becomes much less vibrant than it was before. Finally, a message will pop up warning the player about the effects of over-fishing. However, if the player goes for a minute and a half without killing all the fish, a message will pop up to congratulate them on being a conscious consumer.

I added everything I intended for the program, but I can definitely see how I could add more aspects to make this a more complete and polished screen, like a system to replenish the fish gradually. Also, moving seaweed or bubbles might be nice. But I am happy with this outcome.

sketch

//Elise Chapman
//ejchapma
//ejchapma@andrew.cmu.edu
//Section D

f=[]; //array for the fish
fClick=[]; //array for tracking the clicked 
var sandy = []; //for the sand
var noiseParam = 5; //for the sand
var noiseStep = 0.005; //for the sand
//color variables so that the coral can turn gray
var tube1;
var tube2;
var tube3;
var brain1;
var brain2;
var gray1=125;
var gray2=100;
var moneyCount=0; //counts the money
var timer=0; //for tracking after fish die
var timerLive=0; //for tracking time for player for being good

function setup() {
    createCanvas(600, 300);
    rectMode(CENTER);
    strokeJoin(ROUND);
    textAlign(CENTER,CENTER);
    noCursor();
    frameRate(10);
    //fish setup
    for (var i=0; i<20; i+=1) {
        f[i]=new Object();
        f[i].x=random(30,width-31);
        f[i].y=random(75,height-31);
        f[i].dx=random(-10,11); //change in x
        r=int(random(0,256));
        //g=int(random(0,256));
        b=int(random(0,256));
        f[i].c=color(r,0,b); //fish color
    }

    //for the sand
    noiseSeed(87);
    for (var i=0; i<(width/5)+1; i+=1) {
        var n=noise(noiseParam);
        var value=map(n,0,1,0,height);
        sandy[i]=value;
        noiseParam+=noiseStep;
    }

    //tube colors
    tube1=color(67,87,173) //blue
    tube2=color(242,160,242); //pink
    tube3=color(239,99,81); //red
    brain1=color(97,208,149); //green
    brain2=color(249,199,132); //yellow
}

function draw() {
    if (f.length<1 & timer>90) {
        background(122,161,187); //darker ocean blue
    } else {
        background(74,225,255); //ocean blue
    }
    sandscape();
    coral();
    seaweed(15,100);
    seaweed(40,175);
    seaweed(250,200);
    seaweed(275,75);
    seaweed(300,125);
    seaweed(450,225);
    seaweed(550,175);
    seaweed(575,100);
    //fish
    for (var i=0; i<f.length; i+=1) {
        fish(f[i].x,f[i].y,f[i].dx,f[i].c);
        f[i].x+=f[i].dx;
        if (f[i].x<15 || f[i].x>width-15) {
        f[i].dx=-f[i].dx;
        }
    }
    //bad ending
    if (timer>120 & f.length<1) {
        push();
        translate(width/2,height/2)
        noStroke();
        fill(0,0,0,200);
        rect(0,0,600,300);
        strokeWeight(1);
        stroke(255);
        fill(255);
        text("You've chosen greed over the fish.\nOver-fishing is one of the greatest causes \nof devastation for our oceans.\nDoes making a quick buck make killing the coral worth it?\nI should hope not.\nAlways choose the environment."
            ,0,0);
        pop();
    }
    //money
    noStroke();
    fill(255); //white
    rect(75,30,100,50,10,10,10,10);
    strokeWeight(2);
    stroke(0,122,4); //green
    fill(0,122,4); //green
    textSize(20);
    text("$"+str(moneyCount),75,30);
    //fish hook
    if (f.length>0) {
        fishHook(mouseX,mouseY);
    }
    if (f.length<1) {
        timer++;
    }
    //good ending
    if (timerLive>6300 & f.length>1) {
        push();
        translate(width/2,height/2)
        noStroke();
        fill(0,0,0,200);
        rect(0,0,600,300);
        strokeWeight(1);
        stroke(255);
        fill(255);
        text("Congrats!\nYou've chosen to fish sustainably, or not at all.\nAs over-fishing continues to be a source of \ndevastation for our oceans, please continue\nto advocate for healthy fishing!\n:)"
            ,0,0);
        pop();
    }
    timerLive++;
}

//swimming fish
function fish(x,y,dx,c) {
    noStroke();
    fill(c);
    ellipse(x,y,40,30);
    //moving left
    if (dx<0) {
        triangle(x+15,y,x+30,y+15,x+30,y-15);
        triangle(x-20,y,x+10,y-25,x+10,y);
        triangle(x-20,y,x+10,y+25,x+10,y);
        fill(0);
        ellipse(x-7,y-3,9);
    //moving right
    } else if (dx>=0) {
        triangle(x-15,y,x-30,y+15,x-30,y-15);
        triangle(x+20,y,x-10,y-25,x-10,y);
        triangle(x+20,y,x-10,y+25,x-10,y);
        fill(0);
        ellipse(x+7,y-3,9);
    }
}

//landscape made of sand
function sandscape() {
    //sets up the sand
    strokeWeight(3);
    stroke(242,231,189); //beige
    fill(242,231,189); //beige

    //creates the sand
    push();
    translate(0,10);
    beginShape();
    vertex(0,height);
    for (var i=0; i<(width/5)+1; i+=1) {
        vertex(i*5,sandy[i]);
    }
    vertex(width,height);
    endShape();
    pop();
}

//coral reef has got to have coral
function coral() {
    //tube coral
    if (f.length<1 & timer>70) {
        fill(gray1);
        stroke(gray1);
    } else {
        fill(tube1);
        stroke(tube1);
    }
    strokeWeight(8);
    var place = 500; //easier to adjust coral placement
    quad(place,200,place+20,200,place+30,70,place,70);
    quad(place-30,210,place,210,place-10,100,place-30,100);
    quad(place-60,190,place-40,190,place-30,50,place-70,40);
    quad(place-90,200,place-60,200,place-70,130,place-80,130);
    if (f.length<1 & timer>20) {
        fill(gray1);
        stroke(gray1);
    } else {
        fill(tube2);
        stroke(tube2);
    }
    place = 150;
    quad(place-30,250,place-50,250,place-50,120,place-20,120);
    quad(place+30,260,place,260,place+10,150,place+30,150);
    quad(place+60,240,place+40,240,place+30,100,place+70,90);
    quad(place-90,250,place-60,250,place-70,180,place-80,180);

    //brain coral
    if (f.length<1 & timer>10) {
        fill(gray2);
        stroke(gray2);
    } else {
        fill(brain1);
        stroke(brain1);
    }
    ellipse(400,200,100,70);
    if (f.length<1 & timer>50) {
        fill(gray2);
        stroke(gray2);
    } else {
        fill(brain2);
        stroke(brain2);
    }
    ellipse(10,150,100,70);

    //another tube coral
    if (f.length<1 & timer>30) {
        fill(gray1);
        stroke(gray1);
    } else {
        fill(tube3);
        stroke(tube3);
    }
    place = 300;
    quad(place+30,340,place,360,place+10,200,place+30,190);
    quad(place+60,360,place+40,360,place+30,250,place+70,250);
}

//makes the cursor look a certain way
function fishHook(x,y) {
    noFill();
    stroke(255);
    strokeWeight(10);
    beginShape();
    vertex(x+40,y-50);
    vertex(x+40,y-50);
    vertex(x+40,y);
    curveVertex(x+20,y+10);
    curveVertex(x,y);
    vertex(x,y);
    endShape();
    fill(80);
    triangle(x-5,y+10,x+10,y-10,x-5,y-10);
}

//underwater has to have seaweed
function seaweed(x,height) {
    strokeWeight(5);
    stroke(0,122,4); //green
    fill(0,122,4); //still green
    triangle(x,350,x+20,350,x+10,height);
}

function mousePressed() {
    for (var i=0; i<f.length; i+=1) {
        if (dist(mouseX,mouseY, f[i].x,f[i].y)<30) {
            f.splice(i,1);
            fill(0,122,4,100); //green
            rect(width/2,height/2,600,300);
            moneyCount+=10000;
            break;
        }
    }
}

Final Project

In my final project, the user starts at the year 1900 where there’s only fish in the ocean happily floating around and the thermometer on the left is quite low. As the reader reads the message on the top of the screen, they click the mouse and the year changes to 1940 where there is now oil barrels floating in the ocean. This addition of similar pollutants (oil barrels, plastic water bottles, face masks, and plastic bags) continues one by one as the user continues clicking the mouse. In the final click, year 2100, the user ends up killing the earth.

To do this project, I did some research onto the type of ocean pollutants that become more and more common as time passes. For example, in 2020, my animation spawns face masks in the ocean, which is a reflection of what truly happened in the real world due to COVID-19. The expectation from the user is quite straightforward as they just have to click their mouse and the animation progresses.

I think if I had more time, I would have changed more elements like the number of fish in the ocean, the color of the ocean gets dirtier, and the fish would have had expressions that go from happy to sad. Although I was unable to add these features, I am quite satisfied with how my project turned out.

Download

// Yash Mittal
// Section D 
// Final Project 

var waveValue = []; //array for front wave
var waveValue2 = []; //array for back wave
var noiseParam = 0.0001;
var noiseParam2 = 0.0001;
var noiseStep = 0.01;
var noiseStep2 = 0.01;
var x = []; //x value of fish
var y = []; //y value of fish
var dx = []; //x direction of fish
var c = []; //color for fish
var count = 0; //variable to keep track of user mousePressed
var clouds = 'https://i.imgur.com/RLqcPK7.png' //cloud image
var cloudsX = 0; //x value for 1st cloud
var cloudsX1 = -160; //x value for 2nd cloud
var cloudsDx = 2; //x direction speed for 1st cloud
var cloudsDx1 = 1; //x direction speed for 2nd cloud
var oilBarrel = 'https://i.imgur.com/nHrLCul.png' //oil barrel image
var numBarrels = 5; //number of barrels that spawn
var oilBarrelList = []; //array for barrels
var waterBottles = 'https://i.imgur.com/Xxl9tDk.png' //water bottle image
var numBottles = 10; //number of plastic water bottles that spawn
var waterBottlesList = []; //array for bottles
var faceMasks = 'https://i.imgur.com/wgsNqdq.png' //face mask image
var numMasks = 10; //number of face masks that spawn
var faceMasksList = []; //array for face masks
var plasticBag = "https://i.imgur.com/L8v1yKk.png" //plastic bag image
var numBags = 10; //number of plastic bags that spawn
var plasticBagList = []; //number of plastic bags that spawn
var sun = 'https://i.imgur.com/ftQzVK5.png'; //sun image
var angle_sun = 0; //rotation angle variable for sun
var thermometer = 'https://i.imgur.com/zcV3Srl.png'; //thermometer image
var deadEarth = 'https://i.imgur.com/tAGCTqA.png'; //dead earth image

function preload() {

    pimg = loadImage (clouds);
    oilImage = loadImage (oilBarrel);
    bottleImage = loadImage (waterBottles);
    maskImage = loadImage (faceMasks);
    plasticImage = loadImage (plasticBag);
    sunImage = loadImage (sun);
    thermoImage = loadImage (thermometer);
    earthImage = loadImage (deadEarth);

}

function setup () {

    createCanvas (600, 400);
    frameRate (15); 

    makeOil();

    makeBottle();

    makeMask();

    makeBag();

    for (var i = 0; i < 50; i ++) { //loop for fish value

        x [i] = random (25, width - 25);
        dx [i] = random (-5, 5);
        c [i] = color (random (0, 130), random (0, 130), random (0,130));
    }
}

function draw () {

    background (220);

    sunRotate(); //rotating circle

    cloudsP (); //drawing clouds

    timelineBar ();

    drawWaves1 ();

    for (i = 0; i < 20; i = i + 1) { //loop for fish value

        fill (c[i]);
        fish (x [i], waveValue [i] + 110, dx [i]); //making y value same as waveValue [i]
        x [i] = x [i] + dx [i];
        if (x [i] >= width - 25 || x [i] < 25 ) {
            dx [i] = - dx [i];

        }
   }

    highlightRect ();

    if (count >= 1) {

        for (var i = 0; i < numBarrels; i++) {
            updateOil(i); //moves oil barrels
            showOil (); //displays oil barrels
        }

        fill ("red");
        rect (17, 194, 8, 6); //increasing avg temp
    }

    if (count >=2) {

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

            updateBottle (i);
            showBottle ();
        }

        rect (17, 185, 8, 13); //increasing avg temp
     }

     if (count >=3) {

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

            updateMask (i);
            showMask ();
        }

        rect (17, 168, 8, 17); //increasing avg temp
     }

     if (count >=4) {

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

            updateBag (i);
            showBag ();
        }

        rect (17, 155, 8, 20); //increasing avg temp
     }

    image(thermoImage, 10, 140, 30, 80);

    drawWaves2 ();

    if (count >=5) {

        fill (0);
        rect (0, 0, width, height);
        image (earthImage, width / 2 - 240, height / 2 - 150, 250, 250);
        textSize(15);
        fill (255);
        text ("Congratulations, you killed the earth!", 330, 200);
     }  
}

function sunRotate () {

    push();
    rotate (radians(angle_sun));
    imageMode (CENTER);
    image (sunImage, 0, 0, 170, 170);
    pop();
    angle_sun = angle_sun + 2; //iterating angle for sun
}

function makeBag () {

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

        tx = random (10, width - 10); //random x value for bags
        ty = 0; //unassigned y value
        plasticBagList.push ({x:tx, y:ty, show:bagDraw, move: bagMove}); //create object & pushing in array
    }
}

function updateBag (i) { //function that holds y value of bottle and move function

    plasticBagList [i].y = waveValue[i] + 120; 
    plasticBagList [i].move ();
}

function showBag () { //function to display mask

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

        plasticBagList [i].show ();
    }
}

function bagDraw() {

    image (plasticImage, this.x, this.y, 35, 35); //calling image

}

function bagMove () {

    this.x = this.x - random (0, 3);

    if (this.x < -25) { //if bags exits canvas from left, it appears on right

        this.x = width + 20;
    }
}

function makeMask () {

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

        tx = random (10, width - 10); //random x value for masks
        ty = 0; //unassigned y value
        faceMasksList.push ({x:tx, y:ty, show: maskDraw, move: maskMove}); //creating object & pushing in array 
    }
}

function updateMask (i) { //function that holds y value of bottle and move function

    faceMasksList [i].y = waveValue[i] + 100;
    faceMasksList [i].move ();
}

function showMask () { //function to display mask

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

        faceMasksList [i].show ();
    }
}

function maskDraw () {

    image (maskImage, this.x, this.y, 30, 30); //calling image
}

function maskMove () {

    this.x = this.x - random (0, 2);

    if (this.x < -25) { //if masks exits canvas from left, it appears on right

        this.x = width + 20;
    }
}

function makeBottle () {

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

        tx = random (25, width - 25); //random x value for bottles
        ty = 0; //unassigned y value
        waterBottlesList.push ({x:tx, y:ty, show: bottleDraw, move: bottleMove});//creating object & pushing in array
    }
}

function updateBottle (i) { //function that holds y value of bottle and move function

    waterBottlesList [i].y = waveValue[i] + 90;
    waterBottlesList [i].move ();
}

function showBottle () { //function to display bottles

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

        waterBottlesList [i].show ();
    }
}

function bottleDraw () {

    image (bottleImage, this.x, this.y, 30, 30); //calling the image
}

function bottleMove () {

    this.x = this.x + random (0, 2);

    if (this.x > width) { //if bottles exits canvas from right, it appears on left

        this. x = -20; 
    } 
}

function makeOil () {

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

        tx = random (25, width - 25); //random x value for barrels
        ty = 0; //unassigned y value
        oilBarrelList.push({x:tx, y:ty, show: oilDraw, move: oilMove}); //creating object & pushing in array 
    }
}

function updateOil (i) { //function that holds y value of barrel and move function

    oilBarrelList [i].y = waveValue [i] + 100; //assigning waveValue to y value 
    oilBarrelList [i].move (); //move function
}

function showOil () { //function to display oil

    for (var i = 0; i < 5; i++) { //for loop to display barrels
        oilBarrelList [i].show();
    }
}

function oilDraw (){

        image(oilImage, this.x, this.y, 35, 58); //drawing oil
}

function oilMove () { //function iterating x value of each barrel

        this.x = this.x - random (0, 2);

        if (this.x < -40) {

            this.x = 600
        } 
}

function mousePressed () {

         count = count + 1; //count increases each time mouse is pressed
    }

function cloudsP () {

    image (pimg, cloudsX, 50, 160, 160);
    image (pimg, cloudsX1, 20, 150, 150);

    cloudsX = cloudsX + cloudsDx;
    cloudsX1 = cloudsX1 + cloudsDx1;

    if (cloudsX >= width) {

        cloudsX = -160;
    }

    if (cloudsX1 >= width) {

        cloudsX1 = -160;
    }
}

function fish (x, y, dx) { //fish function

    fill (c);
    ellipse (x, y, 20, 10);

    if (dx < 0) { //if fish is going left

        triangle (x + 10, y, x + 15, y + 5, x + 15, y - 5);

    } else if (dx >= 0) { //if fish is going right

        triangle (x - 10, y, x - 15, y + 5, x - 15, y - 5);

    }
}

function highlightRect () {

    if (count == 0) { 

        fill ("green");
        rect (85, 57, 20, 40); //1900

    }  

    if (count == 1) {

        fill("green");
        rect (165, 57, 20, 40); //1940

    }  

    if (count == 2) {

        fill ("green");
        rect (245, 57, 20, 40); //1980
    }

    if (count == 3) {

        fill ("green");
        rect (325, 57, 20, 40); //2020
    }

    if (count == 4) {

        fill ("green");
        rect (405, 57, 20, 40); //2060
    }

    if (count == 5) {

        fill ("green");
        rect (485, 57, 20, 40); //2100
    }

    print(count);
}

function drawWaves1 () { // water wave 1 function

    for (var i = 0; i < width / 5 + 1; i++) {

        var n = (noise(noiseParam));

        var value = map (n, 0, 1, 80, height);

        waveValue.push(value); 

        noiseParam = noiseParam + noiseStep;
    }

    beginShape (); // drawing randomised wave

    vertex (0, height); // point 1 

    for (var i = 0; i <= width / 5; i++) { // point 2 random

        fill (116, 205, 235, 200); //water with alpha value
        noStroke();

        vertex (i * 5, waveValue [i] + 80); // randomised wave

    }

        waveValue.shift (); // making wave move by removing first element
        waveValue.push (map (noise (noiseParam), 0, 1, 80, height)); // adding random array value
        noiseParam = noiseParam + noiseStep;

        vertex (width, height); // point 3

        endShape (CLOSE);

    }

function drawWaves2 () { // water wave 2 function

        for (var i = 0; i < width / 5 + 1; i++) {

        var n1 = (noise(noiseParam2));

        var value2 = map (n1, 0, 1, 40, height);

        waveValue2.push(value2); 

        noiseParam2 = noiseParam2 + noiseStep2;
    }

    beginShape (); // drawing randomised wave

    vertex (0, height); // point 1 

    for (var i = 0; i <= width / 5; i++) { // point 2 random

        fill (116, 205, 235, 90); //water with alpha value
        noStroke();

        vertex (i * 5, waveValue2 [i] + 40); // randomised wave 2

    }

        waveValue2.shift (); // making wave move by removing first element
        waveValue2.push (map (noise (noiseParam), 0, 1, 40, height)); // adding random array value
        noiseParam2 = noiseParam2 + noiseStep2;

        vertex (width, height); // point 3

        endShape (CLOSE);

    }

function timelineBar () { //timeline function

        stroke (0);
        strokeWeight(5);
        line (20, 40, 20, 70); //left line
        line (20, 55, 580, 55); //middle line
        line (580, 40, 580, 70); //right line

        for (var a = 0; a < 6; a++) { // for loop for date rectangles 

            noFill();
            strokeWeight(1);
            rect (a * 80 + 85, 57, 20, 40);
        }

        textSize (30);
        fill (0);
        text ("Click mouse to time travel", 120, 40);

        textSize (15);
        text ("1900", 78, 115);
        text ("1940", 158, 115);
        text ("1980", 238, 115);
        text ("2020", 318, 115);
        text ("2060", 398, 115);
        text ("2100", 478, 115);

    }

Final Project – Air Pollution

his project relies on a particle system. It indicated regions with air pollution on an abstract Indian map. Hovering above the regions with your maps will lead to an info box appearing. The more red the region, the worse it is in terms of the air pollution.

class=”p5-embed” href=”https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/12/sketch-9.js”>sketch Karan Shah