Julia Nishizaki – Final Project

sketch

//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Final Project - ABCs of Climate Change


//variables for climate change effects, uses true/false statements to make effects appear/disappear
var cE = {
    lakeColor: false, //algae blooms
    flowers: false, //biodiversity
    clouds: false, //carbon footprint
    trees: true, //deforestation
    gas: false, //greenhouse gases
    mtn: false, //hazardous waste
    hill: false, //invasive species
    jeopardy: false, //jeopardy
    house: false, //population growth
    sky: false, //smog
    field: false, //toxic pollutants
    building: false, //urban sprawl
    lake: false, //water levels
    deadz: false, //zones that are dead
}

//variables to help with effects of climate change
var lakeWidth = 200; //initial width of lake
var lakeHeight = 35; //height of lake
var skyHeight = 0; //height of sky for smog
var cloudX = 475; //starting x position for cloud
var gasX = 475; //starting x position for gas cloud
var jtranslu = 0; //starting opacity for "smoke screen", jeopardy

//variables for the window and its dimensions
var win = {
    ws: 125, //distance from window to right and left sides of canvas
    wt: 40, //distance from window to top of canvas
    wb: 160, //distance from window to bottom of canvas
    frm: 5, //width of window frame
    dis: 5, //displacement outside of canvas
}

//variables for colors used throughout, especially for objects that change color
var colors = {
    hill: 80, //light green hill (HSB)
    mtnb: 70, //purple mountains (HSB)
    sky: '#8ED9EF', //light blue of sky
    smogop: 80, //opacity of smog in background
    field: 'green', //green
    lakeh: 55, //hue value of lake (HSB)
    lakes: 50, //saturation value of lake (HSB)
    lakeb: 100, //brightness value of lake (HSB)
    fieldb: 60, //brightness value of field (HSB)
    wall: 230, //light gray of walls
    table: 150, //dark gray of table 
    flower: 'purple', //purple flowers
    plnflw: 'green', //green flowers
    type: '#8BC63F', //light green of type
}

//arrays that store letters and each letter's climate change info
var alphabetLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
var letterInfo = [ //stores copy on climate change ABCs
    "Algae Blooms: toxic algae can poison water and create dead zones", 
    "Biodiversity: the variety of life on the planet", 
    "Carbon Footprint: the amount of carbon dioxide each of us produces", 
    "Deforestation: the reduction of trees due to natural forces or human activity", 
    "Extinctions: the death of all individuals of a species", 
    "Fossil Fuels: nonrenewable fuels that are burned for energy like coal and gas", 
    "Greenhouse Gases: gases like methane, trap heat and warm the atmosphere", 
    "Hazardous Waste: waste that pose a risk to human health and the environment", 
    "Invasive Species: any organism not native to an ecosystem that causes harm", 
    "Jeopardy: danger of loss, harm, or failure", 
    "Keystone Species: a species that is critical to the survival of other species", 
    "Landfill: a site where wastes are dumped for permanent disposal", 
    "Microplastics: very small pieces of plastic that pollute the environment", 
    "Nonrenewable: resources that can't be replenished onced used", 
    "Ozone Layer: a thin protective layer of gas above Earth that filters UV radiation", 
    "Population Growth: an increase in the total human population", 
    "Quotas Insufficient: limits and restrictions in environmental policies not met", 
    "Runoff: stormwater from cities or farms that carry pollutants into water systems", 
    "Smog: dust, smoke, or chemical fumes that pollute the air", 
    "Toxic Pollutants: contaminate areas and cause death, disease, or birth defects", 
    "Urban Sprawl: expansion of auto-dependent developments over large areas of land", 
    "Vulnerability: susceptibility to harm from exposure to stresses", 
    "Water Level Rise: rising sea levels due to global warming and melting glaciers", 
    "Xenobiotic: non-natural or man-made substances found in the environment", 
    "Yield: amount of crops produced per unit area", 
    "Zones that are Dead: dead zones are caused by hypoxia, or lack of oxygen in water",
    ];

function setup() {
    createCanvas(600, 480);
    frameRate(30);   
}

function draw() {
    background(colors.sky); //sets the background as a light blue
    
    prepEnvironEffects(); //connects each key to a variable

    drawLandscape(); //creates all elements of the landscape 
    drawRoom(); //creates all elements of the room
    
    typedLetterAlphabet(); //displays the alphabet
    typedLetterInfo(); //displays the words and definitions
}

function prepEnvironEffects() {//when a particular key is pressed, the variable associated with that key switches from false to true
    if (key == 'a') { //algae blooms
            cE.lakeColor = true;
        } 
    if (key == 'b') { //biodiversity
            cE.flowers = true;
        }
    if (key == 'c') { //carbon footprint
            cE.clouds = true;
        } 
    if (key == 'd') { //deforestation
            cE.trees = false;
        } 
    if (key == 'g') { //greenhouse gases
            cE.gas = true;
        } 
    if (key == 'h') { //hazardous waste
            cE.mtn = true;
        } 
    if (key == 'i') { //invasive species
            cE.hill = true;
        } 
    if (key == 'j') { //jeopardy
            cE.jeopardy = true;
        } 
    if (key == 'p') { //population growth
            cE.house = true;
        } 
    if (key == 's') { //smog
            cE.sky = true;
        } 
    if (key == 't') { //toxic pollutants
            cE.field = true;
        } 
    if (key == 'u') { //urban sprawl
            cE.building = true;
        } 
    if (key == 'w') { //water level rise
            cE.lake = true;
        } 
    if (key == 'z') { //zones that are dead
            cE.deadz = true;
    }
}

//Creates elements in the landscape, and calls for changes to those elements
function drawLandscape() {
    makeClouds(); //creates clouds for carbon footprint and greenhouse gas, letters c and g
    changeSky(); //creates smog screen in background, letter s
    changeMtnHill(); //changes color of mountains and hills, letters h and i

    var landscapeScale1 = 0.004; //detail in hills
    var landscapeScale2 = 0.018; //detail in mountains

    //creates mountains in the background
    colorMode(HSB, 100);
    stroke(70, 30, colors.mtnb);
    strokeWeight(1);
    for (var x = 0; x < width; x ++) {
        var l = (x * landscapeScale2);
        var y = map(noise(l), 0, 1, height * 0.2, height * 0.5); //constrains hills
        line(x, y, x, height); //creates vertical lines, forming a solid shape
    }

    colorMode(RGB);
    makeBuilding(); //creates buildings when letter u is pressed

    //creates hills in the middleground
    colorMode(HSB, 100); //switches color mode to HSB to help with color changes
    stroke(25, 50, colors.hill);
    for (var x = 0; x < width; x ++) {
        var l = (x * landscapeScale1);
        var y = map(noise(l), 0, 1, height * 0.4, height * 0.6); //constrains hills
        line(x, y, x, height); //creates vertical lines, forming a solid shape
    }

    //creates field in foreground
    noStroke();
    fill(28, 100, colors.fieldb); //field color
    rect(0, height * 0.55, width, height * 0.35);
    changeField(); //changes color of field, letter t
    
    //creates lake
    fill(colors.lakeh, colors.lakes, colors.lakeb);
    ellipse(175, 286, lakeWidth, lakeHeight);
    changeLake(); //changes color and size of lake, letters a, w, and z

    colorMode(RGB); //switches color mode back to RGB
    makeFlowers(); //makes flowers, alternating colors, becomes one color with letter b
    makeHouse(); //makes houses, letter p
    makeTrees(); //makes single yellow tree in foreground, tree disappears with letter d 
    smokeScreen(); //creates a semi-transparent grey layer with letter j
}

//makes and moves the clouds
function makeClouds() {
    if (cE.clouds == true) { //makes a cloud for carbon footprint, letter c
        drawClouds(cloudX, 120, 150, 50, 150);
        cloudX = cloudX - 2;
        if (cloudX < win.ws - 150) {
            cloudX = 475;
        }
    }
    if (cE.gas == true) { //makes a cloud for greenhouse gases, letter g
        drawClouds(gasX, 180, 220, 75, 100);
        gasX = gasX - 1;
        if (gasX < win.ws - 220) {
            gasX = 475;
        }
    }
}

//draws the clouds
function drawClouds(locationX, locationY, width, height, color) {
    push();
    fill(color);
    translate(locationX, locationY);
    rect(0, - height, width, height, 50, 50, 50, 50);
    pop();
}

//adds "smog" in background
function changeSky() {
    if (cE.sky == true) {
        fill(80, colors.smogop);
        noStroke();
        rect(0, height * 0.55 - skyHeight, width, skyHeight);
        skyHeight = constrain(skyHeight, 0, 300) + 3;
    }
}

//changes colors of mountains and hills
function changeMtnHill() {
    if (cE.mtn == true) { //changes mountain colors
        colors.mtnb = constrain(colors.mtnb, 20, 70) - 5;
    }
    if (cE.hill == true) { //changes hill colors
        colors.hill = constrain(colors.hill, 30, 80) - 5;
    }
}

//makes the buildings for urban sprawl
function makeBuilding() {
    if (cE.building == true) { //from left to right
        drawBuildings(125, 37, 130, 180);
        drawBuildings(162, 62, 110, 150);
        drawBuildings(224, 50, 120, 200);
        drawBuildings(274, 37, 100, 130);
    }
}

//draws buildings
function drawBuildings(locationX, buildW, buildH, color) {
    push();
    noStroke();
    fill(color);
    translate(locationX, height * 0.58);
    rect(0, - buildH, buildW, buildH);
    //windows in buildings
    fill(255);
    for (var x = 0; x < (buildW / 6) - 1; x ++) {
        for (var y = 0; y < 200; y ++) {
            rect(2 + x * 6, - buildH + 4 + y * 8, 3, 4);
        }
    }
    pop();
}

//changes lake size and color
function changeLake() {
    if (cE.lake == true) { //makes larger for water level
        lakeWidth = constrain(lakeWidth, 200, 350) + 5;
    }
    if (cE.lakeColor == true) { // becomes green for algae
        colors.lakeh = constrain(colors.lakeh, 30, 55) - 0.75;
    }
    if (cE.deadz == true) { //becomes dark for dead zones
        colors.lakes = constrain(colors.lakes, 50, 100) + 5;
        colors.lakeb = constrain(colors.lakeb, 35, 100) - 5;
    }
}

//changes color of field
function changeField() { 
    if (cE.field == true) {
        colors.fieldb = constrain(colors.fieldb, 20, 60) - 2;
    }
}

//makes row of flowers at base of hills
function makeFlowers() {
    for (var i = 0; i < 20; i ++) {
        strokeWeight(2);
        for (var g = 0; g < 6; g ++) {
            if (i % 2) { //alternates colors of flowers to represent biodiversity
                stroke(colors.plnflw);
                push();
                translate(win.ws + i * 25, height * 0.55);
                rotate(g * 60);
                line(0, 0, 0, 3);
                pop();   
            } else {
                stroke(colors.flower);
                push();
                translate(win.ws + i * 25, height * 0.55);
                rotate(g * 60);
                line(0, 0, 0, 3);
                pop();   
            }
        }
    }
    if (cE.flowers == true) { //changes color of flowers to single color, removal of biodiversity
        colors.flower = colors.plnflw; 
    }
}

//makes houses for population growth
function makeHouse() {
    if (cE.house == true) {
        drawHouses(320, height * 0.58, '#FCAD77', '#E8762A', 0.9); //left
        drawHouses(375, height * 0.57,'#7BE0FF', '#1CB8E8', 0.8); //right
        drawHouses(350, height * 0.59,'#B09DCC', '#9274C1', 1.0); //middle
    }
}

//draws houses
function drawHouses(locationX, locationY, colorHouse, colorDoor, houseScale) {
    push();
    noStroke();
    fill(colorHouse);
    translate(locationX, locationY);
    scale(houseScale);
    rect(0, -20, 40, 20);
    fill('white');
    triangle(-5, -20, 45, -20, 20, -30);
    rect(24, -15, 10, 10);
    fill(colorDoor);
    rect(8, -15, 8, 15);
    pop();   
}

//makes tree in foreground of landscape
function makeTrees() {
    if (cE.trees == true) { //the tree disapears when key is pressed, as key switches variable to false
        push();
        rectMode(CENTER);
        translate(440, 110);
        noStroke();
        fill(249, 176, 30); //yellow of tree
        rect(0, 0, 130, 200, 40, 40, 40, 40);
        //tree branches
        strokeWeight(15);
        stroke(124, 20, 22);
        line(0, -50, 0, 225);
        strokeWeight(10); //thinner branches
        line(0, 80, 40, 40);
        line(0, 20, -40, -20);
        pop();
    }  
}

function smokeScreen() { //creates grey screen
    if (cE.jeopardy == true) {
        noStroke();
        jtranslu = constrain(jtranslu, 0, 80) + 15;
        fill(150, jtranslu);
        rect(win.ws, win.wt, 350, 300)
    }
}

//creates all aspects of the room - window, window frame, walls, table, poster, instructions
function drawRoom() { 
    rectMode(CORNER);
    noStroke();
    
    //walls of the room
    fill(colors.wall);
    rect(-win.dis, -win.dis, win.ws + win.dis, height + win.dis * 2);
    rect(width - win.ws, -win.dis, win.ws + win.dis, height + win.dis * 2);
    rect(0, height - win.wb, width, win.wb);
    rect(0, 0, width, win.wt);
    
    //gray "table" below window where alphabet and definitions appear
    fill(colors.table); //medium gray
    rect(0, height - 130, width, 130);

    //white lines that divide window
    stroke(255);
    strokeWeight(4);
    line(width / 2, win.wt - win.frm, width / 2, height - win.wb + win.frm);
    line(win.ws - win.frm, (height - win.wb) / 2 + win.wt / 2, width - win.ws + win.frm, (height - win.wb) / 2 + win.wt / 2);
    //white border around the window
    strokeWeight(10);
    line(win.ws - win.frm, win.wt - win.frm, win.ws - win.frm, height - win.wb + win.frm);
    line(width - win.ws + win.frm, win.wt - win.frm, width - win.ws + win.frm, height - win.wb + win.frm);
    line(win.ws - win.frm, win.wt - win.frm, width - win.ws + win.frm, win.wt - win.frm);
    line(win.ws - win.frm, height - win.wb + win.frm, width - win.ws + win.frm, height - win.wb + win.frm);

    drawPoster(); //draws the poster to the left of window
    drawInstructions(); //draws instructions on the gray "table"
}

function drawPoster() { //creates poster telling you to refresh
    push();
    noStroke();
    rectMode(CENTER);
    angleMode(DEGREES);
    textAlign(CENTER);
    fill(255);
    translate(60, 165);
    rotate(-3); //rotates poster slightly
    rect(0, 0, 75, 100);
    //pin at the top of the poster
    fill(colors.table); 
    ellipse(0, -40, 5, 5);
    //writing in gray telling you to refresh
    textSize(12);
    textLeading(15); //sets leading
    var poster = "Refresh\npage\nto\nrestart"; //puts each word on a new line
    text(poster, 0, -17);
    pop();
}

function drawInstructions() { //creates instructions
    textAlign(CENTER);
    noStroke();
    fill(255);
    var textLocation = 375;
    textSize(12);
    text("Press and hold down keys to see some ABCs of climate change", width / 2, textLocation);
}

//creates alphabet
function typedLetterAlphabet() {
    for (var i = 0; i < 26; i ++) {
        textAlign(CENTER);
        textSize(20);
        noStroke();
        var alphabetLocation = 400;
        var x = map(i, 0, alphabetLetters.length, 50, width - 30);
        if (keyCode === 65 + i) { //when key is down, letter turns grey
            fill(100);
            text(alphabetLetters[i], x, alphabetLocation);
        } else { //all letters green when not pressed
            fill(colors.type);
            text(alphabetLetters[i], x, alphabetLocation);
        } 
    }
}

//creates climate change info
function typedLetterInfo() {
    textAlign(CENTER);
    textSize(15);
    fill(255);
    for (var i = 0; i < 26; i ++) {
        if (keyCode === 65 + i) {
            text(letterInfo[i], width / 2, height - 45);  
        } 
    }   
}

//when key released, already pressed letters disapear
function keyReleased() { //replaces already clicked letters and their info with spaces in the respective arrays
    for (var i = 0; i < 26; i ++) {
        if (keyCode == 65 + i) {
            alphabetLetters.splice(i, 1, " ");
            letterInfo.splice(i, 1, " ");
        }       
    }
}

For this project, I initially wanted to use sound and the typing keyboard in order to create an instrument out of sounds related to the environmental crisis. However, I decided to instead pivot towards creating an interactive and visual display of some “ABCs” of climate change. When you type and hold down a key, a word that starts with that letter will appear, along with that word’s definition. For a little less than half of the letters in the alphabet, something related to the word will happen on the landscape that is visible outside of the window. I wanted to keep the interactions fairly simple, while still conveying some of the effects of climate change, global warming, and our actions as a society.

Leave a Reply