gyueunp – Project-10: Generative Landscape

Generative Landscape

//GyuEun Park
//15-104
//gyueunp@andrew.cmu.edu
//Project-10

var merry = [];
var drops = [];
var terrainSpeed = 0.0003;
var terrainDetail = 0.008;

function setup() {
    createCanvas(480, 240);
    frameRate(10);
//repeat snow falling 
    for (var j = 0; j < 100; j++) {
    drops[j] = new Drop();
  }
}
 
function draw() {
    background(0,123,100);
    for (var t = 0; t < drops.length; t++) {
    	drops[t].fall();
    	drops[t].show();
    }

//add terrain details, filling the horizontal side of canvas
    noStroke();
    fill(255); 
    beginShape(); 
    for (var x = 0; x < width + 5; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 0, height);
        vertex(x, y); 
    }
    vertex(width,height);
    vertex(0,height);
    endShape();

//"MERRY CHRISTMAS" text details
    updateAndDisplayMerry();
    removeMerry();
    addMerry(); 
}

//snow details 
function Drop() {
  this.x = random(width);
  this.y = random(-9, -500);
  this.z = random(0, 20);
  this.len = map(this.z, 0, 20, 10, 20);
  this.yspeed = map(this.z, 0, 50, 1, 20);

//creating functions for snow movements
  this.fall = function() {
    this.y = this.y + this.yspeed;
    var grav = map(this.z, 0, 10, 0, 0.1);
    this.yspeed = this.yspeed + grav;

    if (this.y > height) {
      this.y = random(-200, -100);
      this.yspeed = map(this.z, 0, 20, 4, 10);
    }
  }

  this.show = function() {
    var thick = map(this.z, 0, 1, 0.9, 1);
    strokeWeight(thick);
    stroke(255,random(100,200));
    line(this.x, this.y, this.x, this.y+this.len);
  }
}

function updateAndDisplayMerry(){
//update the text's positions and display 
    for (var i = 0; i < merry.length; i++){
        merry[i].move();
        merry[i].display();
    }
}

function removeMerry(){
    var merryToKeep = [];
    for (var i = 0; i < merry.length; i++){
        if (merry[i].x > 0 & merry[i] < height) {
            merryToKeep.push(merry[i]);
        }
    }
    merry = merryToKeep; 
}

function addMerry() {
    var newMerryLikelihood = 5 ; 
    if (random(0,1) < newMerryLikelihood) {
        merry.push(makeMerry(random(0,width),0));
    }
}

function merryMove() {
    this.x += this.speedx;
    this.y += this.speedy;
}

function merryDisplay() {
	var merryX = this.x;
	var merryY = this.y;
	textSize(random(0,70));
	fill(random(100,255),0,0);
	text("MERRY CHRISTMAS", merryX, merryY+random(20,100));
	fill(255);

//asterisks for small decoration 
	text("*", merryX, merryY+random(0,100));
	text("*", merryX, merryY+random(200,300));
}

function makeMerry(birthLocationX,birthLocationY) {
    var merry = {x: birthLocationX,
    			y: birthLocationY,
                speedx: -4.0,
                speedy: 1.0,
                move: merryMove,
                display: merryDisplay}
    return merry;
}

I created a Christmas-themed landscape in anticipation for the holiday. The background and the text contrast drastically in its stagnancy and chaotic motion, respectively. However, they not only complement each other in terms of the coloration, but also work together to represent Christmas. The other two elements, the terrain and snow, are similar in that they are both white, highlighting the objects of complementary colors. Yet, the terrain travels horizontally, while snow is falling in a vertical motion. I’m wishing for a white Christmas ♥

sketch:

.

ifv-Project-10-Landscape

sketch

//Isabelle Vincent
//Section E
//ifv@andrew.cmu.edu
//Project-10
var buildings = [];
var persons = [];

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

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


function draw() {
    background(200);

    displayStatusString();
    displayHorizon();

    updateAndDisplayBuildings();
    updateAndDisplayPersons();
    print(persons.length);
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability();
    removePersonsThatHaveSlippedOutOfView();
    addNewPersonsWithSomeRandomProbability();
}


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

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


function removeBuildingsThatHaveSlippedOutOfView(){
    // 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 buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep; // remember the surviving buildings
}

function removePersonsThatHaveSlippedOutOfView(){

    var personsToKeep = [];
    for (var i = 0; i < persons.length; i++){
        if (persons[i].x + persons[i].thick > 0) {
            personsToKeep.push(persons[i]);
        }
    }
    persons = personsToKeep; // remember the surviving people (tragic)
}


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

function addNewPersonsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newPersonLikelihood = 0.007;
    if (random(0,1) < newPersonLikelihood) {
        persons.push(makePerson(width));
    }
}


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

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

// draw the building and some windows
function buildingDisplay() {
    var floorHeight = 20;
    var roofHeight = random(8,20);
    var bHeight = (this.nFloors * floorHeight)/2;
    fill(35, 28, 64);
    noStroke();
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    triangle(-20, -bHeight,this.breadth/2,(bHeight)-height,this.breadth+20,-bHeight);

    pop();
}

function personDisplay() {
    var headSize = 15;
    var bodyheight = this.tall;
    var bodythick = this.thick;
    var headCenter = bodyheight+headSize/2;
    var bodyCenter = bodyheight/2;
    fill(198, 28, 64,90);
    noStroke();
    push();
    translate(this.x,this.y);
    ellipseMode(CENTER);
    ellipse(0,-bodyCenter,bodythick,bodyheight);
    ellipse(0,-headCenter,headSize,headSize);
    pop();
}

function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 15,
                speed: -1.0,
                nFloors: round(random(2,8)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function makePerson(birthLocationX){
  var person = {x: birthLocationX,
              y:height-50,
              tall: random(30,60),
              thick: random(15,40),
              speed: -1.0,
              eyeballs: random(1,4),
              move: personMove,
              display: personDisplay}
  return person;
}

function displayHorizon(){

  noStroke();

  var green = color(198, 28, 64);
  var yellow = color(229, 199, 31);

  var gradientSteps = 20;//how detailed will the gradient be
  var gradientStripWidth = width/gradientSteps;//compute how many strips of the same width to fill the sketch

  for(var i = 0; i < gradientSteps; i++){//for each gradient strip
    var t = map(i,0,gradientSteps,0.0,1.0);//compute i mapped from 0-gradientSteps to 0.0->1.0
    //this value will plug into lerpColor which does the color interpolation
    var interpolatedColor = lerpColor(green,yellow,t);
    //finally, use the color and draw some boxes
    fill(interpolatedColor);
    rect(0,i*gradientStripWidth,height,gradientStripWidth);
  }

    fill(35, 28, 64);
    rectMode(CORNER);
    rect(0,height-50,width,height-50)
}


function displayStatusString(){
    noStroke();
    fill(0);
    var statusString = "# Buildings = " + buildings.length;
    text(statusString, 5,20);
}

I wanted to make a haunted forest because I’m sad halloween has ended. The trees are sparse and skinny because they are based on the trees I remember in a certain forest in Oregon. I decided to make the ghosts a a transparent version of the red in the sky instead of white (which most people default to) bc it has better visual harmony.

sijings-project10- Generative Landscape

sijings_ GenerativeLandscape

//Clair(sijing) Sun
//session C
//sijings@andrew.cmu.edu
//GenerativeLandscape

var frames = [];
var frameeys=[];
var humans=[];
var cakes = [];
var frames2 = [];
var r=220;


function setup() {
    createCanvas(480, 240);
    var x=width/2;
    var y=height/2;
    var x1;
    var y1;
    
    // create an initial collection of humans
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        humans[i] = makeHuman(rx);
    }

    for (var i2 = 0; i2 < 5; i2++){
        var rx2 = random(0,5);
        cakes[i2] = makeCake(rx2);
    }
    frameRate(10);


}

function preload(){
    var filenames = [];
    filenames[0] = "https://i.imgur.com/SqI6peg.png";
    filenames[1] = "https://i.imgur.com/045MUOm.png";
    filenames[2] = "https://i.imgur.com/fQHcLAX.png";
    filenames[3] = "https://i.imgur.com/8xnKXdV.png";
    filenames[4] = "https://i.imgur.com/RXbcttI.png";
    
    for (i=0; i<filenames.length; i++){//create a new arrary for humans
        frames.push(loadImage(filenames[i]));
    }

    frames2.push(loadImage("https://i.imgur.com/4Li0MwV.png"));
    frames2.push(loadImage("https://i.imgur.com/DPquy2W.png"));
    var filenames2 = [];
    filenames2[0]="https://i.imgur.com/eKURFcs.png";
    filenames2[1]="https://i.imgur.com/6khWp0b.png";
    filenames2[2]="https://i.imgur.com/ftnXNpy.png";
    filenames2[3]="https://i.imgur.com/GUpBr3X.png";
    for (i=0; i<filenames2.length; i++){
        frameeys.push(loadImage(filenames2[i]));//create a new arrary for eyes
    }
}


function draw() {
    background(222,212,212); 
    fill(206,119,44);
    angleMode(DEGREES);
    push();
    noStroke();
    arc(width/2, -40, 390, 390, 0, 180,90);
    pop();
    for (var i2=0; i2<18; i2++){//for drawing the sound's light rays
        x=width/2+sin((360/18)*i2)*r;
        y=-10+cos((360/18)*i2)*r;
        x1=width/2+sin((360/18)*i2)*(r-20);
        y1=-10+cos((360/18)*i2)*(r-20);
        stroke(157,82,32);
        strokeWeight(6);
        line(x, y, x1, y1);
    }
    push();
    scale(0.5,0.5);
    translate(-60,0);
    image(frameeys[frameCount%4], width/2+30, -30);//for the eyes animation
    pop();
    push();
    addNewCake();//call these functions in setup so it is actually get called
    updateHumansandCakes();
    removecakeandhuman();
    addNewHuman(); 
    pop();

    
}


function updateHumansandCakes(){
    // Update the building's positions, and display them.
    for (var i = 0; i < humans.length; i++){
        humans[i].move();
        humans[i].display();
    }
    for (var i2 = 0; i2 < cakes.length; i2++){
        cakes[i2].move2();
        cakes[i2].display2();
    }
}


function removecakeandhuman(){//to remove the cakes and humans which are off the canvas
    var lakesToKeep = [];
    for (var i2 = 0; i2 < cakes.length; i2++){
        if (cakes[i2].x2 + cakes[i2].breadth2 > 0) {
            lakesToKeep.push(cakes[i2]);
        }
    }
    cakes = lakesToKeep; 
    var buildingsToKeep = [];
    for (var i = 0; i < humans.length; i++){
        if (humans[i].x1 + humans[i].breadth > 0) {
            buildingsToKeep.push(humans[i]);
        }
    }
    humans = buildingsToKeep; // remember the surviving buildings
    
}

function addNewCake(){
    var newCakeLikelihood1 = 0.01; //make possibility lower
    if (random(0,1) < newCakeLikelihood1) {
        var randompos1=-5;
        cakes.push(makeCake(randompos1));
    }
}

function addNewHuman() {
    // With a very tiny probability, add a new building to the end.
    var newHumanLikelihood = 0.6; //higher possibility
    if (random(0,1) < newHumanLikelihood) {
        var randompos=random(-5,0);
        humans.push(makeHuman(randompos));        
    }
}

//update position of building every frame
function humanMove() {
    this.x1 += this.speed1;
}
function cakeMove(){
    this.x2 += this.speed2;
}

function lakeDisplay(){
    push();
    translate(this.x2,50);//note here translate has to be inside of push so that
    scale(this.scaleS,this.scaleS);//new objects won't be added out side of the
    image(frames2[0],0,height-10);//canvas instead, they will be added inside
    translate(-650,300);
    image(frames2[1],40,height-10);
    pop();

}


//reconmded to create a new object for a separate image
function makeCake(lakeLocationX){//similar as creating the object below
    var cake = {x2:lakeLocationX,
                speed2 : random(1,2.5),
                move2: cakeMove,
                breadth2: 50,
                scaleS: random(0.1,0.5),
                display2 : lakeDisplay}
    return cake;
}



// display the pedestrian
function humanDisplay() {
    push();
    translate(this.x1,this.floatHeight);
    var framesC = frameCount % 5; //animating the birds
    scale(this.scaleS2,this.scaleS2);
    image(frames[framesC],0,0);// the birds will flap their wings staggered

    pop();
}

function makeHuman(birthLocationX) {//create the human object with below properties
    var pedestrian = {x1: birthLocationX,
                speed1: random(5,10),
                floatHeight: random(40,150),//for some going a little bit higer than others
                breadth: 50,
                nFloors: round(random(2,8)),
                scaleS2: random(0.05,0.15),//for some is larger than others
                move: humanMove,
                display: humanDisplay}
    return pedestrian;//remember to return the object
}




For this project, I was aiming for creating a city landscape where odd, strange things happen as well as normal people walking on the street. The inspiration comes from the idea how people sometimes walk on the street and won’t give too much attention on what’s happening around them. To achieve this idea, I created two objects, one for the pedestrian and the other for all other moving objects (b/c they have different speed and position, so I think it is easier to have them on two different objects). Some randomization here is the location, size, and speed of the individuals in the object. For example, each pedestrian is walking in a different speed. Here is the sketch for the city landscape I imagined.

For this project, I got to learn how to use object much clearly. Also, I also find that loading frames is a really useful strategy for creating cool visual elements.

Here are two screenshot for the original dimention I was working on.

cduong-project 10-Landscape

sketch

var skyColor;
var skyColor1;
var skyColor2;
var skyFadeValue = 0;
var skyFadeSpeed = 0.05;

var umbrellas = [];

var beachgoers = [];

function setup() {
    createCanvas(480, 400);
    frameRate(30);

    //CHANGING SKY COLOR VARIABLES
    skyColor1 = color(211, 232, 252); //Light Blue Color (Morning)
    skyColor2 = color(48, 70, 92); //Dark Blue Color (Night)
    skyColor = skyColor1;

    //INITIALIZE UMBRELLAS
    for (var i = 0; i < 10; i++){
     var rx = random(width);
     umbrellas[i] = makeUmbrella(rx);
 }
}

//CHANGING SKY COLOR CODE
function changingSkyColor() {
	skyFadeVal = ((millis()*skyFadeSpeed)%900)/900;
	if (floor(millis()/900*skyFadeSpeed)%2 == 0) {
		skyColor = lerpColor(skyColor1, skyColor2, skyFadeVal);   //Morning to Night
	}
	else {
		skyColor = lerpColor(skyColor2, skyColor1, skyFadeVal);   //Night to Morning
	}
}
//CHANGING SKY COLOR CODE

//UPDATE AND DISPLAY CODE
function updateAndDisplayUmbrellas(){
    // Update the building's positions, and display them.
    for (var i = 0; i < umbrellas.length; i++){
        umbrellas[i].move();
        umbrellas[i].display();
    }
}

//UPDATE AND DISPLAY CODE

//REMOVE OUT OF VIEW
function removeUmbrellasThatHaveSlippedOutOfView(){
  var umbrellasToKeep = [];
  for (var i = 0; i < umbrellas.length; i++){
      if (umbrellas[i].x + umbrellas[i].breadth > 0) {
          umbrellasToKeep.push(umbrellas[i]);
      }
  }
  umbrellas = umbrellasToKeep; // remember the surviving buildings
}
//REMOVE OUT OF VIEW

//ADD RANDOM NEW THINGS
function addNewUmbrellasWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newUmbrellaLikelihood = 0.007;
    if (random(0,1) < newUmbrellaLikelihood) {
        umbrellas.push(makeUmbrella(width));
    }
}
//ADD RANDOM NEW THINGS

//UPDATE POSITION TO BUILDING EVERY FRAME
function umbrellaMove() {
    this.x += this.speed;
}
//UPDATE POSITION TO BUILDING EVERY FRAME

// DRAW THINGS
function umbrellaDisplay() {
    var floorHeight = 3;
    var bHeight = this.nFloors * floorHeight;
    fill(0);
    stroke(0);

    //Umbrellas Row 2
    push();
    translate(this.x, height - 160);  //Location of Umbrella
    rect(0, -bHeight, this.breadth, bHeight); //Umbrella Stick
    stroke(255);
    fill(43, 71, 99)
    arc(1, -bHeight, 30, 20, PI, 0, PI);  //Umbrella Top
    pop();

    //Beachgoers
    push();
    noStroke();
    translate(this.x * 2, height - 130);  //Location of People
    ellipse(0, -bHeight, this.breadth, bHeight / 2); //Body
    ellipse(0, -bHeight - 8, 5, 5); //Head
    pop();

    //Umbrellas Row 1
    push();
    translate(this.x * 1.5, height - 100);  //Location of Umbrella
    rect(0, -bHeight, this.breadth, bHeight); //Umbrella Stick
    stroke(255);
    fill(43, 71, 99)
    arc(1, -bHeight, 30, 20, PI, 0, PI);  //Umbrella Top
    pop();
}
// DRAW THINGS

//MAKE THINGS
function makeUmbrella(birthLocationX) {
    var umb = {x: birthLocationX,
                breadth: 2,
                speed: -1.6,
                nFloors: round(random(2, 10)),
                move: umbrellaMove,
                display: umbrellaDisplay}
    return umb;
}
//MAKE THINGS


//MOUNTAINS
function drawMountain(){
  noStroke();
  var mountainDetail = 0.01;
  var mountainSpeed = 0.0001;

//MOUNTAINS (Back)
  fill(204, 216, 133); //dark Green color
  beginShape();
    for (x = 0; x < width; x++) {
      var t = (x * mountainDetail) + (millis() * mountainSpeed);
      var y = map(noise(t), 1, 0, 10, 50);
      vertex(x, y);
      vertex(0,height);
      vertex(width,height);
    }
  endShape();
//MOUNTAINS (Back)

//MOUNTAINS (Front)
  fill(234, 230, 161); //Green color
  beginShape();
    for (x = 0; x < width; x++) {
      var t = (x * mountainDetail) + (millis() * mountainSpeed);
      var y = map(noise(t), 0, 1, 30, 150);
      vertex(x, y);
      vertex(0,height);
      vertex(width,height);
    }
  endShape();
}
//MOUNTAINS (Front)
//MOUNTAINS

//GROUND (Sand)
function displaysand(){   //try to make it wavy ish
    noStroke(0);
    fill(251, 249, 231);  //Sandy Tan Color
    rect(0, height-180, width, height);
}
//GROUND (Sand)

//WAVES
function drawWaterWaves(){
  noStroke();

  fill(157, 204, 190);
  rect(0, height-80, width, height);
}
//WAVES


function draw() {
    background(skyColor);

    //CHANGING SKY COLOR
    changingSkyColor();

    //MOUNTAINS
    drawMountain();

    //FLOOR
    displaysand();

    //WATER
    drawWaterWaves();

    //UMBRELLAS
    updateAndDisplayUmbrellas();
    removeUmbrellasThatHaveSlippedOutOfView();
    addNewUmbrellasWithSomeRandomProbability();

}

I’ve been feeling homesick lately and I know I won’t be able to go back home til possibly next summer so I wanted to make something that reminded me of home, hence, the beach!! And there’s always a lot of tourists at the beach, especially the one I live close to, and it’s always really hot and sunny, hence the umbrellas, so voila!!

rsp1-Project-10 – Landscape

sketch

/*Rachel Park
rsp1@andrew.cmu.edu
Section B @ 10:30AM
Project 10: Generative Landscapes*/

var sushiArray = [];
var sushiFrames = 0;
var sushiFrequency = 110;

function setup() {
  createCanvas(500,200);
  background(252,245,229);

  frameRate(10);
}

function draw() {
  setting();
  drawBelt();

  updateSushi();
  displaySushi();
  addSushi();
  makeSushi();
  moveSushi();


}

function updateSushi() {
  for (var i = 0; i < sushiArray.length; i++){
    sushiArray[i].move();
    sushiArray[i].display();
  }
}
function addSushi() {
  var a = random(1);
  if (a < 0.05) {
    sushiArray.push(makeSushi(width));
  }
}

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

function displaySushi() {
  push();
  translate(this.x, this.height);
  for (var i = 0; i < this.number; i++){
    drawSushi();
  }
  pop();
}

//sushi
function drawSushi(){
  noStroke();
  fill(210);
  ellipse(20, height/2+25,35,35);//plate..?? how to make sushi move sideways?
  fill(255);
  rect(13,height/2+20,15,10,5);
  fill('red');
  rect(13,height/2+15,15,10,5);
}

function makeSushi(posX) {
  var sushi2 = {x: posX,
                number: floor(random(1,3)),
                speed: -4,
                height: 10,
                move: moveSushi,
                display: displaySushi}
  return sushi2;
}


//setting/background context
function setting() {
  for (var i = 0; i < 5; i++){
  noStroke();
  fill(139,33,12);
  rect(width/5*i+25,height/2-55,45,75,5);//chairs
  }
}

//conveyor belt
function drawBelt() {
  noStroke();
  fill(138,138,137);
  rect(0, height/2-20, width, 90);
  fill(0);
  rect(0, height/2-10, width, 70);
}

I decided to take a little spin off the landscape project and made a moving conveyor belt that brings out little plates of sushi. I wanted to apply the same concept of the moving landscape to a more real-life situation and perhaps make it a bit more amusing.

sketch
screencap of running code

 

merlebac Project-10

Generative Landscape

// Matthew Erlebacher
// Section B
// merlebac@andrew.cmu.edu
// Project-10

var stars = [];
var planets = [];


function setup() {
    createCanvas(480, 480); 
    
    // create an initial collection of stars
    for (var i = 0; i < 100; i++){
        var rx = random(width);
        stars[i] = makeStar(rx);
    }
    // create an initial collection of planets
    for (var i = 0; i < 3; i++){
        var rx = random(width);
        planets[i] = makePlanet(rx);
    }
    frameRate(10);
}


function draw() {
    background(0); 

    updateAndDisplayStars();
    removeStarsThatHaveSlippedOutOfView();
    addNewStarsWithSomeRandomProbability();

    updateAndDisplayPlanets();
    removePlanetsThatHaveSlippedOutOfView();
    addNewPlanetsWithSomeRandomProbability();

    fill(125);
    rectMode(CENTER);
    rect(120, mouseY, 10, 70);
    // Creates laser holder
    fill(0, 0, 255);
    rect(125, mouseY + 35, 40, 10);
    // Creates lower laser
    rect(125, mouseY - 35, 40, 10);
    // Creates upper laser
    quad(80, mouseY + 20, 60, mouseY + 20, 30, mouseY + 40, 50, mouseY + 40);
    // Creates lower fin
    quad(80, mouseY - 20, 60, mouseY - 20, 30, mouseY - 40, 50, mouseY - 40);
    // Creates upper fin
    ellipse(160, mouseY, 60, 40);
    // Creates cockpit
    fill(0);
    ellipse(160, mouseY, 50, 30);
    // Creates cockpit window
    fill(125);
    rect(110, mouseY, 100, 40);
    // Creakes body
    fill(0);
    textAlign(CENTER);
    textSize(18);
    text("MATTHEW", 110, mouseY + 5);
}

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

function removeStarsThatHaveSlippedOutOfView(){
    // If a star 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 stars
    // 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 stars
    // we want to keep into a new array.
    var starsToKeep = [];
    for (var i = 0; i < stars.length; i++){
        if (stars[i].x + stars[i].breadth > 0) {
            starsToKeep.push(stars[i]);
        }
    }
    stars = starsToKeep; // remember the surviving stars
}


function addNewStarsWithSomeRandomProbability() {
    // With a very tiny probability, add a new star to the end.
    var newStarLikelihood = 0.07; 
    if (random(0,1) < newStarLikelihood) {
        stars.push(makeStar(width));
    }
}


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


// draw the star and some windows
function starDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors;

    fill(255); 
    stroke(0); 
    push();
    translate(this.x, height);
    beginShape();
    vertex(0, -bHeight);
    // Upper point of star
    vertex(0 + 2, -bHeight + 6);
    vertex(0 + 8, -bHeight + 6);
    // Right point of star
    vertex(0 + 3, -bHeight + 9);
    vertex(0 + 4, -bHeight + 16);
    // Lower right point of star
    vertex(0, -bHeight + 11);
    vertex(0 - 4, -bHeight + 16);
    // Lower left point of star
    vertex(0 - 3, -bHeight + 9);
    vertex(0 - 8, -bHeight + 6);
    // Left point of star
    vertex(0 - 2, -bHeight + 6);
    endShape();
    // Creates star shape
    pop();
}


function makeStar(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 50,
                speed: -1.0,
                nFloors: round(random(0, height)),
                // I changed the range of possible values to the entire height of the canvas
                move: starMove,
                display: starDisplay}
    return bldg;
}


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


function removePlanetsThatHaveSlippedOutOfView() {
    // If a planet 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 planets
    // 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 planets
    // we want to keep into a new array.
    var planetsToKeep = [];
    for (var i = 0; i < planets.length; i++){
        if (planets[i].x + planets[i].breadth > 0) {
            planetsToKeep.push(planets[i]);
        }
    }
    planets = planetsToKeep; // remember the surviving planets
}


function addNewPlanetsWithSomeRandomProbability() {
    // With a very tiny probability, add a new planet to the end.
    var newPlanetLikelihood = 0.007; 
    if (random(0,1) < newPlanetLikelihood) {
        planets.push(makePlanet(width));
    }
}


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


// draw the planet and some windows
function planetDisplay() {

    var floorHeight = 20;
    var bHeight = this.nFloors;


    noStroke();
    push();
    translate(this.x, height);
    for (var i = 0; i < height; i++) {
        fill(this.colorR, this.colorG, this.colorB); 
        ellipse(0, -bHeight, this.r, this.r);
        // Creates the main body of planet
        fill(this.colorR - 50, this.colorG - 50, this.colorB - 50);
        ellipse(0, -bHeight, this.r / this.d1, this.r);
        // Creates horizontal texture of planet
        fill(this.colorR - 50, this.colorG - 50, this.colorB - 50);
        ellipse(0, -bHeight, this.r, this.r / this.d2);
        // Creates vertical texture of planet
        fill(this.colorR, this.colorG, this.colorB);
        ellipse(0, -bHeight, this.r / this.d1 + 10, this.r / this.d2 + 10);
        // Creates center of planet
    }
    pop();
}


function makePlanet(birthLocationX) {
    var bldg = {x: birthLocationX,
                r: round(random(50, 100)),
                d1: random(2, 5),
                d2: random(2, 5),
                // Variables for radius of planet

                colorR: round(random(100, 255)),
                colorG: round(random(100, 255)),
                colorB: round(random(100, 255)),
                // Variables for the color of the planet

                breadth: 50,
                speed: -1.0,
                nFloors: round(random(0, height)),
                move: planetMove,
                display: planetDisplay}
    return bldg;
}

I started out with having no idea what to do for this assignment. I just wasn’t sure how I would be able to create a generative landscape using the code that I had. However, I eventually figured out that I could do a space theme. Implementing this was tricky at first. I didn’t have a full understanding of the code when I first went in, so I made a lot of mistakes. I thought that I was supposed to set the location of each object to random until I realized that this wouldn’t animate it. I then had to undo a large amount of my work and replace it with the sample code. After looking at some of my peers’ projects I decided to add a rocket ship since I felt that the appearance was somewhat bland.

Project 10 – Yugyeong Lee

sketch

//Yugyeong Lee
//Section B
//yugyeonl@andrew.cmu.edu
//Project-10

var stars = [];		//array of stars
var clouds = [];	//array of clouds
var landscapes = [];	//array of landscapes
var camera;

function preload() {
	//loading previously-made (through code) camera image
	var cameraImage = "https://i.imgur.com/5joEquu.png"
	camera = loadImage(cameraImage);
}

function setup() {
    createCanvas(480, 360);
    //create initial set of stars
    for (var i = 0; i < 100; i++) {
    	var starX = random(width);
    	var starY = random(3*height/4);
    	stars[i] = makeStars(starX, starY);
    }
    //create initial set of clouds
    for (var i = 0; i < 4; i++) {
    	var cloudX = random(width);
    	var cloudY = random(height/2);
    	clouds[i] = makeClouds(cloudX, cloudY);
    }
    //create mountain
    makeLandscape(height-100, 120, 0.0001, .0075, color(20));
    //create ocean
    makeLandscape(height-50, 20, 0.0001, .0005, color(42, 39, 50));
}

function draw() {
	//gradient background
    var from = color(24, 12, 34);
	var to = color(220, 130, 142);
    setGradient(0, width, from, to);
    //stars
	updateAndDisplayStars();
	removeStars();
	addStars();
	//moon
	makeMoon();
    //clouds
	updateAndDisplayClouds();
	removeClouds();
	addClouds();
	//landscape
	moveLandscape();
    //reflection of moon on ocean
    ellipseMode(CENTER);
    fill(243, 229, 202, 90);
    ellipse(3*width/4, height-50, random(50, 55), 4);
    ellipse(3*width/4, height-35, random(35, 40), 4);
    ellipse(3*width/4, height-26, random(25, 30), 4);
    ellipse(3*width/4, height-17, random(10, 15), 4);
    ellipse(3*width/4, height-8, random(35, 40), 5);
	fill(204, 178, 153, 50);
    ellipse(3*width/4, height-50, random(70, 80), 8);
    ellipse(3*width/4, height-35, random(50, 60), 8);
    ellipse(3*width/4, height-26, random(70, 80), 8);
    ellipse(3*width/4, height-17, random(30, 40), 8);
    ellipse(3*width/4, height-8, random(60, 70), 10);
	//camera LCD display
	push();
	translate(65, 153);
	scale(.475, .46);
	var from = color(24, 12, 34);
	var to = color(220, 130, 142);
    setGradient(0, width, from, to);
    //stars
	updateAndDisplayStars();
	removeStars();
	addStars();
	//moon
	makeMoon();
    //clouds
	updateAndDisplayClouds();
	removeClouds();
	addClouds();
	//landscape
	moveLandscape();
    //reflection
    ellipseMode(CENTER);
    fill(243, 229, 202, 90);
    ellipse(3*width/4, height-35, random(50, 55), 6);
    ellipse(3*width/4, height-28, random(35, 40), 4);
    ellipse(3*width/4, height-19, random(25, 30), 4);
    ellipse(3*width/4, height-10, random(10, 15), 4);
	fill(204, 178, 153, 50);
    ellipse(3*width/4, height-35, random(70, 80), 8);
    ellipse(3*width/4, height-28, random(50, 60), 8);
    ellipse(3*width/4, height-19, random(70, 80), 8);
    ellipse(3*width/4, height-10, random(30, 40), 8);
	pop();
	//camera
	image(camera, 0, 0);
	//camera crosshair
	noFill();
	strokeWeight(.25);
	stroke(235, 150);
	rect(75, 163, 200, 140);
	rect(85, 173, 180, 120);
	line(170, 233, 180, 233);
	line(175, 228, 175, 238);
	//battery symbol
	strokeWeight(.5);
	rect(94, 279, 18.25, 6);
	noStroke();
	fill(235, 150);
	for (i = 0; i< 4; i++) {
		rect(95+i*4.25, 280, 4, 4);
	}
	rect(112.25, 280, 2, 3);
	//REC text
	fill(235);
	textSize(7);
	text("REC", 245, 184);
	fill(225, 100, 0);
	ellipse(238, 182, 7, 7);
	//camera tripod
	fill(30);
	rect(width/2-50, height-26, 100, 20);
	fill(25);
	rect(width/2-75, height-16, 150, 50, 10);
}

function setGradient (y, w, from, to) {
	// top to bottom gradient (background)
    for (var i = y; i <= height; i++) {
      var inter = map(i, y, y+w, 0, 1);
      var c = lerpColor(from, to, inter);
      stroke(c);
      strokeWeight(2);
      line(y, i, y+w, i);
	}
}

function makeMoon() {
	ellipseMode(CENTER);
	for (var i = 0; i < 30; i++) {
		//glowing gradient moonlight through array & randomizing value
		var value = random(7, 8);
		var transparency = 50-value*i;
		var diam = 80;
		fill(243, 229, 202, transparency);
		ellipse(3*width/4, 90, diam+10*i, diam+10*i);
	}
	//the moon
	fill(204, 178, 153);
	ellipse(3*width/4, 90, diam, diam);
}

function makeLandscape(landscapeY, landscapeR, landscapeS, landscapeD, landscapeC) {
	var landscape = {ly: landscapeY,		//locationY
					 range: landscapeR,		//range of how far landscape goes up
					 speed: landscapeS,		//speed of the landscape
					 detail: landscapeD,	//detail (how round/sharp)
					 color: landscapeC,		//color of the landscape
					 draw: drawLandscape}
	landscapes.push(landscape);
}

function drawLandscape() {
	//generating landscape from code provided
	fill(this.color);
	beginShape();
	vertex(0, height);
	for (var i = 0; i < width; i++) {
		var t = (i*this.detail) + (millis()*this.speed);
        var y = map(noise(t), 0,1, this.ly-this.range/2, this.ly+this.range/2);
        vertex(i, y); 
	}
	vertex(width, height);
	endShape(CLOSE);
}

function moveLandscape() {
	//move the landscape
	for (var i = 0; i < landscapes.length; i++) landscapes[i].draw();
}

function updateAndDisplayStars() {
	//update the stars' position & draw them
	for (var i = 0; i < stars.length; i++) {
		stars[i].move();
		stars[i].draw();
	}
}

function makeStars(starX, starY) {
	var star = {x: starX,					//locationX of star
				y: starY,					//locationY of star
				speed: -random(0, .005),	//speed of the star
				move: moveStars,			
				draw: drawStars}
	return star;
}

function drawStars() {
	noStroke();
	//setting transparency at random to have twinkling effect
	var transparency = random(50, 200);
	fill(255, transparency);
	ellipse(this.x, this.y, 1.25, 1.25);
}

function moveStars() {
	//move stars by updating its x position
	this.x += this.speed;
}

function removeStars() {
	var keepStars = []; //array of stars to keep
	for (var i = 0; i < stars.length; i++) {
		if (0 < stars[i].x < width) {
			keepStars.push(stars[i]);
		}
	}
	stars = keepStars;	//remember the surviving stars
}

function addStars() {
	//new stars from the right edge of the canvas
	var newStarsProbability = 0.0025;
	//likliness of new stars
	if (random(0, 1) < newStarsProbability) {
    	var starX = width;
    	var starY = random(3*height/4);
		stars.push(makeStars(starX, starY));
	}
}
//clouds
function updateAndDisplayClouds() {
	//update the clouds' position & draw them
	for (var i = 0; i < clouds.length; i++) {
		clouds[i].move();
		clouds[i].draw();
	}
}

function makeClouds(cloudX, cloudY) {
	var cloud = {x: cloudX,					//locationX of cloud
				y: cloudY,					//locationY of the cloud
				breadth: random(200, 300),	//width of the cloud
				speedC: -random(.3, .5),	//speed of the cloud
				nFloors: round(random(2,6)),//multiplier that determines the height of the cloud
				transparency: random(20, 60),//transparency of the cloud
				move: moveClouds,
				draw: drawClouds}
	return cloud;
}

function drawClouds() {
	var multiplier = 5;	//multiplier that determines the height of the cloud
	var cloudHeight = this.nFloors*multiplier;
	ellipseMode(CORNER);
	noStroke();
	fill(255, this.transparency);
	push();
	translate(this.x, height/2-80);
	ellipse(0, -cloudHeight, this.breadth, cloudHeight/2);
	pop();
	push();
	translate(this.x, height/2-100);
	ellipse(30, -cloudHeight, this.breadth, cloudHeight);
	pop();
}

function moveClouds() {
	//move stars by updating its x position
	this.x += this.speedC;
}

function removeClouds() {
	var keepClouds = [];	//array of clouds to keep
	for (var i = 0; i < clouds.length; i++) {
		if (clouds[i].x + clouds[i].breadth > 0) {
			keepClouds.push(clouds[i]);
		}
	}
	clouds = keepClouds;	//remember the surviving clouds
}

function addClouds() {
	//new clouds from the right edge of the canvas
	var newCloudsProbability = 0.005;
	//likliness of new clouds
	if (random(0, 1) < newCloudsProbability) {
    	var cloudX = width;
    	var cloudY = random(height/2);
		clouds.push(makeClouds(cloudX, cloudY));
	}
}

I first visualized the generative landscape through the lens of a camera. As if to record the moving landscape on the background, the LCD display shows the night sky with twinkling stars as well as clouds, mountains, and flowing body of water. I created the camera through code but in realizing that I cannot make a transparent LCD display, I took a screenshot of the camera I generated and created a transparent layer in Photoshop and included it in my code as an image. I focused on creating depth with this generative landscape project through different layers and wanted to make sure that even the objects with subtle movement such as the moon and the stars have movement through having blinking and glowing effect.

keuchuka – project -10

project10

//Fon Euchukanonchai
//15-104 Section A
//keuchuka@andrew.cmu.edu
//Project-10

var plates = [];
var plates2 = [];
var plates3 = [];

var sushi = [];
var sushi2 = [];
var sushi3 = [];

var salmon;
var roe;
var egg;
var seaweed;

//preload all images of sushi and gradients
function preload(){
	var bgLink = "https://i.imgur.com/alDAyjZ.jpg"
	var bar1Link = "https://i.imgur.com/60amesK.png"
	var bar2Link = "https://i.imgur.com/fghTsKQ.png"
	var bar3Link = "https://i.imgur.com/SCIYqYe.png"

	var salmonLink = "https://i.imgur.com/Cb4N5Lb.png"
	var roeLink = "https://i.imgur.com/rJjcqJo.png"
	var eggLink = "https://i.imgur.com/FMF2QvN.png"
	var seaweedLink = "https://i.imgur.com/QbnIWmr.png"

	salmon = loadImage(salmonLink)
	roe = loadImage(roeLink)
	egg = loadImage(eggLink)
	seaweed = loadImage(seaweedLink)

	bg = loadImage(bgLink)
	bar1 = loadImage(bar1Link)
	bar2 = loadImage(bar2Link)
	bar3 = loadImage(bar3Link)
}


function setup() {

	createCanvas(480, 360)
		
	}

//make new plates for first belt
function makenewPlates(){
	//even-ish chance of getting different types of sushi
	if(random(0,2)<0.0025 & random(0,2)> 0.000){
		plates.push(new makePlates(width,60, -6, 3.5));
		sushi.push(new makeSushi(width-30, 40, -6, 3.5, salmon))

	} else if(random(0,2)<0.005 & random(0,2)> 0.0025) {
		plates.push(new makePlates(width,60, -6, 3.5));
		sushi.push(new makeSushi(width-30, 40, -6, 3.5, egg))

	} else if(random(0,2)<0.0075 & random(0,2)> 0.005) {
		plates.push(new makePlates(width,60, -6, 3.5));
		sushi.push(new makeSushi(width-30, 40, -6, 3.5, roe))

 	} else if(random(0,2)<0.01 & random(0,2)> 0.075) {
		plates.push(new makePlates(width,60, -6, 3.5));
		sushi.push(new makeSushi(width-30, 40, -6, 3.5, seaweed))
 
	}
}

//make new plates for second belt
function makenewPlates2(){

	if(random(0,2)<0.0025 & random(0,2)> 0.000){
		plates2.push(new makePlates(93,0, 5, 3));
		sushi2.push(new makeSushi(63, -25, 5, 3, salmon))

	} else if(random(0,2)<0.005 & random(0,2)> 0.0025) {
		plates2.push(new makePlates(93,0, 5, 3));
		sushi2.push(new makeSushi(63, -25, 5, 3, egg))

	} else if(random(0,2)<0.0075 & random(0,2)> 0.005) {
		plates2.push(new makePlates(93,0, 5, 3));
		sushi2.push(new makeSushi(63, -25, 5, 3, roe))

 	} else if(random(0,2)<0.01 & random(0,2)> 0.075) {
		plates2.push(new makePlates(93,0, 5, 3));
		sushi2.push(new makeSushi(63, -25, 5, 3, seaweed))
 
	}
}


//make new plates for third belt
function makenewPlates3(){

	if(random(0,2)<0.0025 & random(0,2)> 0.000){
		plates3.push(new makePlates(0, 170, 6, -3.5));
		sushi3.push(new makeSushi(-30, 150, 6, -3.5, salmon))

	} else if(random(0,2)<0.005 & random(0,2)> 0.0025) {
		plates3.push(new makePlates(0, 170, 6, -3.5));
		sushi3.push(new makeSushi(-30, 150, 6, -3.5, egg))

	} else if(random(0,2)<0.0075 & random(0,2)> 0.005) {
		plates3.push(new makePlates(0, 170, 6, -3.5));
		sushi3.push(new makeSushi(-30, 150, 6, -3.5, roe))

 	} else if(random(0,2)<0.01 & random(0,2)> 0.075) {
		plates3.push(new makePlates(0, 170, 6, -3.5));
		sushi3.push(new makeSushi(-30, 150, 6, -3.5, seaweed))
 
	}
}


function draw(){

	// sushi travels slowly
	frameRate(25)

	//background image
	image(bg, 0,0)

	//call to push plates into array
	makenewPlates();
	makenewPlates2();
	makenewPlates3();

	//conveyor belt 1
	image(bar1, 0,0)

	//move and display sushi and plates in first set of array
	for (var i = 0; i < plates.length; i++){
		plates[i].move();
		plates[i].display();
		sushi[i].move();
		sushi[i].display();
	}

	//conveyor belt 2
	image(bar2, 0,0)

	//move and display sushi and plates in second set of array
	for (var i = 0; i < plates2.length; i++){
		plates2[i].move();
		plates2[i].display();
		sushi2[i].move();
		sushi2[i].display();
		}

	//conveyor belt 3
	image(bar3, 0,0)

	//move and display sushi and plates in third set of array
	for (var i = 0; i < plates3.length; i++){
		plates3[i].move();
		plates3[i].display();
		sushi3[i].move();
		sushi3[i].display();		
		}
	}
	

// constructing the plates and their behavior
function makePlates(makeX, makeY, speedX, speedY){

	this.x = makeX
	this.y = makeY


	this.Xspeed = speedX
	this.Yspeed = speedY

	this.color = color(255,0,0)

	this.move = function() {

	this.x += this.Xspeed
	this.y += this.Yspeed
	
	}
	this.display = function(){
		noStroke();
		fill(170, 170, 170);
		ellipse(this.x-5, this.y+12, 102, 57)		
		fill(199, 222, 202)
		ellipse(this.x, this.y+2, 113,66)
		fill(240, 249, 250)
		ellipse(this.x, this.y, 113, 66)
		fill(203,233,230)
		ellipse(this.x, this.y, 95, 56)
		fill(240, 249, 250)
		ellipse(this.x, this.y+3, 89, 51)
	}
}

// constructing the different sushis and their behavior
function makeSushi(makeX, makeY, speedX, speedY, top){

	this.x = makeX
	this.y = makeY

	this.fish = top

	this.Xspeed = speedX
	this.Yspeed = speedY

	this.color = color(255,0,0)

	this.move = function() {

	this.x += this.Xspeed
	this.y += this.Yspeed
	}

	this.display = function(){

		image(this.fish,this.x, this.y)
	}
}


initial sketches

I didn’t really want a traditional landscape, so I thought about representing either faces or food. The phrase “stuff passing by” really reminded me of a sushi conveyor belt, so I decided to use that as my landscape. Having one felt like the conveyor belt was more an object, therefore I made three in order to make the piece a bit more spatial and landscape-y. I started by drawing the bars and sushi itself with code, but it wasn’t too efficient and I couldn’t get to the level of detail I wanted. I ended up drawing it somewhere else and animating it with p5. The result is some abstract land with some sushi flying around on colorful carousels.

jooheek-Project10-Generative Landscape

sketch

//JooHee Kim
//Section E
//jooheek@andrew.cmu.edu
//Project-10

var animals = [];
var mountainSpeed1 = 0.00005;
var mountainDetail1 = 0.005;
var mountainSpeed2 = 0.0001;
var mountainDetail2 = 0.003;
var mountainSpeed3 = 0.0002;
var mountainDetail3 = 0.001;

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

    //creates 5 animals at start
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        animals[i] = makeAnimals(rx);
    }

    frameRate(30);
}


function draw() {
    background(210, 240, 255); 

    makeMountains();
    makeOasis();
    updateAndDisplayAnimals();
    removeAnimals();
    addNewRandomAnimals(); 

}

function makeMountains() {
    //first farthest mountain
    noStroke();
    fill(125, 185, 130);
    beginShape(); 
    for (var m1 = 0; m1 < width; m1++) {
        var mountainOneSpeed = (m1 * mountainDetail1) + (millis() * mountainSpeed1);
        var mountainPeaksOne = map(noise(mountainOneSpeed), 0, 1, width/2, height/4);
        vertex(m1, mountainPeaksOne); 
    }

    vertex(width,height);
    vertex(0, height);
    endShape();

    //second mountain
    fill(155, 215, 140);
    beginShape(); 
    for (var m2 = 0; m2 < width; m2++) {
        var mountainTwoSpeed = (m2 * mountainDetail2) + (millis() * mountainSpeed2);
        var mountainPeaksTwo = map(noise(mountainTwoSpeed), 0, 1, width/2 + 10, height/4 + 30);
        vertex(m2, mountainPeaksTwo); 
    }

    vertex(width,height);
    vertex(0, height);
    endShape();

    //third closest mountain
    fill(185, 245, 150);
    beginShape(); 
    for (var m3 = 0; m3 < width; m3++) {
        var mountainThreeSpeed = (m3 * mountainDetail3) + (millis() * mountainSpeed3);
        var mountainPeaksThree = map(noise(mountainThreeSpeed), 0, 1, width/2 + 20, height/4 + 60);
        vertex(m3, mountainPeaksThree); 
    }

    vertex(width,height);
    vertex(0, height);
    endShape();

}


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


function removeAnimals(){
    var animalsToKeep = [];
    for (var i = 0; i < animals.length; i++){
        if (animals[i].x + animals[i].breadth > 0) {
            animalsToKeep.push(animals[i]);
        }
    }
    animals = animalsToKeep;
}


function addNewRandomAnimals() {

    var newAnimals = 0.009; 
    if (random(0,1) < newAnimals) {
        animals.push(makeAnimals(width));
    }
}

function animalsMove() {
    this.x += this.speed;
}
    
function animalsDisplay() {
    noStroke(); 
    push();
    translate(this.x, height - height/4);
    //shadow of animals
    fill(100, 100, 100, 60);
    ellipse(this.size/4, this.size*3/4, 150, 30);
    //the butts of the animals
    fill(this.color); 
    ellipse(0, 0, this.size, this.size);
    ellipse(this.size/2, 0, this.size, this.size);
    //the tails of the animals
    fill(50);
    ellipse(this.size/4, -this.size/2+this.size/4, this.size/8, this.size/4);
    //the legs of the animals
    fill(this.color);
    quad(-this.size/4-5, 0, -this.size/8-5, this.size*3/4, this.size/8-5, this.size*3/4, this.size/4-5, 0);
    quad(this.size/2-(this.size/4-5), 0, this.size/2-(this.size/8), this.size*3/4, this.size/2+(this.size/8), this.size*3/4, this.size/2+(this.size/4+5), 0);
    pop();
}


function makeAnimals(birth) {
    var ANIMALS = {
                x: birth,
                breadth: 50,
                size: 100,
                speed: -7.0,
                move: animalsMove,
                display: animalsDisplay,
                color: [random(50, 255), random(50, 255), random(50, 255)]
            }

    return ANIMALS;
}

function makeOasis() {
    fill(120, 170, 245);
    rect(0, height/2+80, width, 100);

}

I got inspiration for this project from the Lion King, where the animals drink from a pond or lake. I wanted to use this project to show animals drinking from a lake as well while the background (mountains) is moving. There are three mountains that vary in color to show depth and there are animals in the foreground drinking from the water. This is the picture that gave me the inspiration from the movie.

thlai-Project-10-Landscape

Generative Landscape

I struggled a lot with this project. There were so many little things I wanted to do but didn’t know how to execute. I wanted to create a calming lake and mountains landscape with the sun in the background and used a purple color scheme and gradients to achieve this. The starter code helped me a lot with the clouds.  The most difficult part, I think, was creating the reflections in the water – I used the noise() function to create them and used a similar code to the mountains. In the end, I used fog image to spice things up and create atmosphere.

sketch

// Tiffany Lai
// 15-104, Section A
// thlai@andrew.cmu.edu
// Project 10 - Landsape

var clouds = []; // array for clouds
var waterX = []; // array for x position of reflection lines
var waterY = []; // array for y position of reflection lines
var speed1 = 0.0002; // for mountain1
var peaks1 = 0.03; // for mountain1
var speed2 = 0.0005; // for mountain2
var peaks2 = 0.03; // for mountain2
var boatX = 250; // x coordinates of boat
var img; // variable to store fog filter

function preload() {
	img = loadImage("https://i.imgur.com/aoZ4YwF.png"); // fog image
}

function setup() {
	createCanvas(480, 480);
	// initial collection of clouds
	for (var i = 0; i < 5; i++) {
		var rx = random(width);
		clouds[i] = makeClouds(rx);
	}
	for (var i = 0; i < 50; i++) {
		var sparkleX = random(0, width);
		var sparkleY = random(height * 2 / 3, height);
		waterX.push(sparkleX);
		waterY.push(sparkleY);
	}
}

function draw() {
	var num = height; // number of lines for gradient bg
	// gradient background
	for (var i = 0; i < num; i++) {
		strokeWeight(2);
		stroke(100 + 1.2 * i, 50 + i, 100 + 0.7 * i);
		line(0, i, width, i);
	}
	sun(); // draw sun
	updateClouds(); // update and display clouds
	removeClouds(); // remove clouds that have slippsed out of view
	addClouds(); // add new clouds with random probability
	mountain1(); // draw first mountains
	mountain2(); // draw second mountains
	water(); // draw water and reflections
	boat(boatX); // draw boat
	boatX -= 0.5; // boat speed
	if (boatX < -50) { // if boat exits left, make it come in right
		boatX = width;
	}
	image(img, 0, 0, width, height); // load fog
}

function sun() { // sun and rays
	noStroke();
	fill(255, 200);
	ellipse(width / 3, height / 3, 170, 170); // sun
	for (var i = 0; i < 55; i++) { // sun rays
		strokeWeight(1);
		stroke(color(220 + 2 * i, 120 + i, 130 + 1 * i, 100)); // gradient
		noFill();
		ellipse(width / 3, height / 3, 170 + i * i * 0.2, 170 + i * i * 0.2); // distance between circles
	}
}

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

function removeClouds() {
	var keepClouds = [];
	for (var i = 0; i < clouds.length; i++) {
		if (clouds[i].x + clouds[i].breadth > 0) {
			keepClouds.push(clouds[i]);
		}
	}
	clouds = keepClouds;
}

function addClouds() {
	// probability of cloud appearing
	var cloudChance = 0.007;
	if (random(0, 1) < cloudChance) {
		clouds.push(makeClouds(width));
	}
}

function moveClouds() { // speed of clouds
	this.x += this.speed;
}

function displayClouds() {
	fill(255, 50);
	noStroke();
	ellipse(this.x, this.y, this.width, this.height);
	ellipse(this.x + 10, this.y + 10, this.width - 10, this.height - 10);
	ellipse(this.x + 20, this.y - 10, this.width / 2, this.height / 2);
	ellipse(this.x - 20, this.y, this.width - 20, this.height - 10);
}

function makeClouds(cloudX) {
	var cloud = {
		x: cloudX,
		y: random(0, height / 2 - 100),
		speed: random(-1, -0.1),
		width: random(40, 100),
		height: random(20, 50),
		breadth: 50,
		move: moveClouds,
		display: displayClouds,
	}
	return cloud;
}

function mountain1() { // background mountains
	noStroke();
	fill(135, 86, 110);
	beginShape();
	for (var x = 0; x < width; x++) {
		var t = (x * peaks1) + (millis() * speed1);
		var y = map(noise(t), 0, 1, height / 5, height / 2);
		vertex(x, y);
	}
	vertex(width, height);
	vertex(0, height);
	endShape();
}

function mountain2() { // middleground mountains
	// noStroke();
	stroke(70, 63, 86);
	strokeWeight(1);
	// beginShape();
	for (var x = 0; x < width; x++) {
		var t = (x * peaks2) + (millis() * speed2);
		var y = map(noise(t), 0, 2, height / 2, height / 3);
		line(x, 330 + y / 2, x, 330 - y / 2);
	}
}

function water() { // water and reflections
	noStroke();
	fill(170, 120, 126, 100);
	rect(0, height - height / 3, width, height);

	for (var i = 0; i < 15; i++) {
		var t = (i * peaks2) + (millis() * speed2);
		var widthChange = (map(noise(t), 0, 1, 0, 100));
		stroke(255, 70);
		line(waterX[i] - widthChange, waterY[i], waterX[i] + widthChange, waterY[i]);
	}
}

function boat(boatX) { // make boat
	noStroke();
	fill(50, 43, 76);
	triangle(boatX + 31, 367, boatX + 31, 393, boatX + 16, 393);
	triangle(boatX + 33, 374, boatX + 34, 393, boatX + 47, 393);
	quad(boatX + 15, 396, boatX + 23, 405, boatX + 40, 405, boatX + 47, 396);

	stroke(255, 50);
	line(boatX + 15, 405, boatX + 45, 405);
}