heeseoc-Project-10-Landscape

sketch

//Steph Chun
//15-104 section #A
//heeseoc@andrew.cmu.edu
//Project-10

var buildings = [];
var terrainSpeed = 0.0005;
var terrainDetail = 0.008;
var c1, c2;
var lc1, lc2, lc3, lc4;

function setup() {
    createCanvas(480, 480); 
    //background gradient color
    c1 = color(60,1,29);
  	c2 = color(205,100,70);
  	//gradient color for reflected streetlight
  	lc1 = color(255,230,109,30);
  	lc2 = color(255,230,109,0);
  	//gradient color for reflected buildings
    lc3 = color(random(180,200), random(100,150), random(100,150), 50);
  	lc4 = color(random(180,200), random(100,150), random(100,150), 0);

    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    frameRate(20);
}

function draw() {
    setGradient(0, 0, width, height/2+50, c1, c2, 1);
    updateBuildings();
    removeBuildings();
    addBuildings(); 
    makeBushes();
    riverDisplay();
}

//gradient for the background(sky)
function setGradient(x, y, w, h, c1, c2, axis) {
  noFill();
    for (var i = y; i <= y+h; i++) {
      var inter = map(i, y, y+h, 0, 1);
      var c = lerpColor(c1, c2, inter);
      stroke(c);
      line(x, i, x+w, i);
    } 
}

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

//remove buildings when they're out of frame
function removeBuildings(){
    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep;
}

//introduce new buildings
function addBuildings() {
    var newBuilding = 0.008; 
    if (random(0,1) < newBuilding) {
        buildings.push(makeBuilding(width));
    }
}

//move the buildings
function buildingMove() {
    this.x += this.speed;
}

//draw multiple buildings
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    push();
    noStroke();
    fill(this.bColor); 
    translate(this.x, height - 190);
    rect(0, -bHeight, this.breadth, bHeight);
    stroke(200); 
    for (var y = 0; y < this.nFloors; y++) {
    	for (var x = 0; x < 6; x++){
    		noStroke();
    		fill(random(165,255), random(180,255), random(200,220));
    		rect(x*10+8, -10-(y*floorHeight), 4, 7);
    	}
	}
    pop();
}

//determine the shape and movement of the building
function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 70,
                speed: -1.2,
                bColor: color(random(180,200), random(100,150), random(100,150)),
                nFloors: round(random(3,10)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

//make bushes
function makeBushes(){
    noStroke(); 

    //the farthest bush
    beginShape();
    for (var x = 0; x < width; x++) {
    	fill(93,15,11);
        var t = (terrainDetail * x) + (millis() * terrainSpeed);
        var y = map(noise(t*2), -.5, 1, 370, height/2-30);
        curveVertex(x, y); 
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE); 

    //second to the front 
    beginShape();
	for (var x = 0; x < width; x++) {
        fill(61,0,4);
        var t2 = (terrainDetail * x) + (millis() * terrainSpeed);
        var y2 = map(noise(t2*2), -.5, 1, 390, height/2-30);
        curveVertex(x, y2); 
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE);   

    //closest(darkest) bush
    beginShape();
	for (var x = 0; x < width; x++) {
        fill(31,7,6);
        var t3 = (terrainDetail * x) + (millis() * terrainSpeed);
        var y3 = map(noise(t3*2), -.7, 1.1, 420, height/2-10);
        curveVertex(x, y3); 
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE); 
}

function riverDisplay(){

	//river and road
    fill(31,4,9);
    rect(0, height/2+50, width, height/2+50); 
    fill(120,6,41);
    rect(0, height/2+50, width, 5);
    fill(161,12,44);
    rect(0, height/2+53, width, 2);

    for (var s = 0; s < width; s++) {

    	//streetlight
    	strokeWeight(1.3);
    	stroke(255,216,205);
    	line(s*80-7, height/2+30, s*80+7, height/2+30);
    	stroke(217,136,109);
    	line(s*80, height/2+50, s*80, height/2+30);
    	noStroke();
    	fill(255,246,109,60);
    	quad(s*80-7, height/2+30, s*80+7, height/2+30, s*80+15, height/2+50, s*80-15, height/2+50);
    	
    	//gradient for the reflected streetlights
    	setlGradient(s*80-8, height/2+55, 16, height/2-55, lc1, lc2, 1);
    	setl2Gradient(s*80-15, height/2+55, 30, height/2-55, lc1, lc2, 1);

    	//gradient for the reflected buildings 
    	setl3Gradient(s*30+(random(10,70)), height/2+55, 10, height/2-55, lc3, lc4, 2);
    }

    //road detail
    fill(31,4,9,80);
    rect(0, height/2+53, width, 10); 
 
}

//gradient for the reflected streetlights
function setlGradient(x, y, w, h, lc1, lc2, axis) {
	noFill();
	for (var i = y; i <= y+h; i++) {
	    var inter = map(i, y, y+h, 0, 1);
	    var lc = lerpColor(lc1, lc2, inter);
	    stroke(lc);
	    line(x, i, x+w, i);
    } 
}
function setl2Gradient(x, y, w, h, lc1, lc2, axis) {
	noFill();
	for (var i = y; i <= y+h; i++) {
	    var inter = map(i, y, y+h, 0, 1);
	    var lc = lerpColor(lc1, lc2, inter);
	    stroke(lc);
	    line(x, i, x+w, i);
    } 
}

//gradient for the reflected buildings 
function setl3Gradient(x, y, w, h, lc3, lc4, axis) {
	noFill();
	for (var i = y; i <= y+h; i++) {
	    var inter = map(i, y, y+h, 0, 1);
	    var lc = lerpColor(lc3, lc4, inter);
	    stroke(lc);
	    line(x, i, x+w, i);
    } 
}




I created a cityscape at night, with the lights reflected on the river. I immediately came up with the image when I first read the instructions, and then noticed that the sample code would be super helpful for me to get started on this. I modified the code so that the shapes are visually more pleasing, and played around a lot with gradients to achieve the reflected city on the surface of the water. I wanted to have multiple layers of buildings, but for some reason, my code got broken whenever I tried adding more. So I just settled with varying the colors of the building to be more random.

Leave a Reply