Project 11- Generative Landscape

sketchDownload
//Jessie Chen
//D
//Project 11
//Generative Landscape

var kiki = [];
var stars = [];
var clouds = [];
var animation = 0;

function preload() {
    //loads kiki animation frames
    var kikiFrames = [];
    kikiFrames[0] = "https://i.imgur.com/LxKITCM.png";
    kikiFrames[1] = "https://i.imgur.com/535FqDb.png";

    for (var i = 0; i < kikiFrames.length; i++) {
        kiki[i] = loadImage(kikiFrames[i]);
    }
}


function setup() {
    createCanvas(400, 300);
    imageMode(CENTER);
    frameRate(5);
    noStroke();

    //create an initial collection of stars
    for (var i = 0; i < 10; i++) {
        var rx = random(width);
        var ry = random(height)
        stars[i] = makeStars(rx, ry);
    }

    //creates an initial collection of clouds
    for (var i = 0; i < 10; i++) {
        var rx = random(width);
        var ry = random(height);
        clouds[i] = makeClouds(rx, ry);
    }
}

function draw() {
    background(39, 36, 55);

    //draws the moon
    fill(233, 220, 152);
    ellipse(200, 150, 200, 200);


    updateStars();
    removeStars();
    addNewStars();

    updateClouds();
    removeClouds();
    addNewClouds();

    //plays kiki animation
    image(kiki[animation%kiki.length], 200, 150, 270, 200);
    animation ++;
}

//update positions
function updateStars() {
    for (var i = 0; i < stars.length; i++) {
        stars[i].move();
        stars[i].display();
    }
}

//remove stars that have gone off canvas
function removeStars() {
    var starsToKeep = [];
    for (var i = 0; i < stars.length; i++) {
        if (stars[i].x < width) {
            starsToKeep.push(stars[i]);
        }
    }
    stars = starsToKeep;
}
//add new stars from the left
function addNewStars() {
    var newStarLikelihood = 0.05; 
    if (random(0,1) < newStarLikelihood) {
        stars.push(makeStars(-10, random(0, height)));
    }
}

//stars move to the right
function starsMove() {
    this.x += this.speed;
}

//draws stars
function starsDisplay() {
    fill(233, 220, 152, 100);
    ellipse(this.x, this.y, this.size + 10);
    fill(233, 220, 152)
    ellipse(this.x, this.y, this.size);
}

//stars object
function makeStars(startX, startY) {
    var star = {x: startX,
                y: startY,
                speed: 0.5,
                size: random(2, 5),
                move: starsMove,
                display: starsDisplay}
    return star;
}

//update positions
function updateClouds() {
    for (var i = 0; i < clouds.length; i++) {
        clouds[i].move();
        clouds[i].display();
    }
}

//remove clouds that have gone off canvas
function removeClouds() {
    var cloudToKeep = [];
    for (var i = 0; i < clouds.length; i++) {
        if (clouds[i].x < width + 100) {
            cloudToKeep.push(clouds[i]);
        }
    }
    clouds = cloudToKeep;
}

//add new clouds from the left
function addNewClouds() {
    var newCloudLikelihood = 0.05; 
    if (random(0,1) < newCloudLikelihood) {
        clouds.push(makeClouds(-100, random(0, height)));
    }
}

//clouds move to the right
function cloudsMove() {
    this.x += this.speed;
}

//draws clouds
function cloudsDisplay() {
    fill(102, 94, 110, 60);
    noStroke();
    arc(this.x, this.y, 25 * this.size, 20 * this.size, PI + TWO_PI, TWO_PI);
    arc(this.x + 10, this.y, 25 * this.size, 45 * this.size, PI + TWO_PI, TWO_PI);
    arc(this.x + 25, this.y, 25 * this.size, 35 * this.size, PI + TWO_PI, TWO_PI);
    arc(this.x + 40, this.y, 30 * this.size, 20 * this.size, PI + TWO_PI, TWO_PI);
}

//clouds object
function makeClouds(startX, startY) {
    var cloud = {x: startX,
                y: startY,
                speed: 2,
                size: random(0, 8),
                move: cloudsMove,
                display: cloudsDisplay}
    return cloud;
}

This was inspired by Kiki’s Delivery Service by Studio Ghibli. I used Procreate to draw out the animation frames of Kiki and imported them to my code to create a little animation. I was reminded of this scene where she flew on her broom at night, so I decided to base the project on that. As she flies through the sky, accompanied by her cat, Jiji, she moves through clouds and passes stars.

This is my sketch on Procreate.

Project: 11

I really enjoyed creating this even though it took me a while to understand objects, I feel the birds and pagoda along with the colour tones were extremely soothing!

sketch

//Aadya BHartia
//Section A 
//abhartia@andrew.cmu.edu

/* the program shows a river and mountains as well as pagodas, the birds and pagodas along with the 
variation in landscape help the visuals become more interesting and dynamic */

//variables to store colurs
var c1;
var c2;
//storing birds in an array 
var birds = [];
//pagoda in an array
var pagodas = [];
//water speed
var waterSpeed = 0.0001;

function setup() {
    createCanvas(400, 400);
    c1 = color(218, 239, 252);
    c2 = color(240, 198, 196);
    frameRate(15);
    //create an initial collection of birds
    for(var i = 0; i<5; i++){
    	var birdX = random(width);
    	var birdY = random(0, height/3);
    	birds[i] = drawBird(birdX, birdY);
    }
    //create an initial collection of pagodas 
    for(var k = 0; k<2; k++){
    	var pagodaX = random(width);
    	var pagodaY = random(250, 300); 
    	pagodas[k] = drawPagoda(pagodaX, pagodaY);
    }
}

function draw() {
	gradient(c1, c2);
	drawMountain2(); //background mountains 
	drawMountain();//foreground mountains 
	//pagoda update functions 
	pagodaUpdate();
	pagodaAppear();
	pagodaDisappear();
	//water level
	drawWater();
	drawWater2();
	//birds in the sky
	birdUpdate();
	birdAppear();
	birdDisappear();
}

//background gradient from blue to light orange 
function gradient(c1,c2){
	noFill();
	noStroke();
	for(var i = 0; i<height; i++){
		var a = map(i, 0, height, 0, 1);
		var c = lerpColor(c1,c2,a);
		stroke(c);
		line(0, i, width, i);	
	}
}
//function to display water in foreground 
function drawWater(){
	var water1 = 0.001;
	var speedW1 = 0.0003;
	noStroke();
	fill(189, 210, 222);
	beginShape();
	for(var i = 0; i<width; i++){
		var x = i*water1 + millis()*speedW1;
		var y = map(noise(x), 0, 1, 260, 300);
		vertex(i, y);
	}
	vertex(width, height);
	vertex(0, height);
	endShape();
}
function drawWater2(){
	//function to display second shade water in foreground  
	var water2 = 0.001;
	var speedW2 = 0.0001;
	fill(163, 198, 218);
	beginShape();
	for(var i = 0; i<width; i++){
		var x = i*water2 + millis()*speedW2;
		var y = map(noise(x), 0, 1, 290, 350);
		vertex(i, y);
	}
	vertex(width, height);
	vertex(0, height);
	endShape();
}
function drawMountain(){
	var mount1 = 0.014;
	var speedM1 = 0.0008;
	//foreground mountain
	stroke(249, 224, 226); 
	beginShape();
	for(var i = 0; i<width; i++){
		var x = i*mount1 + millis()*speedM1;
		var y = map(noise(x), 0,1.5,height/6, height);
		line(i, y, i, height);
	}
	endShape(); 
	//shading for foreground mountain 
	for(var k = width/2; k<4*width/5; k++){
		var z = map(k, width/2,4*width/5,0, 255);
		stroke(246, 188, 192,z);
		line(0, k, width, k);
	}
}
function drawMountain2(){
	var mount2 = 0.009;
	var speedM2 = 0.001;
	//background mountain
	stroke(246, 188, 192); 
	beginShape();
	for(var i = 0; i<width; i++){
		var x = i*mount2 + millis()*speedM2;
		var y = map(noise(x), 0,1.5,20, 2*height/3);
		line(i, y, i, height);
	}
	endShape();
	//shading for background mountain	
	for(var k = width/4; k<2*width/3; k++){
		var z = map(k, width/4,2*width/3,0, 255);
		stroke(249, 224, 226,z);
		line(0, k, width, k);
	}
}

//pagodas
function pagodaMove(){
	//update speed of every pagoda 
	this.x1 -= this.speed; 
}
function pagodaMake(){
	noFill();
	stroke(80);
	strokeWeight(2);
	//making the pagoda 
	line(this.x1, (this.y1+50) , this.x1, (this.y1-40));
	line(this.x1+30, (this.y1+50) , this.x1 +30, (this.y1-40));
	strokeWeight(4);
	line(this.x1, (this.y1-35), this.x1+30, (this.y1-35));
	strokeWeight(6);
	line(this.x1-5, (this.y1-42), this.x1+35, (this.y1-42));
}
function pagodaUpdate(){
	// Update the pagodas's positions, and display them.
	for(var i = 0; i< pagodas.length; i++){
		pagodas[i].shift();
		pagodas[i].display();
	}
}
function pagodaAppear(){
	//with a tiny probablilty adding pagodas 
	if(random(0,1)<0.007){
		var pagodaX = width; 
		var pagodaY = random(250, 300 ); 
		pagodas.push(drawPagoda(pagodaX, pagodaY));
	}
}
function pagodaDisappear(){
	//removing pagodas which have reached the edge 
	var pagodasKeep = [];
	for(var i = 0; i<pagodas.length; i++){
		if(pagodas[i].x1 + pagodas[i].bredth > 0){
			pagodasKeep.push(pagodas[i]);
		}
	}
	pagodas = pagodasKeep;
}
function drawPagoda(pagodaX, pagodaY){
	var pagoda = { x1: pagodaX, y1: pagodaY, 
		speed: 4, bredth: 30,
		shift: pagodaMove, display: pagodaMake}
	return pagoda;	
}

//birds 
function drawBird(birdX, birdY){
	var bird = { x: birdX, y: birdY, 
		velocity: random(4,8), size: random(6,10),
		move: birdMove, show: birdMake}
	return bird;	
}

function birdMove(){
	//update speed of every birds 
	this.x -= this.velocity; 
	this.y -= this.velocity/random(5,10);
}
function birdMake(){
	noFill();
	stroke(80);
	strokeWeight(1);
	arc(this.x, this.y, this.size, this. size/2, PI, TWO_PI);
	arc(this.x+ this.size, this.y, this.size, this. size/2 ,PI, TWO_PI);
}
function birdUpdate(){
	// Update the birds's positions, and display them.
	for(var i = 0; i< birds.length; i++){
		birds[i].move();
		birds[i].show();
	}
}
function birdAppear(){
	//with a tiny probablilty adding birds 
	if(random(0,1)<0.1){
		var birdX = width; 
		var birdY = random(0, height/3 ); 
		birds.push(drawBird(birdX, birdY));
	}
}
function birdDisappear(){
	//removing birds which have reached the edge 
	var birdsKeep = [];
	for(var i = 0; i<birds.length; i++){
		if(birds[i].x + birds[i].size > 0){
			birdsKeep.push(birds[i]);
		}
	}
	birds = birdsKeep;
}

Project 11

For my generative landscape, I chose to make a desert with different types of cacti whose sizes and colors are randomly generated. For the sand and hills in the back, I referenced the lab from week 7. While the sand keeps moving, the hills in the back are still but change every time the page is refreshed.

zimmy desert
var cacti = [];
var canyons = [];
var sand = [];
var ball = [];
var noiseParam = 0;
var noiseStep = 0.02;

function setup() {
    createCanvas(640, 240); 
    background(0);

    
    /*// create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }*/
    frameRate(20);
    //canyon values
    for(var i = 0; i <= width/5; i++){
        var n = noise(noiseParam);
        canyons[i];
        var value = map(n, 0, 1, 0, height);
        canyons.push(value);
        noiseParam += noiseStep;
    }
    //sand values
    for(var i = 0; i <= width/5; i++){
        var n = noise(noiseParam);
        sand[i];
        var value = map(n, 0, 1, 0, height/2);
        sand.push(value);
        noiseParam += 0.5*noiseStep;
    }

}


function draw() {
    //sunset gradient
    var gradRed = color(190, 60, 38); // darker red color
    var gradYellow = color(250, 185, 21); // yellow
    for (var i = 0; i < height; i++){
        var gradient = map (i, 0, (height/3)*1.5, 0, 1);
        var bgColor = lerpColor(gradRed, gradYellow, gradient);
        stroke(bgColor);
        line(0, i, width, i);
    } 
    // draw a setting sun
    push();
    noStroke();
    fill(255, 226, 161);
    circle(500, 110, 180);
    pop();
    
    drawCanyons();
    drawSand();

    // taller cacti
    updateAndDisplayCacti();
    removeCactiThatHaveSlippedOutOfView();
    addNewCactiWithSomeRandomProbability(); 
    

    updateAndDisplayBalls();
    removeBallsThatHaveSlippedOutOfView();
    addNewBallsWithSomeRandomProbability(); 




}

//draws background canyons (still)
function drawCanyons(){
    // canyon values
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    noiseParam += noiseStep;
    // draws shape for canyons
    beginShape();
    vertex(0, height);
    for(var i = 0; i <= width/5; i++){
        //filling the canyons with translucent brown
        fill(178, 108, 55, 180);
        noStroke();
        //vertex function to fill the canyon
        vertex((i * 5), canyons[i]); 
        vertex((i + 1) * 5, canyons[i + 1]);   
    }
    vertex(width, height);
    endShape(CLOSE);
}

// draws sand (moving)
function drawSand(){
    push();
    translate(0, 130)
    sand.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height/2);
    sand.push(value);
    // draws shape for sand
    beginShape();
    vertex(0, height);
    for(var i = 0; i <= width/5; i++){
        //filling the sand color
        fill(237, 197, 154);
        noStroke();
        //vertex function to fill the sand
        vertex((i * 5), sand[i]); 
        vertex((i + 1) * 5, sand[i + 1]);   
    }
    vertex(width, height);
    endShape(CLOSE);
    pop();
}



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


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


function addNewCactiWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newCactusLikelihood = 0.02; 
    if (random(0,1) < newCactusLikelihood) {
        cacti.push(makeCactus(width));
    }
}


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

//draw the cactus
function cactusDisplay() {
    cacti.push();
    strokeWeight(25);
    stroke(this.color);

    //main stalk
    var y = 220;
    line(this.x, this.cBottom, this.x, this.cBottom-this.cHeight)
    strokeWeight(17);
    stroke(204, 209, 135, 60);
    line(this.x, this.cBottom, this.x, this.cBottom-this.cHeight)

    // two stalks on side
    strokeWeight(13);
    stroke(this.color);
    line(this.x-20, this.cBottom-this.s1Bottom, this.x-20, this.cBottom-this.s1Height); 
    // left stalk has a random height
    line(this.x+20, this.cBottom-this.s2Bottom, this.x+20, this.cBottom-this.s2Height); 
    // right stalk has a random height
}



// makes taller cacti
function makeCactus(birthLocationX) {
    var ccts = {x: birthLocationX,
                breadth: 50,
                speed: -4.5,
                cHeight: random(30, 60), // height of cactus
                cBottom: random(200, 225), // bottom of cactus
                s1Height: random(20, 60), // top of the left stalk
                s1Bottom: random(5, 20), // bottom of left stalk
                s2Height: random(20, 60), // top of right stalk
                s2Bottom: random(5, 20), // bottom of right stalk
                
                color: color(random(40, 100), random(80, 200), 72), // varies shades of green
                move: cactusMove,
                display: cactusDisplay}
    return ccts;
}

function addNewBallsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newBallLikelihood = 0.02; 
    if (random(0,1) < newBallLikelihood) {
        ball.push(makeBall(width));
    }
}

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

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

function addNewBallWithSomeRandomProbability() {
    // With a very tiny probability, add a new ball cactus to the end.
    var newBallLikelihood = 0.02; 
    if (random(0,1) < newBallLikelihood) {
        ball.push(makeBall(width));
    }
}

// method to update position of ball shaped cactus every frame
function ballMove() {
    this.x += this.speed;
}


// displays ball-shaped cacti
function ballDisplay(){
    push();
    noStroke();
    fill(this.color);
    ellipse(this.x, this.ey, this.ew, this.eh); // main ball cactus
    fill(204, 209, 135, 60)
    ellipse(this.x, this.ey, this.ew-5, this.eh-5); // highlight
    fill(this.color);
    ellipse(this.x, this.ey, this.ew-10, this.eh-10);
    fill(251, 203, 188);
    stroke(this.color);
    strokeWeight(1);
    ellipse(this.x, this.ey-(this.eh/2), 8, 5) // lil flower guy on top
    pop();
}

// makes ball-shaped cacti
function makeBall(birthLocationX) {
    var b = {x: birthLocationX,
                breadth: 50,
                speed: -4.5,
                eh: random(20, 40), // height of ellipse
                ey: random(200, 225), // y coord of ellipse
                ew: random(20, 40), // width of ellipse
                color: color(random(50, 150), 100, random(100, 200)), // varies shades of blue
                move: ballMove,
                display: ballDisplay}
    return b;
}






Project 11: Landscape

This landscape wasn’t the most challenging but the UFO really wasn’t the easiest to get working. I had to experiment a lot with the order of my elements in the draw function to get it looking like it should and it took some testing to get it to move around on the campus and get back on when it flew away.

sketch

var chasm = []
var alien = []
var roadLines = []



function makeLines(lineY, lineLength){  ///creates the yellow lines on the road
  l = {y: lineY, length: lineLength, drawFunction: drawLines, stepFunction: moveLines}
  return l
}

function drawLines(){
  push()
  translate(190, this.y)
  stroke(255, 255, 0)
  line(0, 0, 0, this.length)
  pop()
  push()
  translate(210, this.y)
  stroke(255, 255, 0)
  line(0, 0, 0, this.length)
  pop()
}

function moveLines(){ ////advances the lines so it appears the viewer is moving over the road
  this.y += 10
  if (this.y >= 420){
    roadLines.shift()
    roadLines.push(makeLines(-100, random(0, 200)))
  }

}

function makeUFO(ufoX, ufoY, ufoDX, ufoDY){ ////draws the hovering ufo
  ufo = {x: ufoX, y: ufoY, dx: ufoDX, dy: ufoDY, drawFunction: drawUFO, stepFunction: ufoFly}
  return ufo
}

function drawUFO(){ 
  push()
  translate(this.x, this.y)
  fill(100)
  ellipse(0, 0, 125, 125)
  fill(227, 252, 252)
  ellipse(0, 0, 70, 70)

  for (var t = 0; t <= 10; t++){
    fill(random(0, 255), random(0, 255), random(0, 255))
    ellipse(0, -48, 10, 20)
    rotate(12)
}
pop()
}

function ufoFly(){ ////keeps the ufo flying around the scene if it hits an edge
  this.x += this.dx
  this.y += this.dy
if (this.x >= 400 || this.y >= 400){
  this.dx = random(-5, 5)
  this.dy = random(-5, 5)
  this.dx *= -1
  this.dy *= -1
}
if (this.x <= 0 || this.y <= 0){
  this.dx = random(-5, 5)
  this.dy = random(-5, 5)
  this.dx *= -1
  this.dy *= -1
}



}
function makeChasm(cx, cy){ ///makes the creatures and features on the road
  c = {x: cx, y: cy, type: round(random(0, 3)), drawFunction: chasmDraw, move: chasmAdvance}

return c
}

function chasmDraw(){
  stroke(255)
  translate(this.x, this.y)
  switch (this.type){
  case 0: ////spider alien
  stroke(50) 
  for (u = 0; u <= 8; u++){
  line(0, 0, random(-20, 20), random(-20, 20))
  } 
    break;
   case 1: ////lava pit
   stroke(252, 90, 3)
   line(0, 0, 20, 20)
   line(20, 20, 0, 30)
   line(0, 30, 0, 40) 
   line(0, 40, 20, 60)
   line(20, 60, 0, 80)
   break;
   case 2: ////green alien
   stroke(86, 237, 40)
   line(0, 0, 60, 60)
   line(0, 0, -60, -60)
   line(0, 0, 60, 120)
   line(0, 0, -60, 120)
   stroke(0)
   fill(86, 237, 40)
   ellipse(0, 0, 20, 80)
   break;
   case 3: ////portal thing????
    strokeWeight(3)
    stroke(189, 36, 209)
  fill(0)
   beginShape()
   vertex(0,-40)
   vertex(20, 20)
   vertex(30, 30)
  vertex(20, 40)
  vertex(10, 50)
  vertex(0, 60)
  vertex(-10, 50)
  vertex(-20, 40)
  vertex(-30, 30)
  vertex(-20, 20)
  vertex(0, -40)
   endShape()   
   break;
  }
  

}



function chasmAdvance(){ ////moves the features and makes a new one when one disappears
     translate(0, this.y += 2)
     if (this.y >= width){
      chasm.shift()
      chasm.push(makeChasm(random(0, 400), -200)) 
     }
}



function setup() { ////creates and pushes all of the parts to arrays to be drawn
    createCanvas(400, 400); 
    for (var o = 0; o <= 4; o++){
      var c = makeChasm(random(0, 400), -200)
      chasm.push(c)
    }
    var ufo = makeUFO(200, 200, random(-10, 10), random(-10, 10))
    alien.push(ufo)
    for (var k = 0; k <= 4; k++){
      var l = makeLines(0, random(0, 200))
      roadLines.push(l)
    }

}


function draw() { ////draws each feature and calls their functions
  background(168, 125, 50)
  road()
  for (var k = 0; k <= 4; k++){
    var l = roadLines[k]
    l.stepFunction()
    l.drawFunction()   
  }
  var ufo = alien[0]
  noStroke()
  ufo.stepFunction()    
  ufo.drawFunction()
    for (var o = 0; o <= 4; o++){
      var c = chasm[o]
      c.move() 
      c.drawFunction()
}  
}


function road(){ ///creates the road for the features to be built on
  fill(162, 168, 163)
  rect(100, 0, 200, 400)
  strokeWeight(6)
  stroke(255, 255, 255)
  line(100, 0, 100, 400)
  line(300, 0, 300, 400)
}

Project – 11

I chose to do my project in this minimalist style because I thought it was really cute and reminded me of 8-bit video games (minus all the triangles.) My focus was on the smoothness and cleanliness of the moving image by coordinating objects together.

sketch
var count = 0;

var divwidth = 16;
var divider1;
var divider2;

var bench1;
var bench2;
var bench3;

var people = [];   //holds the people
var mountains = [];  //holds the mountains :)
var trees = [];   //holds the trees 😊

var trainbasecolor = 150;

var windowTop = 30;  //just helper variables for the window dimensions
var windowBottom = 150;


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

    for (var i = 0; i < width/15+10; i++){
        mountains[i] = makeMountain(i*15);
    }
    bench1 = makeBench(158);
    bench2 = makeBench(458);
    bench3 = makeBench(-142);
    
    for (var i = 0; i < 6; i++){  //start off w some people
        if (random(0, 30)<13){
				people.push(makePerson(bench1.x-108.5 + i*43.1));
			}
    }
    for (var i = 0; i < 6; i++){  //start off w some people
        if (random(0, 30)<13){
				people.push(makePerson(bench2.x-108.5 + i*43.1));
			}
    }
    for (var i = 0; i < 6; i++){  //start off w some people
        if (random(0, 30)<13){
				people.push(makePerson(bench3.x-108.5 + i*43.1));
			}
    }
    
    divider1 = makeDivider(300);
    divider2 = makeDivider(0);

    
    
    

    
    frameRate(24);



}


function draw() {

	background(150, 180, 255);
	
	noStroke();  
	for(i=0; i<mountains.length; i++){ //draw mountains
		mountains[i].drawit();
	}
	for(i=0; i<trees.length; i++){ //draw trees
		trees[i].drawit();
	}

	fill(trainbasecolor);
	rect(0, windowBottom, width, 125);  //trainbase
	rect(0, 0, width, windowTop);
	fill(120);
	rect(0, height-20, width, 20);

	divider1.drawit();
	divider2.drawit();

	bench1.drawit();
	bench2.drawit();
	bench3.drawit();


	for(i=0; i<people.length; i++){ //draw people
		people[i].drawit();
	}
	




	divider1.stepit();
	divider2.stepit();

	bench1.stepit();
	bench2.stepit();
	bench3.stepit();

	for(i=0; i<people.length; i++){
		people[i].stepit();
	}
	for(i=0; i<mountains.length; i++){
		mountains[i].stepit();
	}
	for(i=0; i<trees.length; i++){
		trees[i].stepit();
	}

	removePeopleThatHaveSlippedOutOfView();
	removeMountainsThatHaveSlippedOutOfView();

	if(count % 15 == 0){       //make mountain objects
		//if(random(0,10)<3){

			mountains.push(makeMountain(680));
			
		//}
	}
	if(count % 30 == 0){      //make tree objects
		if(random(0,10)<6){

			trees.push(makeTree(600));
			
		}
	}




	count ++;
	print(people.length.toString());
}

//FUNCTIONS FOR TREE OBJECTS
function makeTree(tx){
	
	var treeTopWidth = random(100, 150);
	var treeTopHeight = random(50, 100)
	var treeHeight = random(70, 250);
	var trunkWidth = random(10, 50);
	

	var tree = {x: tx, y: 150, c: color(random(25, 75), random(125,175), random(25, 75)), topw: treeTopWidth, trunkw: trunkWidth, toph: treeTopHeight, trunkh: treeHeight, drawit: treeDraw, stepit: treeStep};

	return tree;

}

function treeDraw(){
	fill(150, 100, 50);
	rectMode(CENTER);
	rect(this.x, this.y, this.trunkw, this.trunkh);

	fill(this.c);
	ellipse(this.x, this.y-this.trunkh/2, this.topw, this.toph);
	rectMode(CORNER);

	
}

function treeStep(){
	this.x -= 8;
}

function removeMountainsThatHaveSlippedOutOfView(){

    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x > -200) {
            treesToKeep.push(trees[i]);
        }
    }
    mountains = mountainsToKeep; // remember the surviving buildings
}
//FUNCTIONS FOR MOUNTAIN OBJECTS
function makeMountain(mx){
	
	var mountainWidth = random(50, 200);
	var mountainHeight = random(50, 125);
	

	var mountain = {x: mx, y: mountainHeight, w: mountainWidth, c: color(random(80, 120), random(225, 255), random(80, 120)), drawit: mountainDraw, stepit: mountainStep};

	return mountain;

}

function mountainDraw(){
	fill(this.c);
	
	triangle(this.x, this.y, this.x-this.w, 250, this.x+this.w, 250);
	
}

function mountainStep(){
	this.x -= 2;
}

function removeMountainsThatHaveSlippedOutOfView(){

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


//FUNCTIONS FOR WINDOW DIVIDER OBJECTS
function makeDivider(wx) { 
    var divider = {x: wx, y: windowTop,
                  drawit: dividerDraw, stepit: dividerStep};

    return divider;
}

function dividerDraw(){
	fill(trainbasecolor);
	rect(this.x, this.y, divwidth, 150);
}

function dividerStep(){
	this.x++;
	
	if(this.x == 600-divwidth){
		this.x = (0-divwidth);
		
	}

	

}
//FUNCTIONS FOR PEOPLE OBJECTS
function makePerson(px){
	
	var personWidth = random(15, 35);
	var personHeight = random(25, 60);
	var headSize = random(8, 20);

	var person = {x: px, y: 196-personHeight/2, w: personWidth, h: personHeight, hs: headSize, c: random(0, 50), drawit: personDraw, stepit: personStep};

	return person;

}

function personDraw(){
	fill(this.c);
	rectMode(CENTER);
	rect(this.x, this.y, this.w, this.h);
	rect(this.x-this.w/4, 212, 5, 36);
	rect(this.x+this.w/4, 212, 5, 36);
	rect(this.x, this.y-this.h/2-this.hs/2+1, this.hs, this.hs);
	rectMode(CORNER);
	
}

function personStep(){
	this.x++;
}

function removePeopleThatHaveSlippedOutOfView(){

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

//FUNCTIONS FOR BENCH OBJECTS
function makeBench(bx){
	var bench = {x: bx, y: 170+divwidth, drawit: benchDraw, stepit: benchStep};
	return bench;

	
}



function benchDraw(){
	rectMode(CENTER);
	fill(220);

	rect(this.x, this.y, 266, 50);
	
	for(i=0; i<6; i++){
		fill(225, 0, 0);
		rect(this.x-108 + i*43.1, this.y, 38, 40);
		fill(155, 0, 0);
		rect(this.x-108 + i*43.1, this.y+15, 38, 10);
		
	}
	rectMode(CORNER);

}

function benchStep(){
	this.x++;
	if(this.x == 750){
		this.x = -150;
		for(i=0; i<6; i++){
			if (random(0, 30)<13){
				people.push(makePerson(this.x-108.5 + i*43.1));
			}
		
		}
	}

}

Project – 11 – Landscape

sketch
//Dreami Chambers; Section C; dreamic@andrew.cmu.edu; Assignment-11-Project

var stars = []
var planets = []
var moon = []
var noiseParam = 0
var noiseStep = 0.1
var sky
var astronaut
var planet
var meteor 
var mx = 300
var my = 0
var mdx
var mdy
var ax = 0
var ay = 100
var ady = 1
var frameCount = 0

function preload() { 
	sky=loadImage("https://i.imgur.com/zfE0rbY.jpg")
	astronaut=loadImage("https://i.imgur.com/0GaKn9k.png")
	planet=loadImage("https://i.imgur.com/UCrpkmB.png")
	meteor=loadImage("https://i.imgur.com/gcfvaqR.png")
} 

function setup() {
    createCanvas(400, 300)
    //meteor velocity
	mdx = random(-10,-15)
	mdy = random(10,15)
    //stars setup
    for (var i = 0; i < 100; i++) {
    	var rx = random(width)
    	var ry = random(height)
    	var rdx = random(4)
        stars[i] = makeStars(rx, ry, 2, rdx)
    }
    //planets setup
    for (var j = 0; j < 2; j++) {
    	var rx = random(width)
    	var ry = random(150)
        planets[j] = makePlanets(rx, ry)
    }
    //moon surface setup
    for (var k = 0; k < width; k++){
		var n = noise(noiseParam)
		var value = map(n, 0, 1, 10, 50)
		moon.push(value)
		noiseParam += noiseStep
	}
    frameRate(10)
}

function draw() {
	image(sky, 0, 0, 400, 400)

	//draws stars
	starUpdate()
	starsRemove()
	starsAdd()

	//draws planets
	planetUpdate()
	planetsRemove()
	planetsAdd()
	
	//draws moving meteor
	drawMeteor(mx, my, mdx, mdy)

	//draws moon surface
	drawMoon()

	//draws astronaut
	drawAstronaut(ax, ay)

	//moves meteors across screen
	mx+=mdx
	my+=mdy

	//moves astronaut up and down
	ay+=ady
	if (ay > 110){
		ady*=-1
	}
	if (ay < 90){
		ady*=-1
	}
	frameCount++
}

function drawAstronaut(x, y){
	image(astronaut, x, y, 55, 60)
}

function drawMoon(){
	stroke(200, 180, 200)
	strokeWeight(200)
	moon.shift()
	var n = noise(noiseParam)
	var value = map(n, 0, 1, 10, 50)
	moon.push(value)
	noiseParam += noiseStep
	for (var i=0; i < width; i++){
		line(i*15, 300+moon[i], (i+1)*15, 300+moon[i+1])
	}
}

function drawMeteor(x, y, dx, dy){
	image(meteor, x, y, 50, 45)
}

//star functions
function starUpdate(){
	for (var i = 0; i < stars.length; i++){
        stars[i].stepFunction()
        stars[i].drawFunction()
	}
}

function starsRemove(){
	starsToKeep = []
	for (var i = 0; i < stars.length; i++){
        if (stars[i].x + stars[i].size > 0){
        	starsToKeep.push(stars[i])
        }
	}
	stars = starsToKeep
}

function starsAdd(){
	var starProb = 0.5
	if (random(1) < starProb){
		stars.push(makeStars(random(width, 410), random(200), 2, random(4)))
	}
}

function starStep() {
    this.x -= this.dx
}

function starDraw() {
	stroke(this.c)
	strokeWeight(this.size)
	point(this.x, this.y)
}

function makeStars(px, py, pdx, ps) {
	var s = {x: px, y: py, dx: pdx, 
		size: ps, c: color(random(150, 230),random(100, 140),random(200, 255)),
		drawFunction: starDraw, stepFunction: starStep
	}
	return s
}

//planet functions
function planetUpdate(){
	for (var i = 0; i < 2; i++){
        planets[i].stepFunction()
        planets[i].drawFunction()
	}
}

function planetsRemove(){
	planetsToKeep = []
	for (var i = 0; i < planets.length; i++){
        if (planets[i].x + planets[i].size > 0){
        	planetsToKeep.push(planets[i])
        }
	}
	planets = planetsToKeep
}

function planetsAdd(){
	var planetsProb = 0.3
	if (random(0, 1) < planetsProb){
		planets.push(makePlanets(random(width, 450), random(150)))
	}
}

function planetStep() {
    this.x -= this.dx
}

function planetDraw() {
	image(planet, this.x, this.y, this.size, this.size)
}

function makePlanets(px, py) {
	var p = {x: px, y: py, dx: 2, 
		size: random(10,60), c: color(random(200,200),random(140,170),random(140,170)),
		drawFunction: planetDraw, stepFunction: planetStep
	}
	return p
}

For this project, I wanted to create a landscape capturing space. I used clip art for a few of the objects here. The meteor moves past the screen at the beginning of the animation. The objects that move with the camera are the stars, the planets, and the moon surface. The stars are created by randomly placing points with different sizes and slightly different colors. The planets have random sizes and locations as well. For the moon surface, I referred to the stock market example that we did in lab previously. I had originally planned to add craters to the moon, but decided not to for the sake of time. Here is my sketch for this project:

11 – Landscape

I was motivated by my experiencing driving. Additionally, a lot of the projects from previous years and such seem to have objects move left or right off the screen, or top to bottom, but I haven’t seen any with “one-point” perspective, so I thought I would give it a try. It was a little challenging and I would’ve like to have made the roadlines move in the mirror as well, but I just couldn’t figure it out.

sketch.sarlDownload
// Sarah Luongo
// Sluongo
// Section A
// Project

// This code aims to articulate the perspective of driving on the road, showing
//different scenery as the car moves forward.

var lines = [];
var cds = [];
var gps;

function preload() {
    gps = loadImage('https://i.imgur.com/tOwIpKP.png');
}

function setup() {
    createCanvas(420, 480);
    background(17, 124, 19);
    gps.resize(100, 100);
    // Creates 6 initial roadline objects
    for (var i = 0; i < 6; i++) {
        lines[i] = makeRoadlines(220,i*(7+(i*7)), i+4, (i+1)*10, -0.1, 0.4, i);
    }
    // Creates 2 initial cloud objects
    for (var i = 0; i < 2; i++) {
        cds[i] = makeCloud(100+(i*200), 40, 50, 40, .3);
    }
}

function draw() {
    road();
    roadlines();
    sky();
    updateRoads();
    driverseat();
}

function driverseat() {
    //Dashboard
    noStroke();
    fill(50);
    rect(0, 360, width, 120);

    //Fuel Meter and Speedometer
    fill('white');
    circle(110, 430, 50);	
    circle(190, 430, 50);
    fill('black');
    circle(110, 430, 40);
    circle(190, 430, 40);

    // Fuel meter lines
    push();
    translate(110, 430)
    rotate(radians(-45));
    for (var i = 0; i < 5; i++) {
	stroke('white');
        strokeWeight(.8);
	line(-15, 0, -10, 0);
	rotate(radians(55));
    }
    pop();

    // Speedometer lines
    push();
    translate(190, 430)    
    rotate(radians(-45));
    for (var i = 0; i < 10; i++) {
        stroke('white');
        strokeWeight(.8);
        line(-15, 0, -10, 0);   
        rotate(radians(25));
    }
    pop();
   
    // Needle
    fill('red');
    push();
    translate(110, 430);
    triangle(-2, -6, 8, 16, 12, 14);
    translate(80, 0);
    triangle(-2, -6, 8, 16, 12, 14);
    pop();

    //Steering Wheel
    stroke('black');
    strokeWeight(20);
    noFill();
    arc(150, 490, 200, 200, PI, PI);
    noStroke();
    fill('black');
    ellipse(150, 500, 200, 100);

    // GPS
    image(gps, 300, 380);

    //Mirror
    fill('black');
    rect(300, 0, 120, 45);
    fill(17, 124, 19);
    rect(310, 0, 100, 35);
    fill('gray');
    triangle(310, 35, 350, 0, 400, 35);
    fill('lightblue');
    rect(310, 0, 100, 10); 
}

function road() {
    noStroke();
    fill('gray');
    triangle(-(width), height, width/2, 80, 1.5*width, height);
}

function sky() {
    noStroke();
    fill('lightblue')
    rect(0, 0, width, 100);
    
    // Sun
    fill('yellow');
    circle(10, 10, 70);

    // Clouds
    clouds();
    updateClouds();
}

function roadlines() {
    fill('white');
    push();
    rotate(radians(20));
    for (var i = 0; i < 6; i++) {                           
        rect(lines[i].x, lines[i].y, lines[i].sx, lines[i].sy);
    }
    pop();
}

function makeRoadlines(xPos, yPos, xSize, ySize, changeX, changeY, c) {
    var roadlines = {x: xPos, y: yPos,
	             sx: xSize, sy: ySize,
                     dx: changeX, dy: changeY,
                     change: c}
    return roadlines;
}

// Updates roadlines & adds to size of road as it moves towards bottom of canvas
function updateRoads() {
    for (var i = 0; i < 6; i++) {
        // Makes new line when each line is greater than 300
        if (lines[i].y > 300) {
            lines[i] = makeRoadlines(220,0*(7+(0*7)),
	    0+4, (0+1)*10, -0.1, 0.4, 0);
	    // How far apart each line is
	    var k = i;
            for (var j = 0 ; j < 6; j++) {
	        if (k > 5) {
		    k = 0;
		}
	        lines[k].change = j;
		k++;
	    }
        }
	// Makes lines move and change size toward bottom of canvas
	lines[i].y += lines[i].dy + lines[i].change/4;
	lines[i].sx += 0.01;
	lines[i].sy += 0.1;
    }
}

function makeCloud(xPos, yPos, w, h, changeX) {
    var clouds = {x: xPos, y: yPos,
	          dx: changeX}
    return clouds;
}

function clouds() {
    fill('white');
    for (var i = 0; i < 2 ; i++) {
        ellipse(cds[i].x, cds[i].y, 50, 40);
        ellipse(cds[i].x + 20, cds[i].y + 20, 50, 40);
        ellipse(cds[i].x + 30, cds[i].y - 10, 50, 40);
        ellipse(cds[i].x + 60, cds[i].y + 15, 50, 40);
        ellipse(cds[i].x + 70, cds[i].y, 50, 40);
    }
}

// Makes cloads reappear at the left of the screen
function updateClouds() {
    // If cloads greater than 450 makes new one reappear from left of canvas
    for (var i = 0; i < 2; i++) {
        if (cds[i].x > 450) {
	    cds[i].x = -100;
	}
        // Makes them move towards right of canvas
	cds[i].x += cds[i].dx;
    }
}

Project 11: Deep Sea

For the project this week, I wanted to create a scene that depicts marine life, with fish seaweed and bubbles blown by the wish.

The objects in this scene are of three types:

  1. Stable – pebbles, seabed
  2. Movement – seaweed, which moves between constraints for the effect of swaying in water
  3. Motion – the fish and the bubbles.

I planned the scene in a sketch and then, using the starter code, tried to explore different ways of making the scene dynamic.

For the fish, I first, used the constructor, to make the shape of the fish and then used transparency to create an element of uniqueness in each new fish that is born on the canvas. This also enhances the effect of transparency scales and that eveything under water is bobbing and swaying.

For the motion of the seaweed, I used the random() function so that the height of the rectangle moves between two constraints, this giving the movement effect.

Please view the full code and visual preview here:

https://editor.p5js.org/ssahasra/full/R7Sh-om9z

Project 11 – Landscape

sketchDownload
//Ian Lippincott
//ilippinc@andrew.cmu.edu
//Section: D
//Project 11

var hill = [];
var mountains = [];
var trees = [];
var c1;
var c2;
var noiseParam = 0;
var noiseStep = 0.03;

function setup() {
    createCanvas(400, 240);
    //Define background colors
    c1 = color(228, 90, 41);
    c2 = color(221, 197, 75);
    strokeWeight(1);
    frameRate(20);
    for (var i = 0; i < (width / 5) + 1; i++) {
      var n = noise(noiseParam);
      var value = map(n, 0, 1, 50, 200);
      hill.push(value);
      noiseParam += noiseStep;
    }
}

 // create an initial collection of mountains 
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        mountains[i] = makemountain(rx);
    }

// create an initial collection of trees 
    for (var i = 0; i < 10; i++){
        var r = random(width);
        trees[i] = maketree(r);
    }    

function draw() {
  setGradient(c1, c2);
  strokeJoin(BEVEL);
  stroke(0);
  strokeWeight(4);
  fill(63, 77, 44);
  hill.shift(); 
  var n = noise(noiseParam);
  var value = map(n, 0, 1, 50, 150);
    hill.push(value);
    noiseParam += noiseStep;
    beginShape();
    vertex(0, height);
    for (var i = 0; i < (width / 5) + 1; i++) {
      vertex(i * 5, hill[i]);
    } 
    vertex(width, height);
    endShape();

    //Ground
    fill(95, 110, 73);
    rect(0, 199, width, height);

    //mountains
    updateAndDisplayMountains();
    removeMountainsThatHaveSlippedOutOfView();
    addNewMountainsWithSomeRandomProbability();

    //Trees
    updateAndDisplayTrees();
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability();
}

//mountains
function makeMountain(birthLocationX) {
    var mntn = {x: birthLocationX,
                breadth: 70,
                speed: -5.5,
                nFloors: round(random(2,8)),
                move: mountainMove,
                display: mountainDisplay}
    return mntn;
}

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

// draw the mountain
function mountainDisplay() {
    var floorHeight = 8;
    var cHeight = this.nFloors * floorHeight; 
    
    strokeWeight(4);
    stroke(0);
    fill(156, 119, 76);
    push();
    translate(this.x, height - 40);

    //Mountain
    triangle(-7,0,this.breadth/2,-cHeight-20,this.breadth + 7,0);
    //Shadow
    fill(87, 66, 42);
    triangle(-7,0,this.breadth/2,-cHeight-20,20,0);
    //Snow
    pop();
}

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

function removeMountainsThatHaveSlippedOutOfView(){
  var mountainToKeep = [];
  for (var i = 0; i < mountains.length; i++){
    if (mountains[i].x + mountains[i].breadth > 0) {
        mountainToKeep.push(mountains[i]);
    }
  }
  mountains = mountainToKeep; // remember the surviving mountain
}

function addNewMountainsWithSomeRandomProbability() {
    // With a very tiny probability, add a new cabin to the end.
    var newMountainLikelihood = 0.02; 
    if (random(0,1) < newMountainLikelihood) {
        mountains.push(makeMountain(width));
    }
}


//trees
function makeTree(birthLocationX) {
    var tr = {x: birthLocationX,
                breadth: 70,
                speed: -6.0,
                nFloors: round(random(2,8)),
                move: treeMove,
                display: treeDisplay}
    return tr;
}

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

// draw the tree
function treeDisplay() {
    var floorHeight = 8;
    var cHeight = this.nFloors * floorHeight; 
    
    strokeWeight(4);
    stroke(0);
    fill(71, 145, 80);
    push();
    translate(this.x, height - 40);

    //Tree
    triangle(0, 0, 10,-cHeight, 20, 0);
    triangle(0, -8, 10,-cHeight, 20, -8);
    triangle(0, -16, 10,-cHeight, 20, -16);
    pop();
}

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

function removeTreesThatHaveSlippedOutOfView(){
  var treeToKeep = [];
  for (var i = 0; i < trees.length; i++){
    if (trees[i].x + trees[i].breadth > 0) {
        treeToKeep.push(trees[i]);
    }
  }
  trees = treeToKeep; // remember the surviving mountain
}

function addNewTreesWithSomeRandomProbability() {
    // With a very tiny probability, add a new cabin to the end.
    var newTreeLikelihood = 0.08; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

//Makes Gradient Background
function setGradient(c1, c2) {
  noFill();
  for (var b = 0; b < height; b++) {
    var inter = map(b, 0, height, 0, 1);
    var c = lerpColor(c1, c2, inter);
    stroke(c);
    line(0, b, width, b);
  }
}

Project 11 – Generative Landscape

My project is a simple landscape with hills, trees, buildings, birds, and the sun. The trees vary in size and location, the building varies in width, and the birds vary in location and speed.

Maggie – Generative Landscape
//Maggie Ma
//Section D
//Generative Landscape

var buildings = [];
var hills = [];
var noiseParam = 0;
var noiseStep = 0.02;
var trees = [];
var birds = [];


function setup() {
    createCanvas(400, 500); 
    strokeWeight(4);
    
    // create an initial collection of buildings
    for (var i = 0; i < 2; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    //create an initial collection of birds
    for (var i = 0; i < 3; i++){
        var rx = random(width);
        birds[i] = makeBird(rx);
    }

    // drawing hills in the back
    for (var i = 0; i<width/5 +1; i++) {
    	var n = noise(noiseParam);
    	var value = map(n,0,1,0,height+50);
    	hills.push(value);
    	noiseParam+=noiseStep;
    }
    frameRate(15);
}


function draw() {
    background(255,203,186); //light pink

    //sun
    fill(253,165,0); //yellow
    circle(width/2, height/2-70, 120.438 );

    //birds
    updateandDisplayBird();
    removeBirdThatHaveSlippedOutOfView();
    addNewBirdWithSomeRandomProbability();	

    //hills
    drawHills();
    displayHorizon();

    //building
    updateAndDisplayBuilding();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 

   //trees
    updateAndDisplayTrees();
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability(); 
}

function drawHills() {
	hills.shift();
    var n = noise(noiseParam);
    var value = map(n,0,1,0,height+50);
    hills.push(value);
    noiseParam += noiseStep;

    beginShape();
    vertex(0,height);
    for(var i =0; i <= width/5; i++) {
    	fill(255,163,130); //pink color
    	strokeWeight(4);
    	vertex((i*5),hills[i]);
    
    }
    vertex(width,height);
    endShape();
}

//creating trees
function makeTree(birthLocationX) {
    var t = {x: birthLocationX,
                breadth: round(random(10,30)),
                speed: -5.0,
                y: random(10, 40), //randomize tree size and location
                w: random(30, 40),
                h: random(40, 60),
                move: treeMove,
                display: treeDisplay}
    return t;
}

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

function treeDisplay() {
    push();
    translate(this.x, height -125);
    strokeWeight(4); 
    fill(80,202,119);
    //leaves
  	ellipse(this.x,this.y, this.w, this.h);
  	//trunk
  	line(this.x, this.y+10, this.x, this.y+70);
    pop();
}

function updateAndDisplayTrees(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

function removeTreesThatHaveSlippedOutOfView(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}
function addNewTreesWithSomeRandomProbability() {
    var newTreeLikelihood = 0.07; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

//creating building
function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 70,
                speed: -8.0,
                w: random(70,110), //randomize width
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

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

function buildingDisplay() {
	push();
    strokeWeight(4); 
    fill(253,165,0); //yellow block on right side
  	rect(this.x ,315.478 ,this.w ,137.574);
  
  	rect(this.x - 55.901, 364.514 ,15.016 ,88.538); //yellow pillars
  	rect(this.x +7.51, 364.514 ,15.016 ,88.538);
  	rect(this.x-28.083,180.775,23.237,26.131); //yellow top
  	fill(255,255,255);
  	rect(this.x-33.153,206.996,33.377,33.377); //middle section
  	fill(253,165,0);
  	rect(this.x-21.845,219.566,10.762,20.807);
  	fill(255,255,255);
  	rect(this.x-40.661, 240.463,48.108 ,212.59 ); //bottom base
  	fill(0,195,227);
  	rect(this.x-40.661,259.105,15.016 ,25.094); //turquoise designs
  	rect(this.x-40.661,302.931,15.016 ,25.094);
  	rect(this.x-7.508,259.105,15.016 ,25.094 );
  	rect(this.x-7.508, 302.931,15.016 ,25.094);
  	fill(225,43,0);
  	rect(this.x-40.885,346.758,15.016,106.295); //red designs
  	rect(this.x-7.508,346.758,15.016,106.295);
  	line(this.x-25.869,240.8 ,this.x-25.869,453.053);
  	line(this.x-7.508,240.8 ,this.x-7.508,453.053);

    pop();
}

function updateAndDisplayBuilding(){
    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

function removeBuildingsThatHaveSlippedOutOfView(){
    var buildingToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingToKeep.push(buildings[i]);
        }
    }
    buildings = buildingToKeep;
}
function addNewBuildingsWithSomeRandomProbability() {
    var newBuildingLikelihood = 0.015; 
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}

//creating birds
function updateandDisplayBird(){
    for (var i = 0; i < birds.length; i ++){
        birds[i].move();
        birds[i].display();
    }
}

function removeBirdThatHaveSlippedOutOfView(){
    var keepBirds=[];
    for (var i = 0; i < birds.length; i++) {
        if (birds[i].x < width) {
            keepBirds.push(birds[i]);
        }
    }
    birds = keepBirds;
}

function addNewBirdWithSomeRandomProbability(){
    var newBirdLikelihood = 0.01; 
    if (random(0,1) < newBirdLikelihood) {
        birds.push(makeBird(15, 15));
    }
}

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

function birdDisplay(){
    fill(0);
    stroke(0);
    push();
    translate(this.x, this.y);
    //wings
    triangle(0, 0, 3, 0, -2, -3);
    triangle(0, 0, 3, 0, 2, 3);
    pop();
}

function makeBird(birthLocationX, birthLocationY){
    var bird = {x: birthLocationX,
                y:random(100,200),
                speed:random(2, 9),
                move: Birdmove,
                display: birdDisplay};
    return bird;
}
//creating grass horizon line
function displayHorizon(){
    fill(106,207,124);
    stroke(4);
    rect(0, height-50, width, height-50);
}