Project 11: Generative Landscape

hc
var buildings = [];
var mountains = [];
var trees = [];
var noiseParam = 0;
var noiseStep = 0.01;
var people = [];
var img;

function preload(){
    //calling the superman image
    img = loadImage("https://i.imgur.com/21p2JQR.png");
}

function setup() {
    createCanvas(480, 480); 
    imageMode(CENTER);
    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    // mountains
    for (var i = 0; i <= width/4; i++) {
        var value = map(noise(noiseParam), 0, 1, height * 0.2, height * 0.9);
        mountains.push(value);
        noiseParam += noiseStep;
    }
}


function draw() {
    background(204, 241, 255); 
    //drawing clouds
    cloud(50, 70);
    push();
    scale(0.7);
    cloud(480, 150);
    pop();
    drawMountains(); //drawing the mountains
    displayStatusString();
    displayHorizon();
    //drawing the buildings
    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability();
    image(img, 250, 150, img.width * 0.2, img.height * 0.2); //superman
    //drawing the trees
    updateAndDisplayTrees(); 
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability(); 
    //drawing the people
    updateAndDisplayPeople();
    removePeopleThatHaveSlippedOutOfView();
    addNewPeopleWithSomeRandomProbability(); 
}

function cloud(x, y){
    //drawing the cloud
    push();
    translate(x, y);
    noStroke();
    fill(255, 237, 209, 95);
    ellipse(0, 10, 70, 50);
    ellipse(25, 0, 90, 60);
    ellipse(50, 10, 80, 45);
    pop();
}

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

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


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


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

// draw the building and some windows
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(59, 107, 130); 
    stroke(100); 
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    stroke(220); 
    fill(207, 226, 232);
    if (bHeight > 55){
        for (var i = 0; i < this.nFloors; i++) {
            rect(5, -15 - (i * floorHeight), this.breadth - 40, 10);
            rect(35, -15 - (i * floorHeight), this.breadth - 40, 10);
        }
    }else{
        fill(255, 246, 230);
        rect(0, -bHeight, this.breadth, bHeight);
        noStroke();
        fill(240, 182, 74);
        triangle(-10,-bHeight,this.breadth/2,-bHeight-30,this.breadth+10,-bHeight);
        fill(150, 100, 45);
        rect(20, 0, this.breadth - 40, -20);
    }
    pop();
}


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

function drawMountains(){
    mountains.shift();
    var value = map(noise(noiseParam), 0, 1, height * 0.2, height * 0.9);
    mountains.push(value);
    noiseParam += noiseStep;
    stroke(135, 173, 141);
    fill(135, 173, 141);
    beginShape(); 
    vertex(0, height);
    for (var i = 0; i < width/4; i++) {
        vertex(i*5, mountains[i]);
        vertex((i+1)*5, mountains[i+1]);
    }
    vertex(width, height);
    endShape();
}

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

function removeTreesThatHaveSlippedOutOfView(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}

function addNewTreesWithSomeRandomProbability() {
    var newTreeLikelihood = 0.025; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

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

function makeTree(birthLocationX) {
    var trees = {x: birthLocationX,
                breadth: 20,
                speed: -3.5,
                treeHeight: round(random(50,100)),
                move: treeMove,
                display: treeDisplay}
    return trees;
}


function treeDisplay() {
    push();
    translate(this.x, height - 30);
    noStroke(); 
    fill(107, 83, 71);
    rect(-5, 0, 10, 15); //tree trunk
    fill(66, 161, 61); 
    //leaves
    triangle(-this.breadth+10, -30, 0, -this.treeHeight, this.breadth-10, -30);
    triangle(-this.breadth+5, 0, 0, -this.treeHeight*0.7, this.breadth-5, 0);
    pop();
}

//Drawing people
function updateAndDisplayPeople(){
    for (var i = 0; i < people.length; i++){
        people[i].move();
        people[i].display();
    }
}

function removePeopleThatHaveSlippedOutOfView(){
    var peopleToKeep = [];
    for (var i = 0; i < people.length; i++){
        if (people[i].x + people[i].breadth > 0) {
            peopleToKeep.push(people[i]);
        }
    }
    people = peopleToKeep;
}

function addNewPeopleWithSomeRandomProbability() {
    var newPeopleLikelihood = 0.005; 
    if (random(0,1) < newPeopleLikelihood) {
        people.push(makePeople(width));
    }
}


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

function peopleDisplay() {
    push();
    translate(this.x, height - 25);
    noStroke(); 
    fill(0);
    ellipse(0, -20, 40, 50); //head
    rect(-35, 0, 70, 50, 80); //body
    push();
    rotate(radians(-7));
    ellipse(25, -15, 15, 110); //arm
    pop();
    pop();
}

function makePeople(birthLocationX) {
    var ppl = {x: birthLocationX,
                breadth: round(random(5, 10)),
                speed: -3.5,
                pHeight: round(random(20,25)),
                move: peopleMove,
                display: peopleDisplay}
    return ppl;
}

function displayHorizon(){
    fill(53, 97, 44);
    rect (0,height-50, width, height-50); 
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
}

Leave a Reply