Final Project

sketch
/* Evan Stuhfire
 * estuhlfi@andrew.cmu.edu section B
 * Project-14: Municiple Water Management Game
*/

// map repair state variables
var rsGreen = 0;
var rsYellow = 1;
var rsOrange = 2;
var rsRed = 3;

// variable to track dam cracks
var dYellow = false;
var dOrange = false;
var dRed = false;

// map facility icons to text
var fDam = "Dam";
var fFiltration = "Filter";
var fPumping = "Pump";
var fHydro = "Hydro\nPower";

// Array to hold facility icons
var iconArray = [];

// Array to hold house objects
var houseArray = [];
var numHouses = 5;
// arrays to store house coordinates
var houseX = [35, 80, 140, 210, 190];
var houseY = [315, 335, 310, 285, 330];

// global worker object
var workerObj;

// player stats, number of fixes
var statsObj;
// control for directions page
var gameStart = true;

function drawIcon() {
    fill(this.repairColor);
    // Draw both the tray and the facility icons
    drawIconHelper(this.trayx, this.trayy, 
        this.traySize, this.facilityIcon, 13);
    drawIconHelper(this.facilityx, this.facilityy,
        this.facilitySize, this.facilityIcon, 10);
}

function drawIconHelper(x, y, size, label, txs) {
    push();
    translate(x, y);
    ellipse(0, 0, size);

    strokeWeight(1);
    fill(10);
    textAlign(CENTER);
    textSize(txs);
    text(label, 0, -3);
    pop();
}

function drawWorker() {
    fill(255);
    // draw circle to contain the worker
    ellipse(this.wx, this.wy, this.size);

    // draw stickman worker
    drawStickFigure(this.wx, this.wy, this.headSize);
    textAlign(CENTER);
    textSize(12);
    fill(255);
    strokeWeight(1);
    text("1. Click the worker", this.wx, this.wy + 50);
}

function drawStickFigure(x, y, h) {
    fill(255);
    strokeWeight(1.5);
    // body
    line(x, y - 15, x, y + 20);
    // legs
    line(x, y + 20, x - 10, y + 30);
    line(x, y + 20, x + 10, y + 30);
    // arms
    line(x, y + 10, x -10, y + 15);
    line(x, y + 10, x + 10, y + 15);

    // head
    circle(x, y - 15, h);

    // hat
    fill(255, 255, 0);
    arc(x, y - 20, 30, 33, PI, 2 * PI, OPEN);
    arc(x, y -25, 30, 15, 0, PI, CHORD);

    // eyes
    line(x - 5, y - 15, x - 5, y - 12);
    line(x + 5, y - 15, x + 5, y - 12);
    // mouth
    line(x - 5, y - 5, x + 5, y - 5);
}

function drawHouse() {
    // draw a house 
    // brick red
    fill(153, 0, 0);
    rect(this.hx, this.hy, this.hw, this.hh);

    // draw roof
    fill(50); // grey for roof
    triangle(this.hx, this.hy, this.hx + this.hw/2, this.hy - 15, 
        this.hx + this.hw, this.hy);

    // draw windows
    if(this.power == true) {
        fill(255, 255, 153); // yellow for lit windows 
    } else {
        fill(5); // black for unlit windows, no power
    }
   
    rect(this.hx + 5, this.hy + 5, 10, 12);
    rect(this.hx + 25, this.hy + 5, 10, 12);

    // draw door
    fill(153, 102, 51); // brown for door
    rect(this.hx + 15, this.hy + 15, 10, 15);
}

function houseState() {
    // change power to house based on probability of 
    // an outage, chances increae with higher repair state
    var chanceOfOutage = 0;
    var highState = 0;

    // find highest repair state of hydro power
    for(i = 0; i < iconArray.length; i++) {
        var currentIcon = iconArray[i];
        if(currentIcon.facilityIcon.slice(0, 1) == "H" &
         currentIcon.repairState > highState) {
            highState = currentIcon.repairState;
        }
    }

    if(highState >= rsOrange & this.power == false){
        return;
    }

    // green repair state all houses have power
    switch (highState) {
    case rsGreen:
        chanceOfOutage = 0;
        break;
    case rsYellow:
        // yellow repair state, probability of outage = low
        chanceOfOutage = .005;
        break;
    case rsOrange:
        // orange repair state, probability of outage = medium
        chanceOfOutage = .01;
        break;
    case rsRed:
        // red repair state, probability of outage = high
        chanceOfOutage = .5
        break;
    }
    if(random(0, 1) < chanceOfOutage) {
        this.power = false; // outage
    } else {
        this.power = true; // no outage
    }
}

function changeState() {
    if(gameStart == true) {
        return;
    }

    repairFacility(this);

    // generate a problem based on likelyhood
    if(random(0, 1) < this.problemLikely) {
        this.ageOfState++;
        // increase likelihood of problems over time
        this.problemLikely += .002;
    }


    if(this.ageOfState > 15 & this.repairState == rsYellow) {
        // set state and color to orange
        // reset ageOfState and increase likelyhood of problem

        this.repairState = rsOrange; 
        this.repairColor = color(255, 102, 0);
        this.ageOfState = 0; 
        this.problemLikely = .015;        
    } else if(this.ageOfState > 10 & this.repairState == rsOrange) {
        // set state and color to red
        // reset ageOfState and increase likelyhood of problem

        this.repairState = rsRed;
        this.repairColor = color(204, 0, 0);
        this.ageOfState = 0;
        this.problemLikely = .02; 

        if(this.facilityIcon.slice(0, 1) == "D" ||
            this.facilityIcon.slice(0, 1) == "P") {
            statsObj.floods++;
        } else if(this.facilityIcon.slice(0, 1) =="F"){
            statsObj.filterFail++;
        } else {
            statsObj.powerLoss++;
        }
    } else if(this.ageOfState > 5 & this.repairState == rsGreen) {
        // set state and color to yellow
        // reset ageOfState and increase likelyhood of problem

        this.repairState = rsYellow;
        this.repairColor = color(255, 255, 0);
        this.ageOfState = 0;
        this.problemLikely = .01;
    } 

    // Check for failing services
    if(this.facilityIcon.slice(0, 1) == "D") {
        damFailure(this);
    } else if(this.facilityIcon.slice(0, 1) == "P" &
        this.repairState == rsRed) {
        pumpFailure(this);
    } else if(this.facilityIcon.slice(0,1) == "F" &
        this.repairState == rsRed) {
        filterFailure(this);
    }
}

function makeIconObj(tx, ty, fx, fy, fac) {
    // object def for game icons
    var icon = {trayx: tx,
                trayy: ty,
                facilityx: fx,
                facilityy: fy,
                traySize: 50,
                facilitySize: 35,
                facilityIcon: fac, 
                repairState: rsGreen,
                repairColor: color(0, 200, 0), 
                ageOfState: 0,
                problemLikely: .05,
                trayClick: false,
                facillityClick: false,
                drawFunction: drawIcon,
                stateFunction: changeState
                }
    return icon;
}

function makeWorker(x, y) {
    // object def for worker
    var icon = {wx: x,
                wy: y,
                size: 80,
                headSize: 30,
                clicked: false,
                drawFunction: drawWorker
                }
    return icon;
}

function makeHouse(x, y) {
    // object def for houses
    var house = {hx: x,
                hy: y,
                hw: 40, // house width
                hh: 30, // house height
                power: true,
                drawFunction: drawHouse,
                stateFunction: houseState}

    return house;
}

function makeStats() {
    // object definition for game stats
    var stats = {maxRepairs: 10,
                maxAge: 60,
                repairs: 0,
                floods: 0,
                filterFail: 0,
                powerLoss: 0}

    return stats;
}

function createIcons() {
    // create icons for equipment tray
    iconArray.push(makeIconObj(200, 430, 295, 140, fDam));
    iconArray.push(makeIconObj(270, 430, 60, 217, fFiltration));
    iconArray.push(makeIconObj(340, 430, 397, 300, fPumping));
    iconArray.push(makeIconObj(410, 430, 305, 235, fHydro));

    // create worker icon
    workerObj = makeWorker(70, 425);

    // create game stats object
    statsObj = makeStats();
}   

function createHouses() {
    // make numHouses number of houses
    for(i = 0; i < numHouses; i++) {
        houseArray[i] = makeHouse(houseX[i], houseY[i]);
    }    
}

function setup() {
    createCanvas(480, 480);
    createIcons();
    createHouses();
}

function draw() {
    background(204, 239, 255);
    drawScene();

    // draw houses
    for(j = 0; j < houseArray.length; j++) {
        var currentHouse = houseArray[j];
        currentHouse.stateFunction();
        currentHouse.drawFunction();
    }


    // draw game icons
    var cIcon = 10;
    for(i = 0; i < iconArray.length; i++) {
        var currentIcon = iconArray[i];

        currentIcon.stateFunction();
        currentIcon.drawFunction();

        // if the tray icon was clicked show on mouse
        if(currentIcon.trayClick == true) {
            fill(currentIcon.repairColor);

            // transform to make small icon at mouse pointer
            push();
            scale(.5);
            translate(mouseX, mouseY);
            drawIconHelper(mouseX - 70, mouseY + 30, 
                currentIcon.traySize,
                currentIcon.facilityIcon);
            pop();
        }
    }

    // draw worker icon
    workerObj.drawFunction();

    // if the worker and/or icon has been clicked,
    // draw worker/icon at mouse pointer
    if(workerObj.clicked == true) {
        push();
        // transformation to make small worker at mouse pointer
        scale(.5);
        translate(mouseX, mouseY);
        drawStickFigure(mouseX - 20, mouseY + 40, workerObj.headSize);
        pop();
    }

    drawScore();

    // at the start of game show instructions
    if(gameStart == true) {
        instructions();
    }

    // Display game stats
    // if at least maxRepairs 
    if(statsObj.repairs >= statsObj.maxRepairs || 
            iconArray[0].ageOfState >= 100) {
        gameStats();
        noLoop(); 
    }
}


function mouseClicked() {
    // start game
    if(gameStart == true) {
        gameStart = false;
        return;
    }

    // check if worker was clicked
    var d = dist(mouseX, mouseY, workerObj.wx, workerObj.wy);
    if(d < workerObj.size/2) {
        if(workerObj.clicked == false) {
            workerObj.clicked = true;
        } else {
            workerObj.clicked = false;
        }
        return;
    }

    // check if worker has been clicked
    if(workerObj.clicked == true) {
        // check if tool was clicked in equipement tray
        for(var i = 0; i < iconArray.length; i++) {
            var icon = iconArray[i];
            var d = dist(mouseX, mouseY, icon.trayx, icon.trayy);
            if(d < icon.traySize/2) {
                setTrayIcon(i);
                return;
            }

            // check if facility was clicked
            if(icon.trayClick == true) {
                var d = dist(mouseX, mouseY, icon.facilityx, icon.facilityy);
                if(d < icon.facilitySize/2) {
                    icon.facilityClick = true;
                }
            }
        }
    }
}

function gameStats() {
    // draw final game stats from statsObj
    push();

    fill(255, 255, 255, 235);
    rectMode(CENTER);
    rect(width/2, height/2, 400, 400);
    fill(5);
    textSize(24);
    strokeWeight(1);
    textAlign(CENTER);
    text("You made "+statsObj.repairs+" repairs", width/2, 75);

    textSize(16);
    text("The town flooded "+statsObj.floods+" time(s)", 
            width/2, 115);
    text("The town filtration failed "+statsObj.filterFail+" time(s)", 
            width/2, 145);
    text("The town lost all power "+statsObj.powerLoss+" time(s)", 
            width/2, 175);

    textSize(24);
    text("Refresh to Play Again", width/2, 380);

    pop();
}

function instructions() {
    // Create instruction front page
    fill(255, 255, 255, 235);
    push();
    rectMode(CENTER);
    rect(width/2, height/2, 400, 400);
    fill(5);
    textSize(24);
    strokeWeight(1);
    textAlign(CENTER);
    text("Municipal Water Management Game", width/2, 75);
 
    // create a click to start message
    text("Click Anywhere to Start", width/2, 420);

    textAlign(LEFT);
    textSize(14);

    var x = 55;
    var y = 110;
    // Display instructions
    text("Welcome! You are managing the repairs for a town's water",
        x, y);
    text("supply. If the dam or pump fail the town will flood. If the",
        x, y + 20);
    text("filtration system fails the water will be dirty. If the hydro",
        x, y + 40);
    text("electric plant falters the lights in the houses will flicker and",
        x, y + 60);
    text("go out. Circle icon colors change as urgency increases.",
        x, y + 80);

    textAlign(CENTER);
    textSize(20);
    text("To Play: Make Repairs", width/2, y + 120);

    textAlign(LEFT);
    textSize(14);
    text("1. Click the worker. The icon will appear at the mouse pointer.",
        x, y + 150);
    text("2. Click a yellow, orange, or red icon from the icon tray.",
        x, y + 180);
    text("3. Click the matching facility in need of repair.",
        x, y + 210);
    pop();
}

function setTrayIcon(index) {
    // when setting icon clicked = true, set the others = false
    for(i = 0; i < iconArray.length; i++) {
        if(i == index) {
            iconArray[i].trayClick = true;
        }else {
            iconArray[i].trayClick = false;
        }
    }
}

function drawScore() {
    fill(5);
    strokeWeight(1);
    textAlign(LEFT);
    text("Repairs made: " + statsObj.repairs, 3, 15);
}

function repairFacility(cur) {
    // reset icons, player repairs the service
    if(cur.facilityClick == true) {
        if(cur.repairState == rsGreen) {
            // there was nothing to repair
            return;
        }

        // increment number of fixes for player score
        statsObj.repairs++;

        cur.trayClick = false;
        cur.facilityClick = false;
        workerObj.clicked = false;

        // update for repaird facilities repaired
        if(cur.facilityIcon.slice(0, 1) == "D") {
            damFail = false;
        } else if(cur.facilityIcon.slice(0, 1) == "P") {
            pumpFail = false;
        } else if (cur.facilityIcon.slice(0, 1) == "F") {
            filterFail = false;
        } 

         // user clicked to repair
        // reset state to green
        cur.repairState = rsGreen;
        cur.repairColor = color(0, 200, 0);
        // reset age of facility to 0
        cur.ageOfState = 0;
        // reset probability of problem
        cur.problemLikely = .007;
        return;
    }
}

// variables to track failure
var damFail = false;
var pumpFail = false;
var filterFail = false;

function filterFailure(filter) {
    if(filter.repairState == rsRed) {
        filterFail = true;
    }
}

function pumpFailure(pump) {
    if(pump.repairState == rsRed) {
        pumpFail = true;
    }
}

function damFailure(dam) {
    if(dam.repairState == rsGreen & dYellow == true){
        // reset cracks
        dYellow = false;
        dOrange = false;
        dRed = false;
    }

    if(dam.repairState == rsRed) {
        dRed = true;
        damFail = true;
    } else if(dam.repairState == rsOrange) {
        dOrange = true;
    } else if(dam.repairState == rsYellow) {
        dYellow = true;
    }
}

function drawScene() {
    // draw horizon line
    fill(0, 102, 0);
    rect(0, height/3, width, height);

    drawStaticElements();
    drawCracks();
    drawFlood();
    drawFilterFail();
}


function drawStaticElements() {
    // draw static elements for the game background
    // function are in static.js
    drawMountains();
    drawWater(r, g, b);  
    drawDam();
    drawFiltration();
    drawPumpStation();
    drawHydro();

    drawIconTray();
}

var r = 0;
var g = 0;
var b = 204;
var ft = 0; // filter transparency

function drawFilterFail() {
    // turn water brown to show it is polluted
    // when the filter fails
    if(filterFail == true) {
        r = 134;
        g = 89;
        b = 45;
        ft = min(t + 1, 255);
    } else {
        r = 0;
        g = 0;
        b = 204;
        ft = 0; // filter transparency
    }
}

var t = 0; // variable to control transparency
function drawFlood() {

    // flood the town when the dam fails
    if(damFail == true || pumpFail == true) { 
        t = min(t + 3, 255);       
    }
    else if (damFail == false & pumpFail == false) {
        // dam is repaired decrease transparency
        // to make grass green again
        t = max(t - 3, 0);
    }
    fill(r, g, b, t);
    rect(0, height/3, width, height);
    drawStaticElements();
    drawCracks();
}

function drawCracks() {
    // draw crack in dam
    if(dYellow == true) {
    // draw small cracks
        noFill();
        strokeWeight(1);

        beginShape();
        vertex(355, 170);
        vertex(365, 162);
        vertex(370, 140);
       
        endShape();
    }

    if(dOrange == true) {
    // draw more cracks
        noFill();

        beginShape();
        vertex(350, 170);
        vertex(342, 180);
        vertex(333, 164);
        vertex(325, 168);
       
        endShape();
        strokeWeight(2);

        beginShape();
        vertex(355, 170);
        vertex(380, 180);
        vertex(392, 164);
       
        endShape();
    }

        if(dRed == true) {
        // draw many cracks
        noFill();

        beginShape();
        vertex(350, 170);
        vertex(347, 175);
        vertex(355, 182);
        vertex(358, 190);
        vertex(383, 192);
        vertex(400, 194);
        vertex(425, 205);
       
        endShape();
        strokeWeight(3);

        beginShape();
        vertex(345, 170);
        vertex(340, 160);
        vertex(325, 155);
        vertex(315, 152);
       
        endShape();
    }

    strokeWeight(1);
}

// Functions to draw static game elements

function drawIconTray() {
    fill(230);
    textAlign(LEFT);
    textSize(12);
    strokeWeight(1);
    text("Icon Tray", 165, 395);
    text("2. Click icon from tray          3. Click matching facility", 
        165, 475);
    rect(165, 400, 285, 60);
}

function drawHydro() {
    // draw hydro electric power
    fill(179, 179, 204); 
    beginShape(); 
    vertex(255, 220); 
    vertex(365, 237);
    vertex(365, 254); 
    vertex(255, 237); 
    endShape(CLOSE); 

    // draw top
    beginShape();
    vertex(255, 220);
    vertex(320, 200);
    vertex(388, 208);
    vertex(365, 237);
    endShape(CLOSE);;

    // draw side
    beginShape();
    vertex(365, 237);
    vertex(388, 208);
    vertex(388, 215);
    vertex(365, 254);
    endShape();
}

function drawPumpStation() {
    // draw pumpStation
    fill(179, 179, 204);
    rect(width * .75, 275, 75, 50);

    // pump station top
    beginShape();
    vertex(width *.75, 275);
    vertex(width *.75 + 15, 265);
    vertex(width * .75 + 90, 265);
    vertex(width * .75 + 75, 275);
    endShape(CLOSE);

    // pump station side
    beginShape();
    vertex(width * .75 + 90, 265);
    vertex(width * .75 + 90, 310);
    vertex(width * .75 + 75, 325);
    vertex(width * .75 + 75, 275);
    endShape(CLOSE);

    // Draw pipe
    beginShape();
    vertex(width * .75, 285);
    vertex(width * .75 - 30, 285);
    vertex(width * .75 - 30, 325);
    vertex(width * .75 - 15, 325);
    vertex(width * .75 - 15, 300);
    vertex(width * .75, 300);
    endShape(CLOSE);
}

function drawFiltration() {
    // draw filtration faciity
    fill(179, 179, 204);
    rect(width/14, height/2.5, 50, 50);

    // Draw top
    beginShape();
    vertex(width/14, height/2.5);
    vertex(width/14 + 20, height/2.5 - 10);
    vertex(width/14 + 70, height/2.5 - 10);
    vertex(width/14 + 50, height/2.5);
    endShape(CLOSE);

    // Draw side
    beginShape();
    vertex(width/14 + 70, height/2.5 - 10);
    vertex(width/14 + 70, height/2.5 + 40);
    vertex(width/14 + 50, height/2.5 + 50);
    vertex(width/14 + 50, height/2.5);
    endShape(CLOSE);

    // Draw pipe 1
    ellipse(100, 202, 10, 10);
    beginShape();
    vertex(98, 198);
    vertex(130, 200);
    vertex(130, 240);
    vertex(125, 240);
    vertex(125, 205);
    vertex(98, 205);
    endShape(CLOSE);

    // Draw pipe 2
    ellipse(95, 222, 10, 10);
    beginShape();
    vertex(93, 218);
    vertex(113, 218);
    vertex(113, 245);
    vertex(107, 245);
    vertex(107, 225);
    vertex(93, 225);
    endShape(CLOSE);
}

function drawWater(r, g, b) {
    // draw water as a multipoint curve vertex shape
    fill(r, g, b);
    beginShape();

    curveVertex(425, 100);
    curveVertex(280, 120);
    curveVertex(320, 200);
    curveVertex(250, 240);
    curveVertex(0, 260);
    curveVertex(0, 300);
    curveVertex(270, 280);
    curveVertex(470, 150);

    endShape(CLOSE);
}

function drawDam() {
    var x = width * .55;
    var y = height/3;

    fill(179, 179, 204);

    // draw face of dam
    beginShape();
    vertex(x, y + 50);
    vertex(x + 60, y + 45);
    vertex(x + 90, y + 50);
    vertex(x + 120, y + 55);
    vertex(x + 150, y + 70);
    vertex(x + 185, y + 90);
    vertex(x + 185, y -20);
    vertex(x, y - 50);
    endShape(CLOSE);

    // draw top ledge
    beginShape();
    vertex(x, y - 50);
    vertex(x + 30, y - 55);
    vertex(x + 215, y - 25);
    vertex(x + 185, y - 20)
    endShape();

    // draw right side
    beginShape();
    vertex(x + 185 , y - 20);
    vertex(x + 215, y - 25);
    vertex(x + 215, y + 85);
    vertex(x + 185, y + 90)
    endShape();
}

function drawMountains() {
    // set origin to 0, horizon line
    push();
    translate(0, height/3);

    // draw curves for background mountains
    fill(71, 71, 107);
    beginShape();
    vertex();
    vertex(-20, 20);
    vertex(0, -125);
    vertex(45, -80);
    vertex(120, -155);
    vertex(200, -85);
    vertex(250, -135);
    vertex(290, -90);
    vertex(360, -140);
    vertex(440, -40);
    vertex(500, -120);
    vertex(510, 0);
    endShape(CLOSE);

    // draw curves for mid range mountains
    fill(153, 153, 150);
    beginShape();
    vertex(-30, 30);
    vertex(30, -65);
    vertex(75, -30);
    vertex(120, -90);
    vertex(165, -35);
    vertex(210, -65);
    vertex(255, -25);
    vertex(310, -80);
    vertex(395, 25);
    endShape(CLOSE);

    // draw curves for near mountains
    fill(0, 153, 51);
    beginShape();
    curveVertex(-30, 60);
    curveVertex(0, -5);
    curveVertex(50, -15);
    curveVertex(95, -5);
    curveVertex(135, -20);
    curveVertex(175, -5);
    curveVertex(220, -15);
    curveVertex(275, 10);
    curveVertex(300, 25)
    endShape(CLOSE);

    pop();
}


Srauch – Final Project

Here is my final project! It’s an interactive animation of a waterpark. Click anywhere to send someone down a random slide — or, if you prefer, click the top of a slide to send someone down that specific one!

sketch

//sam rauch, srauch, section B
//final project
//this code creates an animation of a waterpark. It's populated with people objects that have a
//skin tone and swimsuit color randomly picked from an array, so they are different every time
//you reload the page. In the foreground, people go by in a lazy river in tubes. In the background,
//people wait in line for waterslide towers.
//click anywhere to send someone down a random slide, or, click at the top of a slide to send
//a person down that specific slide!

//clouds x, y, and scale
var cloudsx = [];
var cloudsy = [];
var cloudsSc = [];

//skin tones and swimsuit colors
var skincolors;
var swimcolors;

//will hold people waiting for waterslide 1
var topSlide = [];
var slideToppers =[];
var groundWaiters1 = [];
var stairWaiters1 = [];

//will hold people waiting for waterslide 2
var groundWaiters2 = [];
var stairWaiters2 = [];
var topguy;

//bushes and trees
var bushSizes = [];
var bushColors = [];
var treeSizes = [];
var treeColors = [];

//people in lazy river
var tubers = [];

//color of wood in waterslide towers
var woodcolor;

//variables for people going down slides
var slider;
var slidetoggler;
var randomizer1;

//store mouseX and mouseY when clicked
var xWhenClick;
var yWhenClick;

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

    woodcolor = color(105, 89, 56);

    //fill cloud array with clouds at random scales and positions
    for (var i=0; i<8; i++){
        cloudsx[i]= random(-10, width-10);
        cloudsy[i] = random(-10, 200);
        cloudsSc[i] = random(1,3);
    }

    //skin tones and swimsuit color values
    skincolors = [color(235, 207, 176), color(204, 168, 126), color(107, 77, 43),
                color(148, 98, 41), color(117, 84, 47), color(217, 195, 154),
                color(235, 213, 192), color(69, 48, 29), color(247, 220, 195)];
    swimcolors = [color(194, 78, 130), color(224, 49, 22), color(224, 144, 22),
                color(102, 23, 11), color(102, 23, 11), color(102, 93, 11),
                color(207, 195, 87), color(159, 207, 87), color(49, 145, 42),
                color(42, 145, 89), color(92, 191, 186), color(92, 140, 191),
                color(24, 73, 125), color(105, 89, 156), color(154, 89, 156),
                color(55, 84, 179)]

    //filling the array that handles the people in the lazy river
    var tubespacer = 50;
    for (var i=0; i<10; i++){
        tubers[i] = makeTuber(tubespacer, random(340, 350));
        tubespacer += random(30, 100);
    }

    //creating the size and color of the bushes and trees
    for (var i=0; i<width+30; i++){
        bushColors[i] = color(100, random(150, 170), 100);
        bushSizes[i] = random(30, 60);
        treeColors[i] = color(100, random(150, 170), 100);
        treeSizes[i] = random(100, 150);
    }

    //filling the array of people waiting on top of waterslide1
    var slideLocation = 410;
    for (var i=0; i<3; i++){
        topSlide[i] = makeDude(365+(i*15), 125, false);
        slideToppers[i] = makeDude(slideLocation, 125, false);
        slideLocation +=40;
    }

    //filling the array of people waiting for waterslide1 on the ground
    var groundWaiters1Loc = 280;
    for (var i=0; i<9; i++){
        groundWaiters1[i] = makeDude(groundWaiters1Loc, 280, false);
        groundWaiters1Loc += 20;
    }

    //filling the array of people waiting on the waterslide1 stairs
    var stairWaiters1Loc = 460;
    var stairHeight1 = 280;
    for (var i=1; i<13; i++){
        stairWaiters1[i] = makeDude(stairWaiters1Loc, stairHeight1, false);
        stairWaiters1Loc += 17;
        if (i<4 || i>=3) {stairHeight1-= 20;}
        if (i%4 == 0) {stairWaiters1Loc = 460;}
        if (i>4 & i<=8) {stairHeight1 = 205;}
    }

    //filling array of people waiting on ground for waterslide 2
    var groundWaiters2Loc = 240;
    for (var i=0; i<6; i++){
        groundWaiters2[i] = makeDude(groundWaiters2Loc, 270, false);
        groundWaiters2Loc -= 20;
    }

    //filling array of people waiting on stairs for waterslide 2
    var stairWaiters2Loc = 120;
    var stairHeight2 = 265;
    var sidestep = 14;
    var counter2 = 0;
    for (var i=0; i<20; i++){
        stairWaiters2[i] = makeDude(stairWaiters2Loc, stairHeight2, false);
        counter2 += 1;
        if (counter2%4==0){
            sidestep = sidestep*-1;
        }else{
            stairWaiters2Loc -= sidestep;
        }
        stairHeight2 -= 11;
    }
    topguy = makeDude(85, 50, false);

    //when this is true (set to true when mouse is clicked), an if statement in draw
    //runs that sends someone down a slide
    slidetoggler = false;

}

function draw() {
    background(162, 219, 222);
    backgroundstuff(); //draw clouds, trees, waterslides
    slidego(); //send someone down slide when the mouse is clicked
    foregroundstuff(); //draw lazy river and bushes
}

//trigger someone to go down slide in draw function
function mousePressed(){
    xWhenClick = mouseX;
    yWhenClick = mouseY;
    slidetoggler = true;
    slider = makeDude(0, 0, true);
    randomizer1 = random(0,4);
}

//translate and rotate to the top of a specific slide
function slidemover(xpos,ypos,rot){
    push();
    translate(xpos,ypos);
    rotate(radians(rot));
    slider.y += 4;
    slider.draw();
    pop();
}

//send someone down specific slide if clicked, random otherwise
function slidego(){
if (slidetoggler==true){
        //if click at the top of a specific slide, send someone down that slide
        if (xWhenClick >= 70 & xWhenClick <= 130 && yWhenClick >= 40 && yWhenClick <= 100){
            slidemover(88,50,-25);
        } else if (xWhenClick >= 400 & xWhenClick <= 435 && yWhenClick >= 110 && yWhenClick <= 170){
            slidemover(432,140,30);
        } else if (xWhenClick >= 440 & xWhenClick <= 475 && yWhenClick >= 110 && yWhenClick <= 170){
            slidemover(472,140,30);
        } else if (xWhenClick >= 480 & xWhenClick <= 515 && yWhenClick >= 110 && yWhenClick <= 170){
            slidemover(512,140,30);
        } else { //otherwise, send down a random slide
            push();
            if(randomizer1<=3){ //for three slides on right tower
                if (randomizer1 < 1){
                    translate(432,140);
                } else if (randomizer1 >= 1 & randomizer1 < 2){
                    translate(472,140);
                } else {
                    translate(512, 140);
                }
                rotate(radians(30));            
            } else { //for tall slide on left tower
                translate(88,50);
                rotate(radians(-25));
            }
            slider.y+= 4;
            slider.draw();
            pop();
        }
    }
}

//creates a person object
function makeDude(xpos, ypos, armpos){
    var dude = {x:xpos, y:ypos, armsup:armpos,
        swimsuit:swimcolors[floor(random(0,15))],
        swimtype:random(0,2),
        skin:skincolors[floor(random(0,9))],
        draw:drawDude};
    return dude;
}

function drawDude(){
    noStroke();
    fill(this.skin);
    ellipse(this.x, this.y, 10, 10); //head
    rect(this.x-5, this.y+7, 10, 16); //torso
    stroke(this.skin);
    strokeWeight(4.5);
    line(this.x, this.y, this.x, this.y+10); //neck

    strokeWeight(3.5); //toggles if arms are up or down based on this.armsup var declared in constructor
    if (this.armsup == true){
        line(this.x-4, this.y+7, this.x-11, this.y-2); //right arm
        line(this.x+4, this.y+7, this.x+11, this.y-2); //left arm
    } else {
        line(this.x-4, this.y+7, this.x-10, this.y+16); //right arm
        line(this.x+4, this.y+7, this.x+10, this.y+16); //left arm
    }

    strokeWeight(4);
    line(this.x-3, this.y+22, this.x-3, this.y+35); //right leg
    line(this.x+3, this.y+22, this.x+3, this.y+35); //left leg

    noStroke();
    if (this.swimtype<1){ //swim trunks
        fill(this.swimsuit);
        rect(this.x-6, this.y+18, 12, 5);
        rect(this.x-6, this.y+23, 5, 5);
        rect(this.x+1, this.y+23, 5, 5);
    } else { //bikini
        fill(this.swimsuit);
        rect(this.x-5, this.y+10, 10, 13);
        ellipse(this.x-2, this.y+10.5, 5, 5);
        ellipse(this.x+2, this.y+10.5, 5, 5);
        stroke(this.swimsuit);
        noStroke();
        fill(this.skin);
        triangle(this.x-1, this.y+24, this.x-5, this.y+24, this.x-5, this.y+18);
        triangle(this.x+1, this.y+24, this.x+5, this.y+24, this.x+5, this.y+18);
        rect(this.x-5, this.y+13, 10, 4);
    }
}

//creates a person in a tube object
function makeTuber(xpos, ypos){
    var tuber = {x:xpos, y:ypos,
        swimsuit:swimcolors[floor(random(0,15))],
        swimtype:random(0,2),
        skin:skincolors[floor(random(0,9))],
        draw:drawTuber};
    return tuber;
}

function drawTuber(){
    push();

    //inner tube
    stroke(this.skin);
    strokeWeight(4);
    line(this.x-1, this.y+12, this.x-11, this.y+22);
    noStroke();
    fill(62, 158, 62);
    rect(this.x-14, this.y+18, 28, 16);
    ellipse(this.x-14, this.y+26, 16);
    ellipse(this.x+14, this.y+26, 16);
    stroke(30, 94, 30);
    strokeWeight(4);
    line(this.x-10, this.y+23, this.x+10, this.y+23);

    //head, neck, torso, and back arm
    push();
    translate(this.x+6, this.y+4);
    rotate(radians(10));
    noStroke();
    fill(this.skin);
    ellipse(0, 0, 10, 10); //head
    rect(-5, 7, 10, 16); //torso
    stroke(this.skin);
    strokeWeight(4.5);
    line(0, 0, 0, 10); //neck

    noStroke();
    if (this.swimtype<1){ //swim trunks
        fill(this.swimsuit);
        rect(-6, 18, 12, 5);
        rect(-6, 23, 5, 5);
        rect(1, 23, 5, 5);
    } else { //bikini
        fill(this.swimsuit);
        rect(-5, 10, 10, 13);
        ellipse(-2, 10.5, 5, 5);
        ellipse(+2, +10.5, 5, 5);
        stroke(this.swimsuit);
        noStroke();
        fill(this.skin);
        triangle(-1, 24, -5, 24, -5, 18);
        triangle(1, 24, 5, 24, 5, 18);
        rect(-5, 13, 10, 4);
    }
    pop();
    strokeWeight(4.5);
    stroke(this.skin);
    line(this.x+4, this.y+25, this.x+4, this.y+25);
    line(this.x, this.y+25, this.x-6, this.y+21);

    //a few more details
    noStroke();
    fill(62, 158, 62);
    rect(this.x-10, this.y+25, 20, 9);
    strokeWeight(4.5);
    stroke(this.skin);
    line(this.x+10, this.y+14, this.x+16, this.y+25); //front arm
    line(this.x-6, this.y+21, this.x-10, this.y+31); //right leg
    line(this.x+2, this.y+25, this.x, this.y+34); //left leg

    //water texture
    noStroke();
    fill(81, 181, 201, 100);
    rect(this.x-22, this.y+30, 44, 6);

    pop();

}

//draws the waterslide on the left
function waterslide1(x,y){
    //stairs
    fill(woodcolor);
    beginShape();
    vertex(x+100, y+80);
    vertex(x+100, y+90);
    vertex(x+170, y+20);
    vertex(x+170, y+10);
    endShape();
    rect(x+100, y+80, 70, 8);
    beginShape();
    vertex(x+100, y+160);
    vertex(x+113, y+160);
    vertex(x+170, y+95);
    vertex(x+170, y+80);
    endShape();

    //pillars
    fill(95, 79, 46);
    rect(x+5, y+5, 5, 155);
    rect(x+100, y+5, 5, 155);
    rect(x+170, y+5, 5, 155);

    //shade poles
    rect(x+3, y-50, 3, 50);
    rect(x+180-6, y-50, 3, 50);
    rect(x+50, y-55, 3, 55);
    rect(x+130-6, y-55, 3, 55);

    //shades
    fill(35, 82, 168);
    rect(x+3, y-55, 47, 6);
    triangle(x+3, y-55, x+50, y-55, x+27, y-70);
    rect(x+50, y-60, 77, 5);
    triangle(x+50, y-60, x+127, y-60, x+88.5, y-85);
    rect(x+127, y-55, 50, 5);
    triangle(x+127, y-55, x+176, y-55, x+152, y-70);

    //railings
    fill(95, 79, 46);
    var xpos = x;
    for (var i = 0; i < 12; i++){
        rect(xpos, y-15, 2, 15);
        xpos += 5;
    }
    for (var j = 0; j<2; j++){
        xpos += 22
        for (var i = 0; i < 4; i++){
            rect(xpos, y-15, 2, 15);
            xpos += 5;
        }
    }
    xpos += 19
    for (var i = 0; i < 4; i++){
        rect(xpos, y-15, 2, 15);
        xpos += 5;
    }

    //deck
    fill(woodcolor);
    rect(x, y, 180, 10);
    rect(x, y-15, 180, 3);

    //draw slides
    var color1 = color(166, 61, 124);
    slide1(x+60, y, color1);
    var color2 = color(186, 176, 67);
    slide1(x+100, y, color2);
    var color3 = color(57, 94, 163);
    slide1(x+140, y, color3);

}

//draws slides for waterslide1 function
function slide1(x,y,color){ 
    var slidewide = 22;
    fill(color);
    beginShape();
    vertex(x, y);
    vertex(x+slidewide, y);
    vertex(x-80, y+180);
    vertex(x-80-slidewide, y+180);
    endShape();

    var margin = 4;
    fill(150, 255, 255, 50);
    beginShape();
    vertex(x+margin, y);
    vertex(x+slidewide-margin, y);
    vertex(x-80-margin, y+180);
    vertex(x-80-slidewide+margin, y+180);
    endShape();
}

//draws waterslide on left
function waterslide2(x,y){

    //pillars and stairs
    var loc = 310; //increment 46
    for (var i = 0; i< 5; i++){
        fill(woodcolor);
        if (i%2==0 || i==0) {
            beginShape();
            vertex(x-30, loc-51);
            vertex(x-30, loc-41);
            vertex(x+30, loc);
            vertex(x+30, loc-10);
            endShape();
        } else {
            beginShape();
            vertex(x-30, loc);
            vertex(x-30, loc-10);
            vertex(x+30, loc-51);
            vertex(x+30, loc-41);
            endShape();
        }   
        loc -= 44;
    }
    fill(95, 79, 46);
    rect(x-30, y, 6, 230); //bottom y = 310
    rect(x+24, y, 6, 230);

    rect(x-30, y-40, 3, 40);
    rect(x+27, y-40, 3, 40);
    fill(189, 65, 43);
    rect(x-30, y-45, 60, 6);
    triangle(x-30, y-45, x+30, y-45, x, y-60);

    fill(woodcolor);
    rect(x-30, y, 60, 10);
    rect(x-30, y-15, 15, 2.5);
    rect(x+15, y-15, 15, 2.5);
    var location = x-30;
    for (var i = 0; i<8; i++){
        rect(location, y-15, 2, 15);
        if (i != 3){location += 5;}
        else {location += 28;}
    }

    fill(252, 165, 3);
    beginShape();
    vertex(x-15, y);
    vertex(x+15, y);
    vertex(x+140, y+260);
    vertex(x+110, y+260);
    endShape();

    fill(150, 255, 255, 50);
    beginShape();
    vertex(x-10, y);
    vertex(x+10, y);
    vertex(x+130, y+250);
    vertex(x+115, y+260);
    endShape();
}

//draws cloud
function cloud(x,y, amt){
    noStroke();
    fill(218, 237, 236);
    push();
    translate(x,y);
    scale(amt);
    ellipse(0,0,40);
    ellipse(-20, 5, 30);
    ellipse(20, 5, 30);
    pop();
}

//draws background
function backgroundstuff(){
    //clouds
    for (var i=0; i<8; i++){
        cloud(cloudsx[i], cloudsy[i], cloudsSc[i]);
    }

    //trees
    noStroke();
    for (var i=0; i<width+30; i+= 80){
        fill(treeColors[i]);
        ellipse(i, 270, treeSizes[i]);
    }

    //fence
    strokeWeight(2);
    stroke(120);
    line(0, 280, width, 280);
    strokeWeight(.75);
    for (var i=-12; i<width+12; i+=4){
        line(i, 300, i+16, 280);
        line(i, 300, i-16, 280);
    }

    //concrete
    noStroke();
    fill(199, 196, 163); //concrete color
    rect(0, 300, width, 100);
    fill(168, 162, 28);

    //pool at base of slides
    fill(81, 181, 201);
    rect(80, 325, 420, 100);
    ellipse(80, 350, 50);
    ellipse(500, 350, 50);

    //people in waterslide1 line
    for (var i=0; i<topSlide.length; i++){
        topSlide[i].draw();
        slideToppers[i].draw();
    }
    for (var i=0; i<groundWaiters1.length; i++){
        groundWaiters1[i].draw();
    }
    for (var i=1; i<stairWaiters1.length; i++){
        stairWaiters1[i].draw();
    }

    //people in waterslide2 line
    for (var i=0; i<stairWaiters2.length; i++){
        stairWaiters2[i].draw();
    }
    for (var i=0; i<groundWaiters2.length; i++){
        groundWaiters2[i].draw();
    }
    topguy.draw();

    //draw waterslides
    waterslide1(350, 160);
    waterslide2(100, 80);
}

//draws bushes, draws and updates lazy river
function foregroundstuff(){
        //bushes
    for (var i=0; i<width+30; i+= 30){
        fill(bushColors[i]);
        ellipse(i, 350, bushSizes[i]);   
    }

    //lazy river
    fill(179, 176, 143);
    rect(0, 350, width, 50);
    fill(81, 181, 201);
    rect(0, 355, width, 40);

    //lazy river inhabitants
    for (var i = 0; i < tubers.length; i++){
        if (tubers[i].x <= -30){
            var mover = tubers.shift();
            mover.x = width + 28;
            tubers.push(mover);
        }
        tubers[i].draw();
        tubers[i].x -= 0.5;
    }
}

Srauch – Project 11 – Scrolling Landscape

My code shows a scrolling New Mexico landscape, with sagebrush in the foreground, sage-covered land stretching to the mountains in the middleground, and a mountain range in the background.

sketch
//Sam Rauch, section B, srauch@andrew.cmu.edu, project
//this code creates a randomly generated scrolling new mexico landscape with sagebrush
//in the foreground, distant bushes in the middleground, and mountains in the background.
//A late afternoon moon hangs low in the sky.

//arrays for objects
var sageArray = [];
var mountainArray = [];
var backbushes = [];

function setup() {
    createCanvas(400, 200);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);
    frameRate(30);

    //fill sage array with random sagebrush
    var initsageY = random(30, 40);
    for (var i = 0; i<20; i++){
        sageArray.push(newSage(initsageY, random(160, 190)));
        initsageY += random(20, 40);
    }

    //fill mountain array with random starter mountains
    var initmountX = random(0,40);
    for (var i = 0; i < 20; i ++){
        var mont = makeMountain(initmountX, random(70, 90), random(40, 60));
        mountainArray.push(mont);
        initmountX += random(30, 40);
    }

    //fill backbushes array with random starter bushes
    var initBushX = random(0,10);
    for (var i = 0; i<100; i++){
        backbushes.push(newBush(initBushX, random(100, 150)));
        initBushX += random(0, 10);
    }
}

function draw() {
    background(129, 173, 223);
    noStroke();

    //draw moon
    var moonfill = color(235, 243, 247, 200);
    fill(moonfill);
    ellipse(300, 50, 20, 20);

    //draw middleground
    fill(111, 158, 148);
    rect(0, 100, 400, 100);

    //draw mountains, push in new mountains on right as they go off screen to left
    for (var i = 0; i < mountainArray.length; i++){
        mountainArray[i].peakX -= 0.25;
        mountainArray[i].draw();

        if (mountainArray[i].peakX <= -70){
            mountainArray.shift();
            mountainArray.push(makeMountain(random(440, 460), random(60, 90), random(40, 60)));
        }
    }

    //draw backbushes, push in new ones as go off screen
    for (var i = 0; i < backbushes.length; i++){
        backbushes[i].x -= 0.5;
        backbushes[i].draw();

        if (backbushes[i].x <= -10){
            backbushes.shift();
            backbushes.push(newBush(random(402, 420), random(100, 150)));
        }
    }

    //draw foreground
    fill(156, 127, 70);
    rect(0, 150, 400, 50);

    //draw sagebrush in front

    for (var i = 0; i < sageArray.length; i++){
    //draw each sagebrush shadow; in seperate loop so it will always draw before
    //(thus underneath) the sagebrush
        fill(117, 98, 56);
        ellipse(sageArray[i].x, sageArray[i].y, 20, 8);
    }

    for (var i = 0; i < sageArray.length; i++){
        sageArray[i].x -= 2; //move each sagebrush along to left
        sageArray[i].draw(); //draw each sagebush
    }

    if (sageArray[0].x < -10){ //if sagebrush is off the canvas, shift and push in a new one
        sageArray.shift();
        sageArray.push(newSage(random(410, 430), random(160, 190)));
    }

}

//objects for sagebrush, mountain, and backbush

function newSage(xpos,ypos){
    var sage = {x: xpos, y:ypos, draw:drawSagebrush};
    return sage;
}

function drawSagebrush(){
    stroke(66, 46, 23);
    var bushstart = this.x-10;
    for (var i = 0; i<8; i++){
        line(this.x,this.y,bushstart,this.y-15);
        bushstart += 3;
    }
    stroke(66, 110, 90);
    fill(93, 135, 111);
    ellipse(this.x-8, this.y-15, 7, 7);
    ellipse(this.x+8, this.y-15, 7, 7);
    ellipse(this.x-5, this.y-17, 8, 8);
    ellipse(this.x+5, this.y-17, 8, 8);
    ellipse(this.x,this.y-18, 10, 10);
    noStroke();
}

function makeMountain(x, y, wide){
    var mountain = {peakX: x, peakY: y, base:wide, draw: drawMountain};
    return mountain;
}

function drawMountain(){
    fill(96, 129, 181);
    beginShape();
    vertex(this.peakX, this.peakY);
    vertex(this.peakX-this.base, 100);
    vertex(this.peakX+this.base, 100);
    endShape();
}

function newBush(xpos,ypos){
    var bush = {x: xpos, y:ypos, draw: drawBush};
    return bush;
}

function drawBush(){
    strokeWeight(5);
    stroke(106, 135, 124);
    point(this.x, this.y);
    strokeWeight(1);
    noStroke();
}

Project 11

The most challenging part of this project is figuring out how to construct the different objects. Objects have to appear and disappear on the screen at a constant rate. For my animation, I drew a bunch of bunnies racing and there’s grass, trees, and the sun in the background.

sketch
//Jenny Wang
//Section B
//jiayiw3@andrew.cmu.edu
//Project 11

//image
var img;

//frame 
var frameCount = 0;

//array
var treeShow = [];
var grassShow = [];
var bunnyShow = [];

//object
var tree;
var grass;
var bunny;



//preload sun image
function preload(){
    img = loadImage("https://i.imgur.com/AZGb5wn.png")
}

function setup() {
    createCanvas(475, 300);

    //setup tree
    for(var t = 0; t < 80; t++) {
        tree = makeTree(t*10, 170);
        treeShow.push(tree);
    }

    //setup grass
    for(var g = 0; g<30; g++) {
        grass = makeGrass(g*20, 200);
        grassShow.push(grass);
    }

    //setup car
    for(var h = 0; h < 5; h++) {
        bunny = makeBunny(0, round(random(240, 260)), random(2,3));
        bunnyShow.push(bunny);
    }

}


function draw() {
    background("lightblue");

    //draw the sun
    image(img,140,-100);

    //draw tree
    updateTree();
    removeTree();
    addTree();

    //draw fence
    fill("black")
    rect(0,196,width,6);

    //draw grass
    updateGrass();
    removeGrass();
    addGrass();

    //draw bunny
    updateBunny();
    removeBunny();
    addBunny();
}



//CONSTRUCT BUNNY//
function makeBunny(bx, by, forward) {
    var bunny = {x: bx, y:by,
        speed:forward,
        r: random(100,255),
        g: random(100,255),
        b: random(100,255),
        move: bunnyMove,
        draw: drawBunny 
    }
    return bunny;
}

function drawBunny() {
    fill(this.r, this.g, this.b);
    ellipse(this.x,this.y,20,20);
    ellipse(this.x-5,this.y-10,10,20);
    ellipse(this.x+5,this.y-10,10,20);
    ellipse(this.x-10,this.y+15,40,20);
    ellipse(this.x-30,this.y+15,10,10);

    fill(0);
    ellipse(this.x+5, this.y, 4, 4);
    ellipse(this.x-5, this.y, 4, 4);

}

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

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

function removeBunny() {
    var bunnyKeep = [];
    for (var i = 0; i < bunnyShow.length; i++){
        if (bunnyShow[i].x < width) {
            bunnyKeep.push(bunnyShow[i]);
        }
    }
    bunnyShow = bunnyKeep; // remember the showing cars

}

function addBunny() {
    frameCount +=1;
    if (frameCount % 100== 0){
        bunnyShow.push(makeBunny(0, round(random(240, 260)), random(2,4)));
    }

}



//CONSTRUCT GRASS//
function makeGrass(gx, gy) {
    var grass = {x:gx, y:gy, 
        width:random(40, 70), 
        height:random(100, 300), 
        r:random(70,200), g:random(115,200), b: random(20, 100),
        speed: -0.5,
        move: grassMove,
        draw: drawGrass
    }
    return grass;
}

function drawGrass() {
    noStroke();
    fill(this.r, this.g, this.b);
    rect(this.x, this.y, this.width, this.height);
}

function updateGrass() {
    for(var g = 0; g < grassShow.length; g++) {
        grassShow[g].move();
        grassShow[g].draw();
    }
}

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

function removeGrass() {
    var grassKeep = [];
    for (var g = 0; g < grassShow.length; g++){
        if (grassShow[g].x + width > 0) {
            grassKeep.push(grassShow[g]);
        }
    }
    grassShow = grassKeep; 
}

function addGrass() {
    frameCount +=1;
    if (frameCount % 25 == 0){
        grassShow.push(makeGrass(width,200));
    }

}



//CONSTRUCT TREE//
function updateTree() {
    for(var t =0; t < treeShow.length; t++){
        treeShow[t].move();
        treeShow[t].draw();
    }

}

function removeTree(){
    var treeKeep = [];
    for (var t = 0; t < treeShow.length; t++){
        if (treeShow[t].x +80 > 0) {
            treeKeep.push(treeShow[t]);
        }
    }
    treeShow = treeKeep; 
}

function addTree() {
    frameCount +=1;
    if (frameCount % 25 == 0){
        treeShow.push(makeTree(width+80,170));
    }
}

function makeTree(tx, ty) {
    var tree = {x:tx, y:ty, 
        width:random(80, 150),  
        r:0, g:random(90,200), b: random(10, 20),
        speed: -1,
        move: treeMove,
        draw: drawtree
    }
    return tree;

}

function drawtree() {
    fill(this.r, this.g, this.b);
    ellipse(this.x, this.y, this.width);
}


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

“How Artists Can Bridge the Digital Divide and Reimagine Humanity”

By Ilia Urgen
Section B

Over the last couple of decades, the STEAM (Science, Technology, Engineering, Art, and Mathematics) movement has brought a plethora of new changes in the world’s education system. The goal of this movement is not only to improve the lives of people physically, but to also bring people closer together by changing the way we see diversity and the digital inclusion of others.

According to author Agnes Chavez, a revolution in STEAM is how we see the development of humanistic skills and creating a sustainable future. This process is even more vital in isolated, remote areas such as rural and minority communities, where the necessity to tie the gender and culture gap is even greater.

One of many possible solutions was generated through the creation of the STEMarts Lab. Students from all backgrounds get to work directly with artists whose work imagines what can be achieved with digital technology. This new form of collaboration between generations is what will lead the future in a digitally-sustainable direction.

Furthermore, the STEMarts model is revolutionizing the way the younger generation is thinking through the following pillars:

  • 21st-century skills and technology
  • Cutting-edge science knowledge
  • Real-world application and collaboration
  • New media arts and social practice

The STEMarts model is able to give people a better idea of how the world works better together with the combination of science, art, and technology. These ideas are more important now than ever before. The goal of our generation is to increase individual literacy of these fields as much as possible. The more great minds we have who are able to think critically and out of the box, the less problems our society will have. Even though this solution seems too good to be true, we’ll never know unless we try to unite these pillars by increasing STEAM literacy in our generation.

Link to Article:

https://www.arts.gov/impact/media-arts/arts-technology-scan/essays/how-artists-can-bridge-digital-divide-and-reimagine-humanity

Looking Outwards 11: Societal Impacts of Digital Art

https://www.nytimes.com/2016/12/27/magazine/finding-inspiration-for-art-in-the-betrayal-of-privacy.html

Finding Inspiration for Art in the Betrayal of Privacy

Jenna Wortham

Dec. 27, 2016

The article “Finding Inspiration for Art in the Betrayal of Privacy” by Jenna Wortham discusses topics including works of art, privacy, and data security.

The author introduces an art exhibition in Lower Manhattan and specifically lists some of the works to show how easy it is for people’s private information to be acquired and exploited unknowingly in the era of big data.

For example, information from Wifi-enabled devices passing through the gallery is gathered by eight antennas and relayed to a large screen, which shows how easy and common it is for us to be tracked.

The article acknowledges the high level of technology development and its wide range of uses, but also reminds people of the side effects brought by technology development–the cost of privacy.

In the author’s opinion, artists reflect on society through their creations, making people aware of the problems existing in society and reflect on them.

Project 11: Generative Landscape

SpongeBob SquarePants

sketch
//Xinyi Du 
//15104 Section B
//xinyidu@andrew.cmu.edu
//Project-11

//SpongBob walking gif source:
//https://www.deviantart.com/supermariospongebob/art/SB-Walkin-into-Monday-858782150
//SB Walkin' into Monday
//by supermariospongebob

//arrays for background flowers
var filenamesF = [];
var bgflowers = [];
var backgroundF = [];
//arrays for the character
var filenames = [];
var walkImage = [];
var character = [];

var buildings = [];
var leaves = [];
var flags = [];

function preload() {
    //load SpongeBob walk cycle images
    filenames[0] = "https://i.imgur.com/ulD5SOy.png";
    filenames[1] = "https://i.imgur.com/0cFmmhf.png";
    filenames[2] = "https://i.imgur.com/wmSWQHb.png";
    filenames[3] = "https://i.imgur.com/iYYLnPL.png";
    filenames[4] = "https://i.imgur.com/kFzcZXr.png";
    filenames[5] = "https://i.imgur.com/Ej0nUgn.png";
    filenames[6] = "https://i.imgur.com/wfR57hy.png";
    filenames[7] = "https://i.imgur.com/4TadbPD.png";
    filenames[8] = "https://i.imgur.com/BjVfWWi.png";
    filenames[9] = "https://i.imgur.com/vLUiotP.png";
    filenames[10] = "https://i.imgur.com/oA49LHr.png";
    filenames[11] = "https://i.imgur.com/A9TMzpP.png";
    filenames[12] = "https://i.imgur.com/NAPIs2c.png";
    for (var i = 0; i < filenames.length; i++) {
        walkImage[i] = loadImage(filenames[i]);
    }
    //load background flower images
    filenamesF[0] = "https://i.imgur.com/ZNmnfMU.png";
    filenamesF[1] = "https://i.imgur.com/o1z2jrZ.png";
    filenamesF[2] = "https://i.imgur.com/U4OwJMt.png";
    filenamesF[3] = "https://i.imgur.com/iACszh9.png";
    filenamesF[4] = "https://i.imgur.com/4eTqZLb.png";
    for (var i = 0; i < filenamesF.length; i++) {
        bgflowers[i] = loadImage(filenamesF[i]);
    }
    leaves.push(loadImage("https://i.imgur.com/8NFDDnM.png"));
    leaves.push(loadImage("https://i.imgur.com/CberjzQ.png"));
    flags.push(loadImage("https://i.imgur.com/2kTH6D6.png"));
}

//make SpongeBob
function makeSpongeBob(sx, sy) {
    var s = {x: sx, y: sy, 
             imageNum: 0,
             drawFunction: drawSpongeBob
         }
    return s;
}
function drawSpongeBob() {
    this.imageNum ++; //increase imageNum
    //if reaches the length (end) of the array (go over 10 images), start from 0 again
    if (this.imageNum == walkImage.length) { 
        this.imageNum = 0;
    }
    image(walkImage[this.imageNum], this.x, this.y, 130, 140); //draw the image
}

function setup() {
    createCanvas(480, 400); 
    frameRate(9);
    //store SpongBob andCoral images to the array character
    character.push(makeSpongeBob(180, 220));
    character.push(makeCoral(0));
    //store background flower images to the array makeBackground
    backgroundF.push(makeBackground(20, 50, 0));
    backgroundF.push(makeBackground(180, 30, 1));
    backgroundF.push(makeBackground(460, 30, 2));
    backgroundF.push(makeBackground(120, 180, 3));
    backgroundF.push(makeBackground(300, 180, 4));
    backgroundF.push(makeBackground(550, 100, 0));
    backgroundF.push(makeBackground(650, 30, 3));
    //store 4 types of buildings to the array buildings
    buildings.push(makeBuilding1(0));
    buildings.push(makeBuilding1(360));
    buildings.push(makeBuilding2(130));
    buildings.push(makeBuilding3(270));
    buildings.push(makeBuilding4(560));
}


function draw() {
    background(87,157,231); 
    //draw background flowers
    for (i = 0; i < backgroundF.length; i++) {
        backgroundF[i].update();
        backgroundF[i].display();  
    } 
    //draw the grounds and horizon lines
    fill(235,233,218);
    noStroke();
    rect(0, height*2/3, width, height/3);
    fill(80);
    rect(0, height*3/4, width, height/4);
    stroke(0);
    strokeWeight(0.7);
    line(0, height*3/4, width, height*3/4);
    line(0, height*2/3, width, height*2/3)
    //draw the buildings
    for (i = 0; i < 5; i ++) {
        buildings[i].update();
        buildings[i].drawFunction();
    }
    character[0].drawFunction(); //draw SpongBob
    character[1].drawFunction(); //draw corals
}

//make background flowers
function makeBackground(bgx, bgy, idx) {
    var bg = {x: bgx, y: bgy, index: idx, speed: -3,
                size: random(100, 180), //random starting size
                dsize: random(-6,6), //random decrease or increase size every update
                update: bgFlowerUpdate,
                display: bgFlowerDisplay
            }
    return bg;  
}
function bgFlowerUpdate() {
    this.x += this.speed; //move to the left with speed -3
    this.size += this.dsize; //increase or decrease size by dsize
    if (this.x < -width/2) { //if out of the canvas
        this.x = width; //start from the right side again
        this.size = random(80, 100); //start with random size
        this.size += this.dsize;
    }
    if (this.size >= 200 || this.size <= 30) { //if size reaches the limit 30 or 200
        this.dsize = -this.dsize; //inverse the size change direction
    }
}
function bgFlowerDisplay() {
    image(bgflowers[this.index], this.x, this.y, this.size, this.size); 
}

//Squidward Tentacles' house
function makeBuilding1(bx) { //startX is the starting X of the building
    var bg = {startX: bx, speed: -6,
              r: random(40, 150), g: random(70, 200), b: random(200, 255), //random color in cool tone
              update: updateBuilding1,
              drawFunction: drawBuilding1
            }
    return bg;
}
function drawBuilding1() {
    //structure
    var x1 = 100; var y1 = 140;
    var x2 = 150; 
    var x3 = 165; var y2 = 285;
    var x4 = 85; 
    fill(this.r+20, this.g+20, this.b+20);
    rect(this.startX+80, 180, 90, 45);
    fill(this.r, this.g, this.b);
    quad(this.startX+x1, y1, this.startX+x2, y1, this.startX+x3, y2, this.startX+x4, y2);
    fill(this.r-20, this.g-20, this.b-20);
    rect(this.startX+103, 169, 44, 11);
    quad(this.startX+120, 180, this.startX+130, 180, this.startX+138, 235, this.startX+112, 235);
    //windows
    fill(171,174,191);
    ellipse(this.startX+109, 190, 19, 20);
    ellipse(this.startX+141, 190, 19, 20);
    if (frameCount % 5 == 0) { //blink every 5 frames
        fill(21,144,177); 
    } else {
        fill(255, 250, 112);
    }
    ellipse(this.startX+109, 190, 0.6*19, 0.6*20);
    ellipse(this.startX+141, 190, 0.6*19, 0.6*20);
    //door
    fill(132, 114, 85);
    arc(this.startX+125, 255, 26, 26, PI, PI*2, OPEN);
    noStroke();
    rect(this.startX+125-13, 255, 26, 30);
    stroke(0);
    line(this.startX+125-13, 255, this.startX+125-13, 255+30);
    line(this.startX+125+13, 255, this.startX+125+13, 255+30);
    line(this.startX+125-13, 255+30, this.startX+125+13, 255+30);

}
function updateBuilding1() {
    this.startX += this.speed;
    if (this.startX < -width/3) { //if out of the canvas
        this.startX = width; //start from the right side again
    }

}
//SpongeBob's house
function makeBuilding2(bx) {
    var bg = {startX: bx, speed: -6,
              r: random(240,255), g: random(140,210), b: random(10,45), //random orange/yellow
              update: updateBuilding2,
              drawFunction: drawBuilding2
            }
    return bg;
}
function drawBuilding2() {
    fill(46, 144, 11);
    image(leaves[0], this.startX+16, 76, 200, 230); //draw leaves  
    //pineapple structure
    fill(this.r, this.g, this.b);
    arc(this.startX+125, 245.5, 100, 130, PI*3/4, PI*9/4, CHORD);
    //windows
    fill(171,174,191);
    ellipse(this.startX+109, 210, 19, 20);
    ellipse(this.startX+155, 265, 19, 20);
    if (frameCount % 8 == 0) { //blinks every 8 frames
        fill(255, 250, 112);
    } else {
        fill(21,144,177);
    }
    ellipse(this.startX+109, 210, 0.6*19, 0.6*20);
    ellipse(this.startX+155, 265, 0.6*19, 0.6*20);
    //door
    fill(171,174,191);
    strokeWeight(0.5);
    arc(this.startX+125, 260, 26, 26, PI, PI*2, OPEN);
    noStroke();
    rect(this.startX+125-13, 260, 26, 25);
    stroke(0);
    strokeWeight(0.5);
    line(this.startX+125-13, 260, this.startX+125-13, 260+25);
    line(this.startX+125+13, 260, this.startX+125+13, 260+25);
    line(this.startX+125-13, 260+25, this.startX+125+13, 260+25);
    fill(76,89,121);
    arc(this.startX+125, 260, 18, 18, PI, PI*2, OPEN);
    noStroke();
    rect(this.startX+125-9, 260, 18, 25);
    stroke(0);
    strokeWeight(0.5);
    line(this.startX+125-9, 260, this.startX+125-9, 260+25);
    line(this.startX+125+9, 260, this.startX+125+9, 260+25);
    line(this.startX+125-9, 260+25, this.startX+125+9, 260+25);
}
function updateBuilding2() {
    this.startX += this.speed;
    if (this.startX < -width/3) {
        this.startX = width;
    }

}
//Patrick Star's house
function makeBuilding3(bx) {
    var bg = {startX: bx, speed: -6,
              r: random(150,255), g: 80, b: 80, //random shades of red
              update: updateBuilding3,
              drawFunction: drawBuilding3
            }
    return bg;
}
function drawBuilding3() {
    //decoration
    strokeWeight(0.3)
    fill(248,228,156);
    rect(this.startX+125-1.5, 248, 3, 30);
    rect(this.startX+125-8, 245, 16, 3);
    //structure
    strokeWeight(0.6);
    fill(this.r, this.g, this.b);
    arc(this.startX+125, 285, 60, 60, PI, PI*2, CHORD);
}
function updateBuilding3() {
    this.startX += this.speed;
    if (this.startX < -width/2) {
        this.startX = width;
    }
}
//Krusty Krab Restaurant
function makeBuilding4(bx) {
    var bg = {startX: bx, speed: -6,
              update: updateBuilding4,
              drawFunction: drawBuilding4
            }
    return bg;
}
function drawBuilding4() {
    fill(115,95,42);
    rect(this.startX, 222, 105, 63);
    //glass windows and door
    fill(109,165,244);
    rect(this.startX, 252, 105, 33);
    //wooden structures
    fill(115,95,42);
    rect(this.startX, 215, 12, 70);
    rect(this.startX+105, 215, 12, 70);
    fill(94,74,29);
    line(this.startX-5+63, 252, this.startX-5+63, 285)
    rect(this.startX-5, 273, 40, 12);
    rect(this.startX+80, 273, 41, 12);
    rect(this.startX-5+40, 252, 40, 5);
    rect(this.startX-5+40, 252, 10, 33);
    rect(this.startX+71, 252, 11, 33);
    //load flags
    image(flags[0], this.startX+11.5, 232, 94, 20); 
}
function updateBuilding4() {
    this.startX += this.speed;
    if (this.startX < -width/3) {
        this.startX = width;
    }

}
//corals
function makeCoral(cx) {
    var s = {startX: cx, speed: -10,
             drawFunction: drawCoral
         }
    return s;
}
function drawCoral() {
    image(leaves[1], this.startX+100, 320, 60, 120); //smaller coral
    image(leaves[1], this.startX+200, 280, 100, 200); //bigger coral
    this.startX += this.speed;
    if (this.startX < -width) {
        this.startX = width*1.2;
    }
}






Project 11

//stars and sea

var stars =[]
var fish =[]

//object,flying fish 
var flyfish
var x=350
var y=200
var dx;
var c;





function setup() {
createCanvas(450, 250); 

//stars in the sky created 
    for (var i = 0; i < 7; i++){
        var rx = random(width);
        stars[i] = makeStars(rx);
    }

//fish in the ocean created
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        fish[i] = makeFish(rx);
   }
//framerate
    frameRate(10);
}




function draw() {
    background(40,50,105)

//moon in the sky spinning 
push()
translate(325,50)
stroke(255,228,181)
fill(255,228,181)
ellipse(0,0,80,80)
pop()

push()
strokeWeight(0)
translate(325,50)
rotate(frameCount / -100.0);
fill(40,50,105)
ellipse(0,15,70,70)
pop()

//the ocean 
    push();
    strokeWeight(0)
    fill(116,180,230);
    rect(0,180,width, height);
    pop();

//moving star and cloud
loadStar()
addStars()
clearStars()
//moving fish 

loadFish()
clearFish()
addFish();
}

Blog 11

There is the right for artists to claim copyright but due to the nature of the digital environment, but inevitably works will be spread through digital platforms. I think in most cases the permission and authorization of the artist come first. Especially in public occasions (for example SNS posts), the copyright owner should be given the power to either remove or directly label the work.

Similarly, an artist who uses information such as photos, voice, and private information should gain the permission of the source of the data: in other words, artworks shouldn’t do any unauthorized exploitation.


Another issue with artworks that are based less on private subjects but on a public scale is biasness. Digital networks being the core of globalization, the audience and viewers of the digital work would be more diverse. There would be a huge variety of ways for different people from different backgrounds to understand the works. Artist should be aware of this and make the effort to research/pre-educate themselves with as much culture, history, and social differences; digital artworks have the benefit of exposure but there is the responsibility to take more care in problems such as biases.

Readings:

https://www.smithsonianmag.com/smart-news/art-project-exposed-racial-biases-artificial-intelligence-system-180973207/

https://www.smithsonianmag.com/smart-news/art-project-exposed-racial-biases-artificial-intelligence-system-180973207/

Looking Outwards 11: Societal Impacts of Digital Art

Beeple’s NFT, “Everydays” sold for a whopping price of 69 million dollars to a crypto company. His piece is a piece of digital art relying on the blockchain technology to stay immutable and hold value. This is a new realm of conceptual art. Also, this type of art has a huge social impact. There are people of all ages in all professions making an insane amount of money off NFTs now and no one knows how long this can last and how reliable this is. The whole idea of NFTs rely on the authenticity and the ownership of the art. However, authenticity of digital art is conceptual and only happens when everyone believes in it. It will be interesting to see how many more people will invest in NFTs in the future and how much they will be worth in a few years.

https://www.washingtonpost.com/entertainment/museums/beeple-digital-artwork-sale-perspective/2021/03/15/6afc1540-8369-11eb-81db-b02f0398f49a_story.html