Carly Sacco-Project 11-Generative Landscape

sketch

//Carly Sacco
//Section C
//csacco@andrew.cmu.edu
//Project 11: Generative Landscape

//creates the components on the water
var waterSpeed = 0.00008;
var waterDetail = 0.0005;

//creates the components for the icebergs
var iceSpeed = 0.0005;
var iceDetail = .05;

//snow array
var snow = [];

function setup() {
    createCanvas(480, 280);
	
	//initial collection of snow
	for (var i = 0; i < 100; i += 1) {
		var flake = random(width);
		snow[i] = drawSnow(flake);
	}
	frameRate(10);

	}


function draw() {
	//sky
    background(176, 203, 245);
	
	//icebergs
	noFill();
	beginShape();
	stroke(255);
    for (var x = 0; x < width; x += 1) {
        var t = (x * iceDetail) + (millis() * iceSpeed);
        var y = map(noise(t), 0,1, height/7, height);
        vertex(0, 900)
		vertex(width, 800)
		vertex(x, y);
    }
	endShape();
	
	//calls the function to make water
	makeWater();
	
	//penguin body
	fill('black');
	noStroke();
	ellipse(280, 220, 35, 40);
	ellipse(280, 195, 25, 25);
	
	//penguin stomach
	fill('white');
	ellipse(280, 225, 25, 45);
	ellipse(280, 195, 15, 15);
	
	//penguin eyes
	fill('black');
	ellipse(276, 191, 3, 3);
	ellipse(284, 191, 3, 3);
	
	//penguin body
	fill('orange');
	triangle(276, 195, 284, 195, 280, 200);
	
	//boat
	push();
	noStroke();
	translate(60, 30);
	fill('red')
	quad(40, 200, 250, 200, 230, 260, 60, 260);
	fill('white');
	rect(100, 150, 80, 50);
	
	fill('black')
	ellipse(110, 165, 15, 15);
	ellipse(140, 165, 15, 15);
	ellipse(170, 165, 15, 15);
	pop();
	
	//calling the functions to make the snow
	snowFall();
	drawSnow();	
	addSnow();
	
}
//makes the water
function makeWater() {
	noFill();
    beginShape();
	stroke(66, 114, 189);
    for (var x = 0; x < width; x++) {
        var t = (x * waterDetail) + (millis() * waterSpeed);
        var y = map(noise(t), 0,1, height/2, height);
        vertex(0, 800)
		vertex(width, 800)
		vertex(x, y);
    }
    endShape();
}

//continues to add snow that appears
function addSnow() {
	var moreSnow = 5;
	if(1 < moreSnow) {
		snow.push(drawSnow(height));
	}
}

//calls for the snow to appear and move
function snowFall() {
	for (i = 0; i < snow.length; i +=1) {
		snow[i].displaySnow();
		snow[i].moveSnow();
	}
}

//actually drawing what the snow looks like
function drawSnow(width) {
	var sno = {
		x: random(0, 480),
		y: 0,
		radius: random(5, 10),
		speed: 1,
		moveSnow: function() {
			this.y += this.speed;
		},
		displaySnow: function() {
			noStroke();
			fill(255);
			ellipse(this.x, this.y, this.radius, this.radius);
		},
	}
	return sno;
}

For my project I had decided I wanted to do a winter themed one since it has started to get very cold here. Therefore, instead of mountains I chose to do icebergs and did that by making the sharp edges seem to be floating by the boat. After I added the snow for my objects and boat to fit the theme I thought it would be cute to add the penguin.

Angela Lee – Project 11 – Generative Landscape

sketch

/*
 * Angela Lee
 * Section E
 * ahl2@andrew.cmu.edu
 * Project 11 Generative Landscape
 */

// tallest mountains
var tallMtnDetail = 0.005; // detail in mountains
var tallMtnSpeed = 0.0001; // speed of mountains

// medium mountains
var medMtnDetail = 0.0075;
var medMtnSpeed = 0.0002; 

// beach 
var beachDetail = 0.003;
var beachSpeed = 0.0004;

// array for ripples
var ripples = [];

var yellow, pink; 

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

    // boundaries for ripples
    var top = height * 5/8 + 10;
    var bottom = height - 10;

    // first ripples 
    for (var i = 0; i < 10; i++) {
        var rippleX = random(width);
        var rippleY = random(top, bottom);
        ripples[i] = makeRipples(rippleX, rippleY);
    }

    // gradient for the water
    yellow = color(255, 219, 140);
    pink = color(247, 132, 124);
 }

function draw() {
    noStroke();
    background(255, 156, 161);
    makeSun(); // setting sun
    makeTallMtn(); // tallest mountains
    makeMedMtn(); // middle mountains
    //makeWater();
    gradientWater();

    // ripple functions
    updateRipple();
    removeRipple();
    addRipple(); 

    makeBeach();

}
//----------------- FUNCTIONS BELOW THIS LINE -----------------------------

// SETTING SUN
function makeSun() {
    // sun rays
    noStroke();
    fill(255, 161, 135);
    ellipse(width/2, height * 3/8, 275, 275);

    // sun
    stroke(255);
    strokeWeight(1);
    fill(247, 217, 82);
    ellipse(width/2, height * 3/8, 175, 175);
    
}

// TALLEST MOUNTAINS
function makeTallMtn() {
    fill(252, 119, 165);
    strokeWeight(1);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * tallMtnDetail) + (millis() * tallMtnSpeed);
        var y = map(noise(t), 0, 1, height / 8 * 2, height / 8 * 4);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

// MEDIUM MOUTAINS
function makeMedMtn() {
    fill(230, 99, 160);
    strokeWeight(1);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * medMtnDetail) + (millis() * medMtnSpeed);
        var y = map(noise(t), 0, 1, height / 8 * 3, height / 8 * 5);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

// OCEAN
function gradientWater() {
    noFill();
    for (var y = height * 5/8; y < height; y++) {
        var inter = map(y, height * 5/8, height, 0, 1);
        var c = lerpColor(yellow, pink, inter);
        stroke(c);
        line(0, y, width, y);
    }
}

// BEACH
function makeBeach() {
    fill(252, 195, 182);
    strokeWeight(1);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * beachDetail) + (millis() * beachSpeed);
        var y = map(noise(t), 0, 1, height * 7/8, height * 19/20);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

//----------------- RIPPLE OBJ & FUNCTIONS BELOW THIS LINE -----------------------------

// RIPPLE OBJECT
function makeRipples(xPos, yPos) {
    var makeRipple = {x: xPos,
                      y: yPos,
                      // longer ripples are in the front, shorter ones in the back
                      length: map(yPos, height * 5/8, height, 5, 75),
                      // thinner ripples in the back, thicker ones in the front
                      weight: map(yPos, height * 5/8, height, 1, 4),
                      // faster ripples in the front, slower ripples in the back
                      speed: map(yPos, height * 5/8, height, 1, 4),
                      move: moveRipple,
                      draw: drawRipple}
    return makeRipple; 
}

// MOVING THE RIPPLE
function moveRipple() {
    // x position changes by speed
    this.x += this.speed; 
    // if the ripple leaves the frame, reset x position
    // to the left side of the frame
    if (this.x > width + this.length) {
        this.x === -this.length;
    }
}

// ADDING RIPPLES
// using a tiny probability, add ripples
function addRipple() {
    if (random(0, 1) < 0.075) {
        ripples.push(makeRipples(-75, random(height * 5/8, height)));
    }
}

// REMOVING RIPPLES
function removeRipple() {
    // an array for ripples to keep
    var keepRipples = [];
    for (var i = 0; i < ripples.length; i++) {
        if (ripples[i].x < width) {
            keepRipples.push(ripples[i]);
        }
    }
    ripples = keepRipples;
}

// UPDATE AND DISPLAY RIPPLE
function updateRipple() {
    for (var i = 0; i < ripples.length; i++) {
        ripples[i].move();
        ripples[i].draw();
    }
}

// DRAWING THE RIPPLE
function drawRipple() {
    strokeWeight(this.weight);
    stroke(255);
    line(this.x, this.y, this.x + this.length, this.y);
}







For my landscape, I was inspired the 80s vaporwave illustration style and color. I created a sunset scene and had fun with showing depth through details. For instance, the sizes and speeds of the mountains and ripples are all dependent on the “distance” they would be away from the viewer (the farther something is, the slower and smaller it is).

I’m using a grace day for this project 🙂

A sketch of my beach landscape.

Project 11 Landscape Alice Cai

sketch

//alcai@andrew.cmu.edu
//alice cai
//section E
//week 11 assignment A

//terrain variables
var terrainSpeed = -0.0003;
var terrainDetail = 0.005;
var terrainSpeed2 = -0.0004;
var terrainDetail2 = 0.007;


//lantern variables
var List = [];
var moving = -5;
var end = -20;

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

    //call # of lanterns
    for (var j = 0; j < 20; j++) {
        var px = random(width);
        var py = random(height / 3);
        List[j] = makeLant(px, py);
    }

    //define gradient colors
    yello=color(255, 187, 0);
    orang=color(250, 133, 0);

}

function draw() {
    background(100, 50, 122);
    //call moon
    moon();
    //draw dessert mountains
    mount();
   //water
    fill(10, 12, 71);
    rect(0, height/3 * 2, width, height);
    //render lanterns
    lantRender();

}

//draw a mooon
function moon(){
    noStroke();
    fill(255, 237, 186, 30);
    ellipse(width/2, height/3, 200,200);
    fill(255, 237, 186);
    ellipse(width/2, height/3, 150,150);

    
}

function mount(){
    //two mountain ranges
    noStroke();
    beginShape();
    fill(122, 55, 80);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t2 = (x * terrainDetail2) + (millis() * terrainSpeed2);
        var y = map(noise(t2), 0, 1, 100, 300);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();

    noStroke();
    beginShape();
    fill(53, 40, 105);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t1 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t1), 0, 1, 250, 300);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();

}

//make lantern with variable parameters, return object lant
function makeLant(px,py) {
    var lant = {x: px, 
                y: py,
                width: random(0,50),
                thic: random(20,30),
                speed: moving,
                update: lantUpdate,
                draw: lantDraw}

    return lant;
}

//draw lantern
function lantDraw() {
    noFill();
    noStroke();       
    //random size adds flickering 
    var size = this.thic + random(0,5);
    var thic =  this.width;
    push();
    translate(this.x, this.y * 3);
    //gradient line
    for (var i = 0; i < size; i++) {
        var inter = map(i, 0, size, 0, 1);
        var c = lerpColor(orang, yello, inter);
        stroke(c);
        strokeWeight(thic);
        line(0, i, 20, i);
      }
    pop();
}

//move the lanters and have them start over when they hit the end
function lantUpdate() {
    //speed of moving but with random to make wind/random travel speed effect
    this.x += this.speed + random(-5,5);
    if (this.x <= end) {
        this.x += width - end;
    }
}

//render lantern, add to list array
function lantRender() {
    for (var i = 0; i < List.length; i++) {
        List[i].update();
        List[i].draw();
    }

}

sketch

This project took inspiration from the Disney movie Tangled, specifically from the final, super romantic scene of the lantern lighting. I wanted to recreate this scene with the warm colors and floating lanterns. The randomized sizes created flickering and the size varation created depth to the lanters that lit up the sky. The lanterns float across the screen like they are in the sky.  

lantern scene from tangled
purply lantern scene from tangled

Shannon Ha – Project 11 – Generative Landscape

sketch

//Shannon Ha
//Section D
//sha2@andrew.cmu.edu
//Project 11 Generative Landscape

var terrainSpeed = 0.0001;
var terrainDetail = 0.006;
var martians = [];

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

    for (var i = 0; i < 4; i++){ //create initial collection of martians displayed on screen.
        var rx = random(width);
        martians[i] = makeMartian(rx);
    }
    
    for (var i = 0; i < stars; i++) { //randomly generates star size and position.
    sX.push(random(0, width)); // x position of star
    sY.push(random(0, height / 3)); // y position of star
    starSize.push(random(0.1, 1)); // star size
    }
    frameRate(15);
}

function draw() { // calls all the objects
    background(43, 14, 7);
    drawStars();
    drawMountain();
    drawMountainB();

    //calls martian objects
    updateAndDisplayMartians();
    removeMartians();
    addMartians();

    // draw distant planet A
    fill(130, 67, 52);
    noStroke();
    ellipse(400, 20, 30, 30);
    // draw distant planet B
    fill(176, 91, 70);
    ellipse(350, 15, 10, 10);
}
var stars = 300; //number of star points
var sX = []; //x position array
var sY = []; //y position array
var starSize = [];// star size array

function drawStars() {
    noStroke();
    for (var i = 0; i < stars; i++) { // draws the stars
        stroke(random(100, 255)); // randomize grayscale for stroke to give the twinkle effect
        strokeWeight(starSize[i]);
        point(sX[i], sY[i], 10, 10);
    }
}

function drawMountain(){ //background terrain
    push();
    fill(79, 16, 0);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);// adjusts flatness of terrain
        var y = map(noise(t), 0,1, height/2.5, height * 0.2);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
    pop();
}

function drawMountainB(){ //terrain in the front
    push();
    fill(138, 31, 4);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed * 2);
        var y = map(noise(t), 0,1, height , height * 0.1);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
    pop();
}

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

function removeMartians(){ // removes all martians that go off the canvas.
    var martiansToKeep = [];
    for (var i = 0; i < martians.length; i++){
        if (martians[i].x + martians[i].breadth > 0) {
            martiansToKeep.push(martians[i]);
        }
    }
    martians = martiansToKeep; // remembers the remaining martians on canvas.
}

function addMartians(){ // adds new martians onto canvas
    var newMartiansLikelihood = 0.017;
if (random(0,1) < newMartiansLikelihood) {
    martians.push(makeMartian(0));
}
}

function martianMove() { // allows the martians to glide across screen
    this.x += this.speed;
}

function displayMartian() { //draws the martian.
    fill(12, 63, 117);
    noStroke();
    push();
    translate(this.x, height - 60);
    // body
    ellipse(20, 30, this.breadth, this.height);
    // white part of eye
    fill(255);
    ellipse(20, 20, this.breadth / 2, this.breadth / 2);
    //blue part of eye
    fill(105, 160, 219);
    ellipse(20, 20, 10, 10);
    //antennas
    stroke(105, 160, 219);
    strokeWeight(4);
    line(10, 10, 5, 5);
    line(30, 10, 35, 5);
    //ends of antenna
    fill(random(255), random(100), random(200));
    noStroke();
    ellipse(5, 5, 10, 10);
    ellipse(35, 5, 10, 10);

    pop();
}

function makeMartian(birthLocationX){ // martian characteristics
    var alien = {x: birthLocationX,
                breadth: 30,
                height: 50,
                speed: random(3, 7),
                move: martianMove,
                display: displayMartian};
    return alien;
}

Rough sketch.
Screenshot of the music video I took inspiration from.

For this project, I wanted to create a fictional landscape of Mars, so I took a bit of inspiration from the iconic Britney Spears’ Oops I did it again Music Video (I wanted to add an astronaut but I didn’t know how to remove the background of a picture I found online) and added my own twist by putting in blue aliens that greet you with their antennas as you pass glance over the Martian landscape. I had a lot of fun making this project as it helped me understand the use of objects and characteristics better!

Crystal-Xue-Project-11

sketch-237.js

//Crystal Xue
//15104-section B
//luyaox@andrew.cmu.edu
//Project-11

var terrainSpeed;
var terrainDetail;
var c1, c2;
var cacti = [];
var cWidth = 50; //cactus Width
var cLeft = - 20 - cWidth; //left point of cactus drawn

function setup() {
    createCanvas(480, 240);
    // create an initial collection of cacti
    for (var i = 0; i < 4; i++){
        var xLocation = random(width);
        var yLocation = random(150, 170);
        cacti[i] = makeCacti(xLocation, yLocation);
    }

    frameRate(20);
    //two end colors of the gradient backgound
    c1 = color(134, 162, 148);
    c2 = color(245, 193, 140);
}

function draw() {
    setGradient(c1, c2);
    terrain();
    //addCacti();
    updateCacti();

}

function drawCacti() {
    noStroke();
    fill(255, 230, 238);
    push();
    translate(this.x2, this.y2);
    scale(this.cactiSize);
    stroke(61,73,49);
    strokeWeight(10);
    line(0, 0, 0,60);

    noFill();
    stroke(61,73,49);
    strokeWeight(10);
    beginShape();
    curveVertex(-20,20);
    curveVertex(-20,20);
    curveVertex(-15,30);
    curveVertex(0,30);
    curveVertex(20,25);
    curveVertex(25,-10);
    curveVertex(25,-10);
    endShape();

    stroke(100,100,89);
    strokeWeight(0.5);
    line(0, -2, 0,62);
    line(2, -2, 2,62);
    line(-2, -2, -2,62);

    //draw cacti spines
    fill(0);
    noStroke();
    ellipse(0,2,2,2);
    ellipse(5,20,3,3);
    ellipse(20,30,2,2);
    ellipse(30,10,2,2);
    ellipse(-15,17,3,3);
    ellipse(-10,27,2,2);
    ellipse(5,45,2,2);
    pop();
}


function makeCacti(xlocation, ylocation) {
    //Cacti objects
    var makeCactus = {x2: xlocation,
                      y2: ylocation,
                      cactiSize: random(0.8,1.5),
                      speed: -2.0,
                      move: moveCacti,
                      draw: drawCacti}
    return makeCactus;
}

function moveCacti() {
    //make cacti move
    this.x2 += this.speed;
    if (this.x2 <= cLeft) {
        this.x2 += width - cLeft;
    }
}

function updateCacti() {
    for(i = 0; i < cacti.length; i++) {
        cacti[i].move();
        cacti[i].draw();
    }
}

function setGradient(c1, c2) {
    //gradient color background
    noFill();
    for (var y = 0; y < height; y++) {
        var inter = map(y, 0, height, 0, 1);
        var c = lerpColor(c1, c2, inter);
        stroke(c);
        line(0, y, width, y);
    }
}

function terrain(){
    terrainSpeed = 0.0002;
    terrainDetail = 0.006;

    //draw dessert mountain 1
    fill(225, 184, 139);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t1 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y1 = map(noise(t1), 0, 1, 80, height);
        vertex(x, y1);
    }
    vertex(width, height);
    endShape();

    //draw dessert mountain 2
    terrainDetail = 0.007;
    fill(225, 164, 109);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t1 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y1 = map(noise(t1), 0, 1, 100, height);
        vertex(x, y1);
    }
    vertex(width, height);
    endShape();

    //draw ground
    terrainDetail = 0.0005;
    fill(160, 96, 69);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t2 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y2 = map(noise(t2), 0, 1, 180, height);
        vertex(x, y2);
    }
    vertex(width, height);
    endShape();
}

This is a landscape of a desert with different sized cactus along the road and different depth of the scenery.

ilona altman – landscape – project 11

sketch

let flowers = [];
let grass = [];
let clouds = [];

function setup() {
    createCanvas(600,600);
    //inital placement for flowers
    for (let i = 0; i < 50; i++) {
        let firstX = random(width);
        let firstY = random(height);
        flowers[i] = makingFlower(firstX,firstY)
    }
    // inital placement for grass
    for (let gx = 0; gx < 400; gx++) {
        let grassX = random(width);
        let grassY = random(height);
        grass[gx] = makingGrass(grassX,grassY);
    }
    // initial placement for clouds
    for (let j = 0; j < 7; j++)  {
        let cloudx = random(width);
        let cloudy = random(height);
        clouds[j] = makingCloud(cloudx, cloudy);
    }
}

function draw() {
    background(105,130,80);
    //drawing the grass
    updateAndDisplayGrass();
    addingGrass();
    removingGrass();
    //drawing the flowers
    updateAndDisplayflowers();
    addingFlowers();
    removingFlowers();
    // drawing the clouds
    updateAndDisplayClouds();
    addingClouds();
    removingClouds();
}



////////////////////////////////////flowers//////////////////////////
///removing flowers from the array once they go off screen
function removingFlowers() { 
    var keeping = [];
    for (var i = 0; i < flowers.length; i++) {
        if (flowers[i].x + flowers[i].r > 0) {
            keeping.push(flowers[i]);
        }
    }
    flowers = keeping; //keeping certain flowers in the flowers array
}
//update all the flowers in the array
function updateAndDisplayflowers(){
    for (var i = 0; i < flowers.length; i++){
        flowers[i].move();
        flowers[i].display();
    }
}
//adding new flowers to the array according to a certain liklihood
function addingFlowers() {
    var newflowerliklihood = 0.05;
    var initialX = random(width);
    var initialY = 0;
    if (random(0,1) < newflowerliklihood) {
        flowers.push(makingFlower(initialX,initialY));
    }
}
//the flower object
function makingFlower(firstX,firstY) {
    var flr = {x: firstX,
                y: firstY,    
                r: round(random(10,40)),
                move: moveflowers,
                display: showflowers}
    return flr;
}
//specifying the drawing of the flower
function showflowers() {
    noStroke();
    fill(230, 80, 50); //red petals
    ellipse(this.x+3, this.y, 3, 4);
    ellipse(this.x-3, this.y, 3, 4);
    ellipse(this.x, this.y-3, 3, 4); 
    ellipse(this.x, this.y+3, 3, 4);   
    fill(230, 130, 50); // orange center 
    ellipse(this.x, this.y, 5, 5);
    fill(90, 40, 30); // red inner center
    ellipse(this.x, this.y, 1, 1);
}
//speciftying the movement of the flower
function moveflowers() {
    this.y = this.y + 1
}
/////////////////////////////////// grass////////////////////////////////
function removingGrass() {
    var keepingGrass = [];
    for (var i = 0; i < grass.length; i++) {
        if (grass[i].x > -10) {
            keepingGrass.push(grass[i]);
        }
    }
    grass = keepingGrass; 
}
function updateAndDisplayGrass(){
    for (var i = 0; i < grass.length; i++){
        grass[i].move();
        grass[i].display();
    }
}
function addingGrass() {
    var newgrassliklihood = 0.5;
    var initialX = random(width);
    var initialY = 0;
    if (random(0,1) < newgrassliklihood) {
        grass.push(makingGrass(initialX,initialY));
    }
}
function makingGrass(grassX,grassY) {
    var gss = {x: grassX,
                y: grassY,    
                move: moveGrass,
                display: showGrass}
    return gss;
}
function showGrass() {
    strokeWeight(random(1,2));
    stroke(130,160,140);
    line(this.x, this.y, this.x-2, this.y+2);
}
function moveGrass() {
    this.y = this.y + 1
}
/////////////////////clouds///////////////////////////////////////////////
function removingClouds() {
    var keepingClouds = [];
    for (var i = 0; i < clouds.length; i++) {
        if (clouds[i].x > -10) {
            keepingClouds.push(clouds[i]);
        }
    }
    clouds = keepingClouds; 
}
function updateAndDisplayClouds(){
    for (var i = 0; i < clouds.length; i++){
        clouds[i].move();
        clouds[i].display();
    }
}
function addingClouds() {
    var newcloudliklihood = 0.02;
    var initialX = random(width);
    var initialY = 0;
    if (random(0,1) < newcloudliklihood) {
        clouds.push(makingCloud(initialX,initialY));
    }
}
function makingCloud(cloudX,cloudY) {
    var cld = {x: cloudX,
                y: cloudY,    
                move: moveCloud,
                display: showCloud}
    return cld;
}
function showCloud() {
    noStroke();
    fill(150,180,190,20); // light blue
    beginShape();
    vertex(this.x , this.y);
    quadraticVertex(this.x - 236, this.y - 351 , this.x + 7 , this.y - 357);
    bezierVertex(this.x -17, this.y -215, this.x + 132, this.y + 180, this.x, this.y);
    endShape(CLOSE)
}
function moveCloud() {
    this.y = this.y + 3
}




a landscape by Gustav Klimt I was inspired by

For this project, I was really inspired by the prompt of looking outside of a window. I love flowers and the peacefulness of watching clouds pass. I also love the colors in Gustav Klimpt’s landscapes, so I really wanted to incorporate this into my project, as well as get some practice drawing curves.

Julia Nishizaki – Project 11 – Landscape

sketch

//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project 11 - Generative Landscape

var landscapeScale = 0.005; //detail in hills
var landscapeSpeed = 0.00075; //speed of hills going by
var hillColor = '#92CA6D'; //light green

var houses = []; //array for houses
var trees = []; //array for trees

var train = { ////train variables
    wY: 200, //Y of windows
    wW: 325, //width of windows
    wH: 275, //height of windows
    corners: 30, //roundness of window corners
    wWeight: 25, //stroke weight of light gray
    backgroundColor: 255, //white
    mainColor: '#475AA8', //light blue
    wColor: '#2A357A', //dark blue, color of window and seats
    divXL: 61, //X coordinate of left divider
    divXR: 419, //X coordinate of right divider
}

function setup() {
    createCanvas(480, 480);
    for (var i = 0; i < 5; i ++) { //first houses
        var rx = random(width);
        houses[i] = makeHouses(rx);
    }
    for (var i = 0; i < 3; i ++) { //first trees
        var tx = random(width);
        trees[i] = makeTrees(tx);
    }
    frameRate(30);   
}

function draw() {
    background('#8ED9EF'); //blue sky
    //creates hills in the background
    stroke(hillColor);
    for (var x = 0; x < width; x ++) {
        var l = (x * landscapeScale) + (millis() * landscapeSpeed);
        var y = map(noise(l), 0, 1, 100, 230); //constrains hills
        line(x, y, x, height); //creates vertical lines, forming a solid shape
    }
    displayHouses(); //houses
    removeOldHouses();
    addHouses();

    displayTrees(); //trees
    removeOldTrees();
    addTrees();

    drawTrain(); //train
}

function displayHouses() { //displays and updates house location
    for (var i = 0; i < houses.length; i ++) {
        houses[i].move();
        houses[i].draw();
    }
}
function removeOldHouses() { //gets rid of old houses, puts the houses that are still on the canvas in a new array
    var housesToKeep = [];
    for (var i = 0; i < houses.length; i ++) {
        if (houses[i].x + houses[i].breadth > 0) {
            housesToKeep.push(houses[i]);
        }
    }
    houses = housesToKeep;
}
function addHouses() { //adds new houses into the array
    if (random(0, 1) < 0.02) {
        houses.push(makeHouses(width));
    }
}
function moveHouses() { //moves the houses
    this.x += this.speed;
    if (this.x < -this.breadth) {
        this.x == width + this.breadth;
    }
}
function drawHouses() { //draws the houses
    noStroke();
    rectMode(CORNER);
    fill(this.r, this.g, this.b); //randomizes color
    push();
    translate(this.x, this.y);
    rect(0, -this.height, this.breadth, this.height); //house rectangle
    //roof
    fill(255);
    triangle(-2, -this.height + 1, this.breadth + 2, -this.height + 1, this.breadth / 2, -this.height - this.roofH);
    //door
    rect(this.doorX, - this.doorH, this.doorW, this.doorH);
    pop();
}
function makeHouses(locationX) { //house variables
    var hse = {x: locationX,
               y: random(225, 275),
               r: random(255),
               g: random(255),
               b: random(255),
               roofH: round(random(10, 25)),
               height: round(random(25, 50)),
               breadth: round(random(30, 60)),
               doorX: random(10, 20),
               doorW: 10,
               doorH: 15,
               speed: -6.0,
               move: moveHouses,
               draw: drawHouses}
    return hse;
}

//trees
function displayTrees() { //dispays and updates tree locations
    for (var i = 0; i < trees.length; i ++) {
        trees[i].movet();
        trees[i].drawt();
    }
}
function removeOldTrees() { //gets rid of old trees
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i ++) {
        if (trees[i].xt + trees[i].breadtht > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}
function addTrees() { //adds new trees
    if (random(0, 1) < 0.1) {
        trees.push(makeTrees(width));
    }
}
function moveTrees() { //moves trees
    this.xt += this.speedt;
    if (this.xt < -this.breadtht) {
        this.xt == width + this.breadtht;
    }
}
function drawTrees() { //draws trees
    noStroke();
    rectMode(CORNER);
    colorMode(HSB, 100); //switches color mode to HSB to assist with random colors
    fill(this.ht, 55, this.bt); //random colors between yellow-green to green
    push();
    translate(this.xt, height * 3 / 4);
    rect(0, -this.heightt, this.breadtht, this.heightt, 50, 50, 0, 0);
    pop();
}
function makeTrees(locationX) { //tree variables
    var trs = {xt: locationX,
               bt: random(50, 85),
               ht: random(17, 25),
               heightt: round(random(50, 160)),
               breadtht: round(random(100, 130)),
               speedt: -10.0,
               movet: moveTrees,
               drawt: drawTrees}
    return trs;
}

//train
function drawTrain() {
    colorMode(RGB);
    drawWindow(width / 2); //draws center window
    drawWindow(-118); //draws left window
    drawWindow(width + 118); //draws right window
    //light blue panels
    noStroke();
    rectMode(CORNER);
    fill(train.mainColor);
    rect(0, 0, width, train.wY - (train.wH / 2) - 10); //top panel
    rect(0, train.wY + (train.wH / 2) + 10, width, height - (train.wY + (train.wH / 2)) - 10); //bottom panel
    //seats
    drawSeats(train.divXL, 0, 0, 40); //left seat
    drawSeats(train.divXR, width - 200, 40, 0); //right seat
    //table
    rectMode(CENTER);
    rect(width / 2, height - 105, 150, 20, 5, 5, 5, 5);
    //section dividers, light gray
    drawDividers(train.divXL);
    drawDividers(train.divXR);
}
function drawWindow(x) { //creates center window
    rectMode(CENTER);
    noFill();
    stroke(train.backgroundColor); //creates light gray area around the windows
    strokeWeight(train.wWeight);
    rect(x, train.wY, train.wW + train.wWeight, train.wH + train.wWeight, train.corners, train.corners, train.corners, train.corners);
    stroke(train.wColor); //creates blue window border
    strokeWeight(10);  
    rect(x, train.wY, train.wW, train.wH, train.corners, train.corners, train.corners, train.corners);
}
function drawSeats(x1, x2, UL, UR) {
    fill(train.wColor);
    rect(x1 - 45, height - 200, 90, 200, 30, 30, 0, 0); //seat back
    rect(x2, height - 50, 200, 50, UL, UR, 0, 0); //left seat cushions
}
function drawDividers(x) {
    strokeWeight(5);
    stroke(200);
    line(x, train.wY - (train.wH / 2) - 7.5, x, height); //line dividing sections
}

For this project, I wanted to create a landscape outside of a train window. I decided to use three layers, some bushes or trees in the foreground, houses in the middle ground, and hills in the background. I tried to change the speeds of the different layers, with the tree layer the fastest and the hill layer the slowest, in order to give the illusion of perspective, and that you’re looking out of a window as everything flies by.

Sydney Salamy: Project-11-Landscape

I had started out wanting to do a sunset, with the view of a car driving by it. I didn’t want to create a jagged moving landscape, so I decided to do a desert instead. I was first going to make cactuses, but then I made the ground black and realized I wanted a more futuristic look. So I decided my image would have the sunset, black ground, and then geometric shapes with their shadows. Because I had used the bezier() function in the past, I decided to use that for the sunset, having the anchor parts react with the sun, almost like the sky was melting. 

During the project I changed my objects from pyramids to stars to, finally, sailboats. I added to the black water horizon, putting color lines under the sun to look like a water reflection, and adding vertical lines to the water with an invisible ball pushing them to look like the boats were pushing the current.

My rough sketch

sketch

var quarW = 120;//width divided by 4
var quarW2 = 360;//qaurW times 3
var bezH = 40;//height of bezier anchors
var bezW = 48;//width of ground bezier anchors
var bezWS = 48;//width of ground bezier side points
var sunX = 240;//x value placement of sun in sky
var sunH = 100;//height of sun in sky
var currX = 480;//x placement of horizontal circle
var bzHorLn1 = 360;//horizon line of the bezier anchors
var bzHorLn2 = 360;//horizon line of the bezier anchors
var bzHorLn3 = 360;//horizon line of the bezier anchors
var bzHorLn4 = 360;//horizon line of the bezier anchors
var bzHorLn5 = 360;//horizon line of the bezier anchors
var bzHorLn6 = 360;//horizon line of the bezier anchors
var bzHorLn7 = 360;//horizon line of the bezier anchors
var bzHorLn8 = 360;//horizon line of the bezier anchors
var horLn = 360;//horizon line of the bezier non anchors

var boats = [];

function setup() {
    createCanvas(480, 480); 
    frameRate(10);//faster framerate
    // create an initial collection of boats
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        boats[i] = makeBoat(rx);
    }
    frameRate(20);
}

function draw() {
    background(38,59,103);//dark blue
    
    fill(244,182,103);//brighter orange
    bezier(0,320, quarW,bezH * 8, quarW2,bezH * 8, 480,320);//8
    fill(213,131,87);//bright orange
    bezier(0,280, quarW,bezH * 7, quarW2,bezH * 7, 480,280);//7
    fill(185,106,82);//orange
    bezier(0,240, quarW,bezH * 6, quarW2,bezH * 6, 480,240);//6
    fill(207,63,57);////bright orange
    bezier(0,200, quarW,bezH * 5, quarW2,bezH * 5, 480,200);//5
    fill(167,62,72);//bright pink
    bezier(0,160, quarW,bezH * 4, quarW2,bezH * 4, 480,160);//4
    fill(141,80,94);//pink
    bezier(0,120, quarW,bezH * 3, quarW2,bezH * 3, 480,120);//3
    fill(93,80,109);//purple
    bezier(0,80, quarW,bezH * 2, quarW2,bezH * 2, 480,80);//2
    fill(67,88,122);//blue
    bezier(0,40, quarW,bezH, quarW2,bezH, 480,40);//1
    
    //-------------------------------SUN
    push();
    fill(0);
    ellipse(sunX, sunH, 200,200);
    pop();
    sunH += 5;//sun speed
    if(sunH > height + 100) {//resets sun placement if it moves past canvas
        sunH = -100;
    }
    if(dist(sunX,sunH, quarW,quarW) < 210){//pushes down sunset blocks
        bezH += 3;
    } 
    noFill();
    if(dist(sunX,sunH, horLn,horLn) < 170){//pushes down susnet lines
        bzHorLn1 += .05;
        bzHorLn2 += .1;
        bzHorLn3 += .15;
        bzHorLn4 += .2;
        bzHorLn5 += .25;
        bzHorLn6 += .3;
        bzHorLn7 += .35;
        bzHorLn8 += .4;
    } 
    //-------------------------------
    //-------------------------------GROUND
    push();
    fill(0);
    stroke(0);
    rect(0,360, 480,130);
    stroke(255);
    //vertical lines on black area
    stroke(255);
    strokeWeight(.1);
    bezier(bezWS,360, bezW,400, bezW,440, bezWS,480);
    bezier(bezWS * 2,360, bezW * 2,400, bezW * 2,440, bezWS * 2,480);
    bezier(bezWS * 3,360, bezW * 3,400, bezW * 3,440, bezWS * 3,480);
    bezier(bezWS * 4,360, bezW * 4,400, bezW * 4,440, bezWS * 4,480);
    bezier(bezWS * 5,360, bezW * 5,400, bezW * 5,440, bezWS * 5,480);
    bezier(bezWS * 6,360, bezW * 6,400, bezW * 6,440, bezWS * 6,480);
    bezier(bezWS * 7,360, bezW * 7,400, bezW * 7,440, bezWS * 7,480);
    bezier(bezWS * 8,360, bezW * 8,400, bezW * 8,440, bezWS * 8,480);
    bezier(bezWS * 9,360, bezW * 9,400, bezW * 9,440, bezWS * 9,480);
    pop();
    //horizontal sunset lines
    push()
    stroke(244,182,103);//brighter orange
    bezier(140,horLn, 190,bzHorLn1, 290,bzHorLn1, 340,horLn);
    stroke(213,131,87);//bright orange
    bezier(140,horLn, 190,bzHorLn2, 290,bzHorLn2, 340,horLn);
    stroke(185,106,82);//orange
    bezier(140,horLn, 190,bzHorLn3, 290,bzHorLn3, 340,horLn);
    stroke(207,63,57);////bright orange
    bezier(140,horLn, 190,bzHorLn4, 290,bzHorLn4, 340,horLn);
    stroke(167,62,72);//bright pink
    bezier(140,horLn, 190,bzHorLn5, 290,bzHorLn5, 340,horLn);
    stroke(141,80,94);//pink
    bezier(140,horLn, 190,bzHorLn6, 290,bzHorLn6, 340,horLn);
    stroke(93,80,109);//purple
    bezier(140,horLn, 190,bzHorLn7, 290,bzHorLn7, 340,horLn);
    stroke(67,88,122);//blue
    bezier(140,horLn, 190,bzHorLn8, 290,bzHorLn8, 340,horLn);
    pop();
    //water current (pushed by invisible ball)
    push();
    fill(50);
    noFill();
    noStroke();
    ellipse(currX,420, 20,20);//current ball
    currX -= 5;//speed of invisible ball
    if(currX < width - 600) {//resets invisible ball if it moves off canvas
        currX = 590;
    }
    if(dist(currX,currX, bezW,bezW) < 210){//moves vertical lines if ball nears
        bezW -= .5;//pushes them forward
    }
    else {
        bezW += .3;//pushes them back after ball leaves
    } 
    pop();

    updateAndDisplayBoats();
    removeBoatsThatHaveSlippedOutOfView();
    addNewBoatsWithSomeRandomProbability(); 
}

function updateAndDisplayBoats(){
    // Update the boats positions, and display them.
    for (var i = 0; i < boats.length; i++){
        boats[i].move();
        boats[i].display();
    }
}

function removeBoatsThatHaveSlippedOutOfView(){
    //If a boat has dropped off the left edge,
    //remove it from the array.  
    //Copy boats I want to keep into a new array.
    var boatsToKeep = [];
    for (var i = 0; i < boats.length; i++){
        if (boats[i].x + boats[i].breadth > 0) {
            boatsToKeep.push(boats[i]);
        }
    }
    boats = boatsToKeep; // remember the surviving boats
}

function addNewBoatsWithSomeRandomProbability() {
    // With a very tiny probability, add a new boats to the end.
    var newBoatLikelihood = 0.009; 
    if (random(0,1) < newBoatLikelihood) {
        boats.push(makeBoat(width));
    }
}

function boatMove() {//method to update position of boat every frame
    this.x += this.speed - 3;
}
    
function boatDisplay() {//draw the boat and some windows
    var floorHeight = 10;
    var bHeight = this.hPoles * floorHeight; 
    fill(this.R, this.G, this.B);//star colors
    stroke(0); 
    push();
    translate(this.x, height - 135);
    //boat
    noFill();
    stroke(255);
    bezier(30,67, 50,70, 80,74, 90,73);//top
    line(30,67, 37,83);//front side
    bezier(85,83, 91,80, 90,75, 90,73);//back side
    line(37,83, 85,83);//bottom
    line(60,5 * -bHeight / 60, 60,71);//pole
    triangle(40 / this.sailW,60, 60,5 * -bHeight / 60, 60,60);//flap large
    triangle(60,58, 60,5 * -bHeight / 60, 75 * this.sailW,58);//flap small
    pop();
}

function makeBoat(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 85,
                speed: -1.0,
                sailW: random(1,1.3),
                R: random(142),
                G: random(255),
                B: random(130),
                hPoles: round(random(-5,40)),
                move: boatMove,
                display: boatDisplay}
    return bldg;
}

Nawon Choi— Project 11 Landscape

sketch

// Nawon Choi
// Section C
// nawonc@andrew.cmu.edu
// Project-11 Landscape

// var buildings = [];
var trainCars = [];
var shapes = [];
// canvas height - 50
var yHorizon = 200 - 50;

function setup() {
    createCanvas(480, 200); 
    
    // create an initial train car
    var rw = random(100, 150);
    trainCars.push(makeTrainCar(-50, rw));
        
        
    frameRate(10);
}


function draw() {
    background("#A1C6EA");

    displayHorizon();

    updateAndDisplayTrainCars();
    removeTrainCarsThatHaveSlippedOutOfView();
    addNewCars();

    // railroad sign
    stroke(0);
    strokeWeight(2);
    line(width - 50, height / 3, width - 50, yHorizon);
    fill("yellow");
    ellipse(width - 50, height / 3, 40, 40);
    fill(0);
    textSize(40);
    text("X", width - 62, height / 2.5);

}


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


function removeTrainCarsThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge,
    // remove it from the array.  This is quite tricky, but
    // we've seen something like this before with particles.
    // The easy part is scanning the array to find buildings
    // to remove. The tricky part is if we remove them
    // immediately, we'll alter the array, and our plan to
    // step through each item in the array might not work.
    //     Our solution is to just copy all the buildings
    // we want to keep into a new array.
    var carsToKeep = [];
    for (var i = 0; i < trainCars.length; i++){
        if (trainCars[i].x + trainCars[i].w > 0) {
            carsToKeep.push(trainCars[i]);
        }
    }
    trainCars = carsToKeep; // remember the surviving buildings
}

function addNewCars() {
    var l = trainCars.length - 1;
    var newW = floor(random(100, 150));
    var newX = 0 - newW;
    // only add a new car after the last one is completely revealed
    if (trainCars[l].x >= 0) {
        trainCars.push(makeTrainCar(newX, newW));
    }
}


// method to update position of the car every frame
function carMove() {
    this.x += 3;
}
    
function carDisplay() {    
    // draw car body
    fill(this.cr, this.cg, this.cb);
    rect(this.x, yHorizon - (this.h + 3), this.w, this.h);

    // draw wheels
    fill("#6b6e6a");
    if (this.nWheels >= 2) {
        ellipse(this.x + 5, yHorizon, 10, 10);
        ellipse(this.x + this.w - 5, yHorizon, 10, 10);
        if (this.nWheels == 4) {
            ellipse(this.x + 15, yHorizon, 10, 10);
            ellipse(this.x + this.w - 15, yHorizon, 10, 10);
        } else if (this.nWheels == 3) {
            ellipse(this.x + (this.w / 2), yHorizon, 10, 10);
        }
    } 

}

function makeTrainCar(birthLocationX, carWidth) {
    var car = {x: birthLocationX,
                w: carWidth,
                h: floor(random(50, 70)),
                nWindows: floor(random(0, 3)),
                nWheels: floor(random(2, 5)), 
                cr: floor(random(0, 255)),
                cg: floor(random(0, 255)),
                cb: floor(random(0, 255)),
                move: carMove,
                display: carDisplay}
    return car;

}

function displayHorizon(){
    noStroke();
    // grass 
    fill("#3a6933");
    rect(0, yHorizon, width, 50); 

    // train track
    fill("#35524A");
    rect (0, yHorizon, width, 5); 
}

For this project, I tried to create a moving landscape in which the subject was moving, but the viewer was still. I depicted a railroad crossing of train cars with varying widths, heights, colors, and wheel numbers. It was interesting to play with random vs fixed variables. For instance, the train cars had to generate right after the last car, instead of at a random frequency. I also tried to create more visual interest by adding a railroad crossing sign in the foreground. I think if I had more time, I would have added interesting patterns to each car, such as windows or texture to the cars.

Train cars at a railroad crossing

Charmaine Qiu – Project 11 – Generative Landscape


sketch

In this project, I was able to create a generative landscape with customized features. I really enjoyed sceneries that has a complete reflection on a water surface, and decided to create an animation with a mountain and its reflection on the lake. I added a fun component of ducks swimming around to create a fun element.

Brainstorming process

//Charmaine Qiu
//Section E
//charmaiq@andrew.cmu.edu
//Project 11

//set the speed and detail for terrain
var terrainSpeed = 0.0005;
var terrainDetail = 0.008;
//create empty array for ducks on screen
var ducks = [];

function setup() {
    createCanvas(480, 200);
    frameRate(10);
    //set the number of ducks that appears in the beginning randomly on  screen
    for (var i = 0; i <3; i++){
        var rx = random(width);
        ducks[i] = makeDuck(rx);
    }
}

function draw() {
    //set background visuals
    //the sky
    background('#95dddd');
    //the river
    fill('#419696')
    noStroke();
    rect(0, height / 2, width, height);
    //the sun and its reflection
    fill('red');
    ellipse(width - 60, 10, 60, 60);
    fill('#6e1616');
    ellipse(width - 60, height - 10, 60, 60);
    //draw mountain and ripple function
    mountains();
    ripples();

    //draw the ducks
    push();
    translate(0.1 * width, 0.1 * height);
    scale(0.8);

    updateAndDisplayDucks();
    removeDucksThatHaveSlippedOutOfView();
    addNewDucksWithSomeRandomProbability();
    pop();
}

function mountains(){
    //create the mountain
    fill('#e1a952');
    noStroke();
    beginShape();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 0, height / 2);
        vertex(x, y);
    }
    vertex(width, height/2);
    vertex(0, height/2)
    endShape();
    //create the reflection
    fill('#dd5a62');
    beginShape();
    noStroke();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        //inverse the y component to flip the mountain upside-down
        var y = map(noise(t), 0,1, height, height / 2);
        vertex(x, y);
    }
    vertex(width, height/2);
    vertex(0, height/2)
    endShape();
}

function ripples(){
    //create the ripples
    frameRate(7);
    stroke(255);
    //set individual random values for x and y coordinates of ripples
    rX = random(width / 2 - 50, width / 2 + 50);
    rY = random(height / 2 + 10, height);
    rX2 = random(width / 2 - 50, width / 2 + 50);
    rY2 = random(height / 2 + 10, height);
    rX3 = random(width / 2 - 50, width / 2 + 50);
    rY3 = random(height / 2 + 10, height);
    //set individual random values for width and weight of ripples
    rWidth = random(5, 20);
    rWeight = random(1, 4);
    rWidth2 = random(5, 20);
    rWeight2 = random(1, 4);
    rWidth3 = random(5, 20);
    rWeight3 = random(1, 4);
    //draw out the lines of ripples
    strokeWeight(rWeight);
    line(rX, rY, rX + rWidth, rY);
    strokeWeight(rWeight2);
    line(rX2, rY2, rX2 + rWidth2, rY2);
    strokeWeight(rWeight3);
    line(rX3, rY3, rX3 + rWidth3, rY3);


}

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


function removeDucksThatHaveSlippedOutOfView(){
    // copy all the ducks that's kept into a new array.
    var ducksToKeep = [];
    for (var i = 0; i < ducks.length; i++){
        if (ducks[i].x + ducks[i].breadth > 0) {
            ducksToKeep.push(ducks[i]);
        }
    }
    ducks = ducksToKeep; //remember the surviving ducks
}


function addNewDucksWithSomeRandomProbability() {
    // With a very tiny probability, add a new duck to the end.
    var newDuckLikelihood = 0.007;
    if (random(0,1) < newDuckLikelihood) {
        ducks.push(makeDuck(width));
    }
}


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

function duckDisplay() {
    // draw the ducks
    var headHeight = 20;
    fill(255);
    noStroke();
    push();
    //translate duck to lower part of canvas
    translate(this.x, height - 40);
    ellipse(0, -headHeight, this.breadth, headHeight);
    fill(0);
    ellipse(0, -headHeight, 5, 5);
    fill("#70547c");
    arc(10, -10, 30, 30, 0, PI);
    fill("#f8e184");
    arc(10, -10, 10, 10, 0, PI);
    fill("green");
    arc(-10, -20, 10, 10, 0, PI);
    pop();
}

//the function to create the duck object
function makeDuck(birthLocationX) {
    var mdk = {x: birthLocationX,
                breadth: 20,
                speed: -1.0,
                move: duckMove,
                display: duckDisplay}
    return mdk;
}