{"id":76227,"date":"2022-12-10T19:37:43","date_gmt":"2022-12-11T00:37:43","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/?p=76227"},"modified":"2022-12-10T19:37:43","modified_gmt":"2022-12-11T00:37:43","slug":"dam-it","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/2022\/12\/10\/dam-it\/","title":{"rendered":"dam it!"},"content":{"rendered":"<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<html><body><p>This project is inspired by the tensions between dams, the environment, and people displaced or otherwise affected by dams.<\/p>\n\n\n\n<p>In this animation, you become the dam builder. By pressing the mouse anywhere on the canvas, a dam emerges in the river, affecting the water level, marine life (fish and plants), and nearby communities (houses). Moving the mouse from left to right raises the dam and increases its impact, killing fish and making houses disappear. Pressing the space bar replenishes the fish population. Clicking the mouse advances to different facts about dams, stored in an array. These facts are adapted from research summarized by Earth Law Center and HuffPost.<\/p>\n\n\n\n<div><a class=\"p5_sketch_link\" href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-content\/uploads\/2022\/12\/sketch-4.js\" data-width=\"480\" data-height=\"360\">sketch<\/a><iframe src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-content\/plugins\/p5-embedder\/p5_iframe.html\" class=\"p5_exampleFrame\" width=\"480\" height=\"360\"><\/iframe><pre class=\"language-javascript\"><code class=\"p5_editor language-javascript\">\/* jaden luscher\njluscher\nsection a\ndammit(!): an educational animation *\/\n\nvar waterlevel1; \/\/ water level left of dam (upstream)\nvar waterlevel2; \/\/ water level right of dam (downstream)\nvar damX = 100;\t\/\/ x location of dam\n\nvar fish = [];\nvar numFish = 40;\n\nvar house = []; \/\/ original array of houses\nvar newhouseProbability = 0.03; \/\/ likelihood of a new house popping up\n\nvar plants = [];\nvar plantNum = 100;\n\nvar sceneNum = 0;   \/\/ main reference for changing objects\nvar factNum = 0;    \/\/ determines index of damFacts array\nvar damFacts = ['what a beautiful ecosystem... click to screw it up!',\n    'great. you built a dam. the river&rsquo;s flow is restricted. click to learn more.',\n    'the united states has over 9,000 dams...',\n    '...many are not equipped to handle the amount of water that could result from climate change.',\n    'pennsylvania has 145 high hazard dams in poor or unsatisfactory condition.',\n    'dams have fragmented two thirds of the worlds large rivers...',\n    '...and have flooded a land area the size of california.',\n    'their reservoirs contain three times as much water as all the world&rsquo;s rivers, and speed up evaporation.',\n    'dams disrupt fish and bird migration, both physically and chemically...',\n    '...and habitat loss is the leading cause of extinction.',\n    'upstream: nutrients trapped in reservoirs can cause toxic algae blooms.',\n    'downstream: ecosystems suffer from a lack of sedimentation and nutrients.',\n    'less nutrients = less vegetation = more erosion',\n    'river deltas are deprived of the silt they need to defend against damage from the ocean.',\n    'removing damaged and aging dams protects the surrounding population from disaster...',\n    '...and allows the rivers to restore their natural and biological integrity.',\n    'but often what happens instead is...'\n    ];\n\nfunction setup() {\n    createCanvas(480, 360);\n\tnoStroke();\n\tframeRate(20);\n    angleMode(DEGREES);\n    textFont(\"monospace\");\n    textSize(12);\n    if (sceneNum == 0) {\n        waterlevel1 = 240;\n        waterlevel2 = 240;\n    }\n    for(var i = 0; i &lt; numFish; i++) {\n        var newFish = makeFish();\n        fish.push(newFish);\n    }\n    \/\/ first house\n    for(var i = 0; i &lt; 10; i++) {\n        var firstHouses = makehouse(random(width), 180);\n        house.push(firstHouses);\n    }\n    for (var i = 0; i &lt; plantNum; i++) {\n        var newPlant = makePlant();\n        plants.push(newPlant);\n    }\n}\n\nfunction draw() {\n    drawSky();\n    if (sceneNum &gt; 0) {     \/\/ only occurs once mouse has been pressed\n        sceneNum = constrain(floor(map(mouseX, width\/2, width, 1, 12)), 1, 12);\n        waterlevel1 = 240 - sceneNum * 6;\n        waterlevel2 = 240 + sceneNum * 9;\n    }\n    drawMountain(0, 0.02, 0.00004, 50, 220);   \/\/ background mountains    \n    drawMountain(1, 0.01, 0.00007, 50, 220);   \/\/ midground mountains\n    drawMountainAndHouses(0.005, 0.0001, 40, 220); \/\/ foreground mountains and houses\n\n    for (var i = 0; i &lt; house.length; i++) {\n        house[i].move();\n        house[i].show();  \n    }\n    var keepHouses = []; \/\/ stores houses in range\n    \/\/ keep houses still in range \n    if (house.length &gt; 0) {\n        for (var i = 0; i &lt; house.length; i++) {\n            if (house[i].houseExists & house[i].x + house[i].w > 0) {\n                keepHouses.push(house[i]);\n            }\n        }\n    }\n    house = keepHouses; \/\/ thank you Chuong!\n    water();\n    push();\n    for (var i = 0; i &lt; plantNum; i++) {\n        if (plants[i].plantExists) {\n            plants[i].show();\n            translate(width \/ plantNum, 0);\n        }\n    }\n    pop();\n    \/\/ draw fish\n    for (var i = 0; i &lt; numFish; i++) {\n        if (fish[i].fishExists) {\n            fish[i].move();                \n            fish[i].show();\n        }\n    }\n    makeDam();\n    spitfacts(factNum);\n    if(factNum &gt; damFacts.length - 1) {\n        gameOver();\n    }\n}\n\nfunction mousePressed() {\n    sceneNum = 1;\n    factNum ++;\n}\n\nfunction keyPressed() {\n    if(key == ' ') {\n        sceneNum = 0;\n        waterlevel1 = 240;\n        waterlevel2 = 240;\n        fish = [];  \/\/ clear fish array\n        for(var i = 0; i &lt; numFish; i++) {\n            var newFish = makeFish();\n            fish.push(newFish);\n        }\n    }\n}\n\nfunction gameOver() {\n    background(\"orange\");\n    fill(255);\n    textSize(32);\n    text('DAMMIT!', 170, 180);\n    textSize(14);\n    textAlign(CENTER);\n    text('(YOU KILLED ALL THE FISH AND HAVE CAUSED SEVERE DAMAGE TO THE ECOSYSTEM)',\n            40, 250, 400)\n    noLoop();\n}\n\nfunction drawSky() {\n    background(\"orange\");\n    push();\n    fill(\"yellow\");\n    translate(400, 80);\n    scale(map(mouseY, 0, height, 0.5, 1));\n    ellipse(0, 0, 50, 50);\n    pop();\n}\n\nfunction spitfacts(f) {\n    push();\n    fill(255);\n    text(damFacts[f], 30, 30, 220, 80);\n    pop();\n}\n\nfunction drawMountain(mc, a, speed, high, low) {\n    noStroke();\n    if(mc == 0) fill(240, 150, 120);    \/\/ background mountain color\n    if(mc == 1) fill(220, 130, 100);    \/\/ midground mountain color\n    if(mc == 2) fill(20, 50, 180);      \/\/ water color\n    beginShape();\n    vertex(width, height);\n    vertex(0, height);\n    for(var i = 0; i &lt; width + 1; i ++){\n        var x = (i * a) + (millis() * speed);\n        var y = map(noise(x + mc*1000), 0, 1, high, low); \n        \/\/ x + mx*100 ensures mountains look different\n        vertex(i, y);\n    }\n    endShape();\n}\n\nfunction drawMountainAndHouses(a, speed, high, low) {\n    noStroke();\n    fill(200, 100, 60);     \/\/ foreground mountain color\n    beginShape();\n    vertex(width, height);\n    vertex(0, height);\n    for(var i = 0; i &lt; width + 1; i ++){\n        var x = (i * a) + (millis() * speed);\n        var y = map(noise(x), 0, 1, high, low); \n        vertex(i, y);\n    }\n    endShape();\n\n    if (newhouseProbability &gt; random(1.0)) {  \n        \/\/ make new house randomly\n        var newhouse = makehouse(width + 1, y);\n        house.push(newhouse);\n    }\n}\n\nfunction makehouse(px, py) {\n    var newhouse = {x : px,\n                y : random(220, py),\n                w : random(10, 30),\n                h : random(10, 30),\n                rh : random(3, 15),\n                c : color(random(100, 255), random(100), 0),\n                dx : -1,\n                houseExists: true,\n                move : movehouse,\n                show : showhouse}\n    return newhouse;\n}\n\nfunction showhouse() {  \/\/ house x, y, width, height, roof height\n    push();\n    fill(this.c);\n    rect(this.x, this.y, this.w, this.h);\n    beginShape();\n    vertex(this.x - 2, this.y);\n    vertex(this.x + (this.w\/2), this.y - this.rh); \/\/ roof peak\n    vertex(this.x + this.w + 2, this.y);\n    endShape();\n    fill(230, 180, 120);\n    rect(this.x + this.w \/ 2 - 4, this.y + this.h, this.w \/ 4, -this.h \/ 2); \/\/ door\n    pop();\n}\n\nfunction movehouse() {\n    this.x += this.dx;\n    if(this.y + this.h &gt; waterlevel1) {\n        this.houseExists = false;\n    }\n}\n\nfunction makePlant() {\n    var plant = {x: 0,\n                y: 0,\n                c: color(random(50), random(100, 200), random(100)),\n                n: floor(random(3, 6)),\n                len: random(-5, -40),\n                plantExists: true,\n                show: showPlant,\n    }\n    return plant;\n}\n\nfunction showPlant() {\n    push();\n    translate(0, height + 10 + sceneNum * 3);\n    rotate(15 \/ this.n)\n    stroke(this.c);\n    strokeWeight(6\/this.n);\n    for (var i = 0; i &lt; this.n; i++) {\n        line(0, 0, 0, this.len + random(-1, 1));\n        rotate(-30 \/ this.n);\n    }\n    pop();\n}\n\nfunction makeFish() {\n        var newFish = {x: random(0, width), \n                y: random(waterlevel1 + 10, height-20),\n                w: int(random(10, 25)), h: int(random(5, 10)),\n                dx: random(-3, 3), \n                c: color(random(100, 255), random(100), random(100)),\n                fishExists: true,\n                fishDead: false,\n                show: showFish,\n                move: moveFish,\n                }\n        return newFish;\n}\n\nfunction moveFish() {\n    this.x += this.dx;\n    if (sceneNum == 0) {\n        \/\/ with no dam, fish change directions (off canvas)\n        if(this.x &gt; width + 20 || this.x &lt; -20) {\n            this.dx = -this.dx;\n        }\n    } else {\n        \/\/ if fish is to the left of dam, disappears\n        if(this.x &lt; damX + 30) {\n            this.fishExists = false;\n        } \/\/ if fish is above water, dies\n        else if(this.y &lt; waterlevel2 + 5) {\n            this.fishDead = true;\n        }\n        \/\/ if fish hits dam or goes off screen, change direction\n        if(this.x &gt; width + 20 || this.x &lt;= damX + 33) {\n            this.dx = -this.dx;\n        }\n    }\n}\n\nfunction showFish() {\n    fill(this.c);\n    ellipse(this.x, this.y, this.w, this.h);\n    if(this.dx &lt; 0) {  \/\/ facing left\n        if(this.fishDead) {\n            \/\/ if fish is dead, eyes make it appear belly-up\n            fishEye(this.x - 3, this.y + 3, this.w \/ 4);\n        } else {\n            fishEye(this.x - 3, this.y - 3, this.w \/ 4, true);\n        }\n        triangle(this.x + this.w\/3, this.y, \n                    this.x+this.w, this.y-5, \n                    this.x+this.w, this.y+5);\n    } else {  \/\/ facing right\n        if(this.fishDead) {\n            \/\/ if fish is dead, eyes make it appear belly-up\n            fishEye(this.x + 3, this.y + 3, this.w \/ 4);\n        } else {\n            fishEye(this.x + 3, this.y - 3, this.w \/ 4, true);           \n        }\n        triangle(this.x - this.w\/3,this.y, \n                this.x-this.w, this.y-5, \n                this.x-this.w, this.y+5);\n    }\n    \/\/ if fish is dead, stay floating at water level\n    if(this.fishDead) {\n        this.y = waterlevel2;\n        this.dx = 0;\n    }\n}\n\nfunction fishEye(x, y, sz, alive) {\n    push();\n    fill(255);\n    ellipse(x, y, sz, sz);\n    if (alive) {\n        fill(0);\n        ellipse(x, y, 2, 2);\n    }\n    pop();\n}\n\nfunction water() {\n    if(sceneNum == 0) { \/\/ initial river ripples using mountain function\n        drawMountain(2, 0.005, 0.0005, waterlevel1+10, waterlevel1-10);\n    }\n    push();\n    \/\/ water line shows gradient of water loss\n    for(var i = 0; i &lt; sceneNum; i++) {\n        var alph = 10;     \/\/ alpha\n        fill(0, alph);    \/\/ waterline\n        rect(0, 240, width, height -240);\n        alph += 3;\n        translate(0, 10);\n    }\n    pop();\n\tfill(20, 50 + sceneNum * 6, 180 - sceneNum * 6);     \/\/ blue water\n\tif (sceneNum == 0) {\n\t\trect(0, waterlevel1, width, height - waterlevel1);\n\t} else {\n        if (factNum &gt; 9) {   \/\/ fact 10 is about algae blooms\n            fill(20, 100, 50);\n        }\n\t\t\/\/ water left of dam\n\t\trect(0, waterlevel1, damX, height - waterlevel1);\n\t\t\/\/ water right of dam\n\t\trect(damX, waterlevel2, width - damX, height - waterlevel2);\n\t} \n}\n\nfunction makeDam() {\n\tfill(180, 180, 150);\n\tif (sceneNum &gt; 0) {\n\t\tbeginShape();\n\t\tvertex(damX - 10, waterlevel1 - 20);\n\t\tvertex(damX + 5, waterlevel1 - 20);\n\t\tvertex(damX + 30, height);\n\t\tvertex(damX - 10, height);\n\t\tendShape();\n\t}\n}<\/code><\/pre><\/div><\/body><\/html>\n","protected":false},"excerpt":{"rendered":"<p>This project is inspired by the tensions between dams, the environment, and people displaced or otherwise affected by dams. In this animation, you become the dam builder. By pressing the mouse anywhere on the canvas, a dam emerges in the river, affecting the water level, marine life (fish and plants), and nearby communities (houses). Moving &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/2022\/12\/10\/dam-it\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;dam it!&#8221;<\/span><\/a><\/p>\n","protected":false},"author":741,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[116,55],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts\/76227"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/users\/741"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/comments?post=76227"}],"version-history":[{"count":1,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts\/76227\/revisions"}],"predecessor-version":[{"id":76228,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/posts\/76227\/revisions\/76228"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/media?parent=76227"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/categories?post=76227"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2022\/wp-json\/wp\/v2\/tags?post=76227"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}