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

gondola moment

sketch
// jaden luscher
// jluscher@andrew.cmu.edu
// section a
// project 11

// this program draws a gondola ascending a mountain
// populated by random cabins on a snowy slope

var hillheight = [];
var noiseParam = 0;
var noiseStep = 0.01;
var gondola;
var house = [];   // array of houses
var newhouseProbability = 0.01; // likelihood of a new house popping up per frame

function preload() {
    gondola = loadImage("https://i.imgur.com/H4WC448.png");
    // gondola drawn in illustrator
}

function setup() {
    createCanvas(400, 400);
    frameRate(20);
    noStroke();

    // set up hill data
    for (i = 0; i <= width; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 50, 250);
        hillheight.push(value);
        noiseParam += noiseStep;
    }

    // first house
    var onehouse = makehouse();
    house.push(onehouse);
}


function draw() {
    background("orange");
    drawMoon();

    movehill();
    drawhill();
    drawslope();

    for (var i = 0; i < house.length; i++) {
        movehouse(house[i]);
        showhouse(house[i]);
    }
    if (house.length > 0 & house[0].y - house[0].rh > height) {
        // delete off-screen houses
        house.shift();
    }
    if (newhouseProbability > random(1.0)) {  // make new house randomly
        var newhouse = makehouse();
        house.push(newhouse);
    }

    push();
    stroke(100);
    strokeWeight(2);
    line(0, 260, width, 40);
    image(gondola, 170, 130, 100, 150);
    pop();
}


function showhouse(h) {  // house x, y, width, height, roof height
    push();
    fill(200, 150, 100);
    rect(h.x, h.y, h.w, h.h);
    beginShape();
    vertex(h.x - 2, h.y);
    vertex(h.x + (h.w/2), h.y - h.rh); // roof peak
    vertex(h.x + h.w + 2, h.y);
    endShape();
    fill(230, 180, 120);
    rect(h.x + h.w / 2 - 4, h.y + h.h, 8, -15); // door
    pop();
}

function movehouse(h) {
    h.x += h.dx;
    h.y += h.dy;
}


function makehouse() {
    var house = {x : width + 1,
                y : random(120, 300),
                w : random(15, 50),
                h : random(15, 50),
                rh : random(5, 20),
                dx : -1,
                dy : 0.55,
                show : showhouse}
    return house;
}


function movehill() {
    hillheight.shift();   // creates scrolling effect
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 50, 250);
    hillheight.push(value);
    noiseParam += noiseStep;
}

// background hills
function drawhill() {
    push();
    fill("lightblue")
    beginShape();
    for (var i = 0; i < width +1; i++) {
        var x = i;
        vertex(x, hillheight[i]);
    }
    vertex(width, height);
    vertex(0, height);
    endShape(CLOSE);
    pop();
}

// foreground white slope
function drawslope() {
    push();
    fill(250);
    beginShape();
    vertex(width, height);
    vertex(0, height);
    vertex(0, 370);
    vertex(width, 150);
    endShape();
    pop();
}

function drawMoon() {
    fill(250);
    ellipse(100, 80, 50, 50);
    fill("orange");
    ellipse(105, 80, 45, 45);
}

Project 11: Winter Scroll

sketch

//Name: Hari Vardhan Sampath
//Section: E
//eMail address: harivars@andrew.cmu.edu
//Project-11

var snowForeground = []; // array of snow particles in the foreground
var snowBackground = []; // array of snow particles in the background
var snowAmountForeground = 500;
var snowAmountBackground = 750;
var snowSize = 3;
var snowLayers = 3;

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

    for (i = 0; i < snowAmountForeground; i++) {
        snowForeground[i] = new Object();
        snowForeground[i].x = random(width);
        snowForeground[i].y = random(height);
        snowForeground[i].dy = random(0.25, 1);
        snowForeground[i].c = color(random(200, 255));
    }

    for (i = 0; i < snowAmountBackground; i++) {
        snowBackground[i] = new Object();
        snowBackground[i].x = random(width);
        snowBackground[i].y = random(height);
        snowBackground[i].dy = random(0.25, 1);
        snowBackground[i].c = color(random(200, 255));
    }
}

// update position and draw each of 100 rectangles
function draw() {
    // background sky gradient
    for (var i = 0; i < height; i++) {
        // 
        var c1 = color(0, 20, 52);
        var c2 = color(0, 71, 126);
        // 
        var gradient = map(i, 0, height, 0, 1);
        var c = lerpColor(c1, c2, gradient);
        stroke(c);
        line(0, i, width, i);
    }

    // snow falling in the background
    noStroke();
    for (i = 0; i < snowAmountBackground; i++) {
        drawSnowBackground(snowBackground[i]);
        updateSnowBackground(snowBackground[i]);
    }

    // layers of winter forest
    forest();

    // snow falling in the foreground
    noStroke();
    for (i = 0; i < snowAmountForeground; i++) {
        drawSnowForeground(snowForeground[i]);
        updateSnowForeground(snowForeground[i]);
    }
}

function forest() {
    foliage0 = 0.06;
    foliage1 = 0.04;
    foliage2 = 0.02;
    foliage3 = 0.01;
    foliageSpeed0 = 0.001;
    foliageSpeed1 = 0.002;
    foliageSpeed2 = 0.003;
    foliageSpeed3 = 0.004;

    stroke(163, 196, 217);
    beginShape();
    for (var i = 0; i < width; i++) {
        var t0 = (i * foliage0) + (millis() * foliageSpeed0);
        var y0 = map(noise(t0), 0, 1, 200, 5);
        line(i, y0, i, height);
    }
    endShape();

    stroke(117, 163, 191);
    beginShape();
    for (var i = 0; i < width; i++) {
        var t1 = (i * foliage1) + (millis() * foliageSpeed1);
        var y1 = map(noise(t1), 0, 1, 250, 6);
        line(i, y1, i, height);
    }
    endShape();

    stroke(70, 113, 140);
    beginShape();
    for (var i = 0; i < width; i++) {
        var t2 = (i * foliage2) + (millis() * foliageSpeed2);
        var y2 = map(noise(t2), 0, 1, 275, 7);
        line(i, y2, i, height);
    }
    endShape();

    stroke(30, 51, 64);
    beginShape();
    for (var i = 0; i < width; i++) {
        var t3 = (i * foliage3) + (millis() * foliageSpeed2);
        var y3 = map(noise(t3), 0, 1, 300, 8);
        line(i, y3, i, height);
    }
    endShape();
}

function drawSnowForeground(s) {
    fill(s.c);
    circle(s.x, s.y, 2);
}

function updateSnowForeground(s) {
        s.y += s.dy;
        if (s.y > height) {
        s.y = 0;
        }
        else if (s.y < 0) {
            s.y = height;       
        }
}

function drawSnowBackground(s) {
    fill(s.c);
    circle(s.x, s.y, random(0.5,1.5));
}

function updateSnowBackground(s) {
        s.y += s.dy;
        if (s.y > height) {
        s.y = 0;
        }
        else if (s.y < 0) {
            s.y = height;       
        }
}


Train’s window
Credits: https://www.journeyb.com/2019/10/journeybasket-short-history-indian-railways-book-photos.html

Srishty’s Project 11

The Sushi Bar Train

For my project I decided to create a restaurant on a train that serves japanese food via a conveyer belt. The dishes include: sashimi, tuna sushi, matcha, miso soup, ramen, and salmon. In the window of the train booth, you can watch as you travel through a bright city at night.

Sushi Bar TrainDownload

// SRISHTY BHAVSAR 
// 15104 SECTION C
//PROJECT 11

var buildings = [];

var fd = [] // 

// food items
var ramen; // https://imgur.com/H2R30Wg
var miso; // https://imgur.com/J5EhmuM
var salmon; // https://imgur.com/p6YrdLv
var sashimi;  // https://imgur.com/mJjnmVD
var matcha; // https://imgur.com/SErtIMf
var tunasushi; // https://imgur.com/HCUsYNh
var maki; // https://imgur.com/UI5eghR

var food = 
["https://i.imgur.com/H2R30Wg.png", "https://i.imgur.com/J5EhmuM.png", 
 "https://i.imgur.com/p6YrdLv.png", "https://i.imgur.com/mJjnmVD.png", 
 "https://i.imgur.com/SErtIMf.png" , "https://i.imgur.com/HCUsYNh.png", 
 "https://i.imgur.com/UI5eghR.png"]; // food contains the images of ramen,miso,salmon,etc.


function preload() {

    seats = loadImage("https://i.imgur.com/UEAssld.png");


    ramen = loadImage(food[0]); //ramen
    miso = loadImage(food[1]); //miso
    salmon = loadImage(food[2]); // salmon
    sashimi = loadImage(food[3]); //sashimi
    matcha = loadImage(food[4]); //matcha
    tunasushi = loadImage(food[5]); //tunasushi
    maki = loadImage(food[6]); //maki



    bg = loadImage("https://i.imgur.com/2zjN6qS.png");

}

function setup() {
    createCanvas(480, 480);
    background(220);
    imageMode(CENTER);
    frameRate(17);

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


    // collection of dishes
    var dist = 0;
    for (var i = 0; i <500; i++) {
        fd[i] = makeFood(dist);
        dist += 150; //distance between dishes
    }
    print(fd);

}

function draw() {
    createCanvas(480, 480);
    background(25,25,112);


    //buildings
    push();
    translate(0,-120);
    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 
    pop();

    //bg
    image(bg, 266.4269, 240, 532.8539, 480);

    showFood();

    //seats
    image(seats,240,408.3845,480,143.231);




}


function makeFood(xloc){
    var fd = { x: xloc,
                speedx: 1.5,
                move: foodMove, 
                food : random([ramen, miso, salmon, sashimi, matcha, tunasushi, maki]),
                display: foodDisplay,
                }
    return fd;
}


function foodDisplay(){

    /*the width heights and y location are respective to the 
    ones mapped out on adobe illustrator. thats why they are typed manually */
    //xloc is the speed times 500 and the dist
    if (this.food == ramen){
        image(ramen,this.x -750*20, 310, 148, 108 );  // ramen
    }
    if (this.food == miso){
        image(miso,this.x  -750*20, 310, 119, 115 ); // miso
    }
    if (this.food == salmon){
        image(salmon,this.x -750*20, 318, 174, 126 ); // salmon
    }
    if (this.food == sashimi){
        image(sashimi,this.x -750*20, 309, 203, 147 ); //sashimi
    }
    if (this.food == matcha){
        image(matcha,this.x - 750*20, 324, 119, 86 ); // matcha
    }
    if (this.food == tunasushi){
        image(tunasushi,this.x  -750*20, 318, 164, 119); //tuna
    }
    if (this.food == maki){
        image(maki,this.x  -750*20, 294, 247, 179 ); //maki
    }
}

//speed of moving food
function foodMove() {
    this.x += this.speedx;  
}

//calling show and move function of dishes
function showFood(){
    for( var i = 0; i < fd.length; i++ ) {
        fd[i].display();
        fd[i].move();
        if ( i == fd.length){
            textSize(15);
            text('Sushi Bar closed. No more food for today!', 100, 200);
        }
    }

}



function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 30,
                speed: -1.0,
                nFloors: round(random(2,8)),
                move: buildingMove,
                color: color(random(255),random(255), random(255), 80), // random color buildings with low opacity to look distant
                display: buildingDisplay
            } 
    return bldg;
}


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


function removeBuildingsThatHaveSlippedOutOfView(){

    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep; // remember the surviving buildings
}


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


// method to update position of building every frame
function buildingMove() {
    this.x += this.speed;
}
    

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



Project 11 – Generative Landscape

I combined handdrawn assets from a previous project with walking sprite from Assignment 9 to create a scene of a person walking outside. The sketchy ‘handdrawn’ aesthetic of the assets combined with the layers scrolling at different speeds to create a sense of parallax. Occasionally, another character will pass by between the layer behind the main character.

sketch
var walkImage = [];   // an array to store the images
var character;

var fgElem = [];
var mgElem = [];
var bgElem = [];
var pgElem = [];

var fg = [];
var mg = [];
var bg = [];
var pg = [];

function preload(){
    // walk cycle
    walkImage[0] = loadImage("https://imgur.com/8HlL26L");
    walkImage[1] = loadImage("https://imgur.com/VLCqhEO");
    walkImage[2] = loadImage("https://imgur.com/6rAVlb8");
    walkImage[3] = loadImage("https://imgur.com/2VRJjQ6");
    walkImage[4] = loadImage("https://imgur.com/zFCNtnG");
    walkImage[5] = loadImage("https://imgur.com/AnyR09P");
    walkImage[6] = loadImage("https://imgur.com/PMB0qDG");
    walkImage[7] = loadImage("https://imgur.com/CiQWgmP");




    //loading foreground
    fgElem[0] = loadImage("https://imgur.com/RUYNCQT");
    fgElem[1] = loadImage("https://imgur.com/UaNr8wZ");
    fgElem[2] = loadImage("https://imgur.com/LsfvMCm");
    fgElem[3] = loadImage("https://imgur.com/GRwR31R");
    fgElem[4] = loadImage("https://imgur.com/xQtPjEQ");
    fgElem[5] = loadImage("https://imgur.com/cTUW62y");
    fgElem[6] = loadImage("https://imgur.com/cY58wgx");


    //loading midground
    mgElem[0] = loadImage("https://imgur.com/lal5lq9");
    mgElem[1] = loadImage("https://imgur.com/c5fb0jp");
    mgElem[2] = loadImage("https://imgur.com/kKwofLH");
    mgElem[3] = loadImage("https://imgur.com/iN2MTZN");
    mgElem[4] = loadImage("https://imgur.com/QclBuA8");
    mgElem[5] = loadImage("https://imgur.com/IAaQ7Ta");
    mgElem[6] = loadImage("https://imgur.com/g3xh1GG");
    mgElem[7] = loadImage("https://imgur.com/LWmOUjc");
    mgElem[8] = loadImage("https://imgur.com/xSvimmS");

    //loading background
    bgElem[0]= loadImage("https://imgur.com/8MNPtj6");
    bgElem[1]= loadImage("https://imgur.com/4bjqW3c");
    bgElem[2]= loadImage("https://imgur.com/q7xaqWr");
    bgElem[3]= loadImage("https://imgur.com/gEnWbVW");
    bgElem[4]= loadImage("https://imgur.com/0yBIPM8");
    bgElem[5]= loadImage("https://imgur.com/6TYtEHn");

    //loading clouds
    pgElem[0] = loadImage("https://imgur.com/pdXo0gP");
    pgElem[1] = loadImage("https://imgur.com/ohLIq5A");
    pgElem[2] = loadImage("https://imgur.com/I9uzjJC");
    pgElem[3] = loadImage("https://imgur.com/JYXlm2v");
}


function setup() {
    createCanvas(400, 400);
    background(202, 240, 248);
    frameRate(12);
    imageMode(CENTER);
    character = makeCharacter(width/4, height*0.62, 0, 0);
    surpriseChar = makeCharacter(-width*2.5, height*0.62, -5.5, 0);

    var rand = 27;
    //loading foreground
    var x1 = random(1, width/4);
    for (var i = 0; i<rand; i++){
        var envChar = makeCharacter(x1, height*(0.63), 5.5, 0);
        envChar.imageNum = int(random(0, fgElem.length));
        x1 += random(width/(rand), (2*width)/rand);
        fg.push(envChar);
    }

     //loading midground
     var rand2 = 20;
     var x2 = random(1, width);
     for (var i = 0; i<rand2; i++){
         var envChar = makeCharacter(x2, height*(0.59), 2.5, 0);
         envChar.imageNum = int(random(0, mgElem.length));
         envChar.size = random(0.1, 0.17);
         mg.push(envChar);
         x2 += random(width/4, width/2);
     }

    //loading background
    var rand3 = 10;
    var x3 = random(1, width);
    for (var i = 0; i<rand3; i++){
        var envChar = makeCharacter(x3, height*(0.4), 1, 0);
        envChar.imageNum = int(random(0, bgElem.length));
        x3 += random(width/6, width/3);
       
        bg.push(envChar);
    }

    //loading clouds
    var rand4 = 4;
    var x4 = random(1, width*(2/3));
    for (var i = 0; i<rand4; i++){
        var y = random(height*0.05, height*0.4);
        
        var envChar = makeCharacter(x4, y, 0.2, 0);
        envChar.imageNum = int(random(0, pgElem.length));
        envChar.size = random(0.1, 0.2);
        pg.push(envChar);
        x4 += random(width/3, width/2);
    }
}


function draw() {
    background(190, 225, 230);
    push();
    noStroke();
    
    ellipseMode(CENTER);
    fill(246, 241, 209, 90);
    circle(width*0.75, height*0.17, width*0.27);
    
    fill(244, 222, 44, 70);
    circle(width*0.75, height*0.17, width*0.22);
    fill(244, 222, 44, 120);
    circle(width*0.75, height*0.17, width*0.17);
    fill(243, 222, 44);
    circle(width*0.75, height*0.17, width*0.12);
    pop();

    updateArray(pg, pgElem);
    for (var i = 0; i<pg.length; i++){
        pg[i].drawFunction(pgElem); 
        pg[i].moveFunction(pgElem);
        
    }  

    updateArray(bg, bgElem);
    for (var i = 0; i < bg.length; i++){
        bg[i].drawFunction(bgElem);
        bg[i].moveFunction(bgElem);
    }

    surpriseChar.drawFunction(walkImage);
    surpriseChar.stepFunction(walkImage);
    surpriseChar.moveFunction();
    


    updateArray(mg, mgElem);
    for (var i = 0; i < mg.length; i++){
        mg[i].drawFunction(mgElem);   
        mg[i].moveFunction(mgElem);
        
    }

    character.drawFunction(walkImage);
    character.stepFunction(walkImage);
    

    updateArray(fg, fgElem);
    for (var i = 0; i<fg.length; i++){
        fg[i].drawFunction(fgElem); 
        fg[i].moveFunction(fgElem);
        
    }  

    push();
    noStroke();
    fill(226, 208, 180);
    rect(0, height*0.74, width, height);
    pop();
}


// Constructor for each walking character
function makeCharacter(cx, cy, cdx, cdy) {
    var c = {x: cx, y: cy, dx: cdx, dy: cdy,
             walkingRight: true, 
             imageNum: 0,
             stepFunction: stepCharacter,
             drawFunction: drawCharacter,
             moveFunction: moveCharacter
         }
    return c;
}

function stepCharacter(images){
    this.imageNum ++;
    this.imageNum = this.imageNum % images.length;
}

function moveCharacter(){
    this.x -= this.dx;
    if (this == surpriseChar & this.x > 200){
        this.x = -width;
    }
}

function drawCharacter(images){
    if (images == fgElem){
        push();
        translate(this.x, this.y);
        scale(0.1);
        image(images[this.imageNum], this.x, this.y);
        pop();
    } else if (images == bgElem){
        push();
        translate(this.x, this.y);
        scale(0.19);
        image(images[this.imageNum], this.x, this.y);
        pop();
    } else if (images == mgElem){
        push();
        translate(this.x, this.y);
        scale(0.18);
        image(images[this.imageNum], this.x, this.y);
        pop();
    } else if (images == pgElem){
        push();
        translate(this.x, this.y);
        scale(this.size);
        image(images[this.imageNum], this.x, this.y);
        pop();
    } else {
        if (this == surpriseChar){
            push();
            scale(-1, 1);
            image(images[this.imageNum], this.x, this.y);
            pop();
        } else {
            image(images[this.imageNum], this.x, this.y);
        }
    }
}

function updateArray(array, source){
    for (var i = 0; i < array.length; i++){
        elem = array[i];
        if ((source == fgElem & elem.x < -10)||
            (source != fgElem && elem.x < -100)){
            elem.x = width + random(width/4, width);
            elem.imageNum = int(random(0, source.length));
        }
    }
}





project 11: landscape

midnight stroll
// isis berymon section D

var buildings = [];
var stars = [];
var streetlights = [];
var ground = 160;

function setup() {
    createCanvas(480, 200);
    frameRate(10);

    //initial scene
    for(var i =0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    for(var i=0; i< 30; i++){
        var rx = random(width);
        stars[i] = makeStar(rx);
    }
    for(var i = 0; i<3; i++){
        var rx = random(width);
        streetlights[i] = makeLight(rx);
    }
}

function draw() {
    background(81, 61, 128); //dark purple sky
    showScene();
    updateScene();
    //dark grey road
    fill(84);
    noStroke();
    rect(0, ground, width, height-ground);
}

function showScene(){ //draw and move all objects
    //show stars
    for(var i =0; i< stars.length; i++){
        stars[i].move();
        stars[i].draw();
    }
    //show buildings
    for(var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].draw();
    }
    //show streetlights
    for(var i= 0; i < streetlights.length; i++){
        streetlights[i].move();
        streetlights[i].draw();
    }
}

function updateScene(){ //remove and add to arrays
    //remove stars offscren
    var keepstar = [];
    for(var i = 0; i < stars.length; i++){
        if(stars[i].x + 3 > 0){
            keepstar.push(stars[i]);
        }
    }
    stars = keepstar;
    //add new stars randomly
    var nstr = .1;
    if(random(1) < nstr){
        stars.push(makeStar(width+3));
    }
    //remove buildings offscreen
    var keepbldg = [];
    for(var i = 0; i < buildings.length; i++){
        if(buildings[i].x + buildings[i].bw > 0){
            keepbldg.push(buildings[i]);
        }
    }
    buildings = keepbldg;
    //add new buildings randomly
    var nbldg = .03;
    if(random(1) < nbldg){
        buildings.push(makeBuilding(width));
    }
    //remove lights offscreen
    var keeplight = [];
    for(var i = 0; i < streetlights.length; i++){
        if(streetlights[i].x + 15 > 0){
            keeplight.push(streetlights[i]);
        }
    }
    streetlights = keeplight;
    //add new lights randomly
    var nlight = .005;
    if(random(1) < nlight){
        streetlights.push(makeLight(width));
    }
}

function makeStar(sx){ //star object constructor
    var star = {x: sx,
                y: random(ground),
                speed: -.7,
                move: moveLeft,
                draw: drawS}
    return star;
}

function drawS(){ //white star
    stroke(255);
    line(this.x, this.y-3, this.x, this.y+3);
    line(this.x-3, this.y, this.x+3, this.y);
}

function makeBuilding(bx){ //building object constructor
    var bldg = {x: bx,
                bw: round(random(50, 100)),
                bh: round(random(30, 120)),
                speed: -2,
                move: moveLeft,
                draw: drawB}
    return bldg;
}

function drawB(){
    fill(32, 27, 43); //dark purple grey building
    noStroke();
    rect(this.x, ground-this.bh, this.bw, this.bh);
    fill(95, 86, 115); //light purple grey shading
    rect(this.x, ground-this.bh, 6, this.bh);
    rect(this.x, ground-this.bh, this.bw, 3);
}

function makeLight(lx){
    var light = {x: lx,
                    speed: -2,
                    move: moveLeft,
                    draw: drawL}
    return light; //light object constructor
}

function drawL(){
    fill(112); //mid grey
    rect(this.x, 130, 5, 30);
    //flickering lights
    if(random(1) > .8){
        fill(237, 196, 114); //yellow
    } else {
        fill(122);
    }
    rect(this.x+5, 130, 10, 5); //grey streetlight with flickering light
}

function moveLeft(){ //move left every frame
    this.x += this.speed;
}

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






looking outwards 11

https://www.vice.com/en/article/4x4p43/6-art-projects-prying-the-lid-off-online-privacy

I chose the article showcasing 6 Art Projects Prying The Lid Off Online Privacy. I think vice did a good job of curating art pieces to showcase, and they referenced a good south park episode as well which I appreciated. The first piece was a browser extension that sets off an alarm everytime information gets sent to google called the google alarm. I think that’s pretty clever and is an interesting check in for when the system is keeping an eye on you, which is always. The other project that stood out to me was called My Little Privacy by Niklas Roy. He created a motorized curtain that covered a small portion of his street window display, and tracked people as they walked by. I thought it was an interesting metaphor, the idea of false privacy in the modern era. I mostly like the personality it has, it looks like it would be a lot of fun to pass by and it somewhat takes on a life of its own.

Project 11- Landscape

Graham Murtha

Section A

For this project I wanted to make a boat move through a fiery landscape, like the final world in Mario or Mustafar from Star Wars. I made moving embers, meteors, and randomly generated spires in the background to illustrate this volcanic landscape.

sketch
//Graham Murtha
//Section A
//gmurtha@andrew.cmu.edu
//Project 11- moving landscape

// A fire Nation boat sails through Mustafar AND world 8 of Mario - so many universes in one!

var embers = [];
var spire = [];
var meteors = [];

var ship; // fire nation ship from Avatar lol- it seemed to fit the color scheme, and is steam powered

function preload(){ // input boat image
    ship = loadImage("https://i.imgur.com/v5MzkRY.png");
}

function setup() {
    createCanvas(450, 300);
    frameRate(10);

    //initial embers in the sky
    for(var i = 0; i < 6; i++){
        var sx = random(width);
        embers[i] = makeEmber(sx);
    }//initial spires
    for(var i = 0; i < 10; i++){
        var sx = random(width);
        spire[i] = makeSpire(sx);
    }
    //random meteors
    for(var i = 0; i < 1; i++){
        var sx = random(width);
        meteors[i] = makeMeteors(sx);
    }

}

function draw() {
    //fiery sky
    background(200, 100, 0); //mid-tone neutral orange

    // generates sequence of random embers slowly panning left
    updateAndDisplayEmber();
    removeEmberOutOfView();
    addNewEmber();

    // generates sequence of random meteors quickly panning left
    updateAndDisplayMeteors();
    removeMeteorsOutOfView();
    addNewMeteors();

    // generates sequence of random spires quickly panning left
    updateAndDisplaySpire();
    removeSpireOutOfView();
    addNewSpire();

    //water
    fill(120,70,30); // darker orange- reflects sky a bit
    noStroke();
    rect(0, 230, 500, 75);

    //ship stays stagnant, but as its surroundings move left it seems to move right
    image(ship, width/2 - 200, 180, 200, 100);

}

//Ember object
function makeEmber(emberLocationX){
    var ember = {x : emberLocationX,
                y : random(0, 170),
                emberScale : random(0.5, 2.5),
                speed : -1,
                move : moveEmber,
                display : displayEmber}
        return ember;
}

function displayEmber(){
    push();
    translate(this.x, this.y);
    fill('gold');
    noStroke();
    scale(this.emberScale);
    ellipse(0,0,5,5);
    pop();
}

//recoordinates ember positions and display
function updateAndDisplayEmber(){
    for(var i = 0; i < embers.length; i++){
        embers[i].move();
        embers[i].display();
    }
}

function addNewEmber(){
    var newEmberProbability = 0.01;  // controls scarcity of embers in background 
    if (random(0, 1) < newEmberProbability){
        embers.push(makeEmber(width));
    }
}

function removeEmberOutOfView (){
    //if ember dissappears on the left, remove it from the array
    var embersToKeep = [];
    for (var i = 0; i < embers.length; i++){
        if (embers[i].x + 50 > 0) {
            embersToKeep.push(embers[i]);
        }
    }
    //embers left
    embers = embersToKeep;
}

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


//Spire object
function makeSpire(spireLocationX){
    var spire = {xt : spireLocationX,
                yt : 240,
                spireScale : random(0.1, 0.5),
                spireColor : color(random(20,80),0, 0),
                speedT : -6,
                moveT : moveSpire,
                displayT : displaySpire}
    return spire;
}

function displaySpire(){
    push();
    translate(this.xt + 60, this.yt); //add 60 so transitions onto screen
    noStroke();
    scale(this.spireScale);
    
    //Spire defining shape
    noStroke();
    fill(this.spireColor);
    beginShape();
    vertex(-80,-10);
    vertex(80,-10);
    vertex(10,-200);
    vertex(40,-250);
    vertex(0,-300);
    vertex(-40,-250);
    vertex(-10,-200);
    endShape();

    pop();
}

//update spire positions and display
function updateAndDisplaySpire(){
    for(var i = 0; i < spire.length; i++){
        spire[i].moveT();
        spire[i].displayT();
    }
}

function addNewSpire(){
    var newSpireProbability = 0.04; // controls scarcity of rock spires 
    if (random(0, 1) < newSpireProbability){
        spire.push(makeSpire(width));
    }
}

function removeSpireOutOfView (){
    //if ember dissappears on the left, remove it from the array
    var spireToKeep = [];
    for (var i = 0; i < spire.length; i++){
        if (spire[i].xt + 100 > 0) {
            spireToKeep.push(spire[i]);
        }
    }
    //spires left
    spire = spireToKeep;
}

function moveSpire(){
    this.xt += this.speedT;
}



//meteors object
function makeMeteors(locationX){
    var meteors = {xs : locationX,
                ys : random(75, 125),
                meteorsScale : random(0.5, 3),
                speedS : -13,
                moveS : moveMeteors,
                displayS : displayMeteors}
    return meteors;
}

function displayMeteors(){
    push();
    translate(this.xs + 80, this.ys); //adds 80 transitions on screen
    fill("gold");
    noStroke();
    scale(this.meteorScale);
    
    //meteor
    fill('orange');
    triangle(0,6,0,-6,50,0)
    fill(40,20,20)
    ellipse(0,0,20,20);
    fill('orange');
    ellipse(1,2,3,3);
    ellipse(3,6,3,3);
    ellipse(-4,-6,3,3);

    pop();
}

//update Spire positions and display
function updateAndDisplayMeteors(){
    for(var i = 0; i < meteors.length; i++){
        meteors[i].moveS();
        meteors[i].displayS();
    }
}

function addNewMeteors(){
    var newMeteorsProbability = 0.01; // controls scarcity of meteors
    if (random(0, 1) < newMeteorsProbability){
        meteors.push(makeMeteors(width));
    }
}

function removeMeteorsOutOfView (){
    //if ember dissappears on the left, remove it from the array
    var meteorsToKeep = [];
    for (var i = 0; i < meteors.length; i++){
        if (meteors[i].xs + 100 > 0) {
            meteorsToKeep.push(meteors[i]);
        }
    }
    //Spires left
    meteors = meteorsToKeep;
}

function moveMeteors(){
    this.xs += this.speedS;
}