ShanWang-Project10-GenerativeLandscape

sketch

//Shan Wang
//Section A
//shanw1@andrew.cmu.edu
//Assignment-10-Project

var terrainSpeed = 0.001;
var terrainDetail = 0.05;

var birds = [];
var stars = [];

function setup() {
    createCanvas(600,400);
    frameRate(10);

    //create initial set of birds
    for (var i=0; i < 10; i++){
        var bX = random(width);
        var bY = random(height/8,height/5);
        birds[i] = makeBird(bX, bY);
    }

    //create initial set of stars
    for (var j=0; j < 30; j++){
        var x = random(width);
        var y = random(height*3/4);
        stars[j] = makeStars(x,y);
    }

}

//draw gradient background
function gradient(x,y,wid,hei,c1,c2){
    noFill();
    for (var i = y; i < y+hei; i++){
        var inter = map(i,y,y+hei,0,1);
        var col = lerpColor(c1,c2,inter);
        stroke(col);
        line(x,i,x+wid,i);
    }

}

function gradientLine(x,y,len,c1,c2){
    for (var i = y; i < (y+len); i+=12){
        var interv = map(i,y,y+len,0,1);
        var colM = lerpColor(c1,c2,interv);
        stroke(colM);
        line(x,i,x,i+12);
    }
}

// move and draw the stars
function updateAndDisplayStars(){
    for (var s = 0; s < stars.length; s++){
        stars[s].move();
        stars[s].drawS();
    }
}

function makeStars(sX,sY){
    var star = {x:sX,
                y:sY,
                speed: random(0,1),
                move: moveStar,
                drawS: drawStars}
    return star;
}


//draw every star at its current position
function drawStars(){
    stroke(200);
    point(this.x,this.y);
}

//move the star at a low speed
function moveStar(){
    this.x += this.speed;
}

//only keep the stars that are still in the canvas, update the array
function removeStars(){
    var keepStars = [];
    for (var i=0; i < stars.length; i++){
        if ((0 < stars[i].x < width) & (0 < stars[i].y < height)){
            keepStars.push(stars[i]);
        }
    }
    stars = keepStars;
}


//add stars if the number of array is less than 30
function addStars(){
    if (stars.length < 30){
        var stX = random(width);
        var stY = random(height/2);
        stars.push(makeStars(stX,stY));
    }
}

function makeBird(birdX,birdY){
    var bird = {x:birdX,
                y:birdY,
                speedX: random(5,15),
                speedY: random(-10,5),
                spanX: random(5,10),
                spanY: random(2,5),
                stroke: 0,
                fly: birdFly,
                drawB: drawBird}
    return bird;
}

//move the bird on both x and y direction
function birdFly(){
    this.x += this.speedX;
    this.y += this.speedY;
}

//draw the bird, the stroke weight is based on the size of the wing
function drawBird(){
    stroke(0);
    this.stroke = map(this.spanX,5,10,1,3);
    strokeWeight(this.stroke);
    line(this.x-2,this.y,this.x+2,this.y);
    line(this.x,this.y,this.x-3,this.y-5);
    line(this.x,this.y,this.x+3,this.y-5);
    line(this.x-3, this.y-5,this.x-3-this.spanX,this.y-5-this.spanY);
    line(this.x+3, this.y-5,this.x+3+this.spanX,this.y-5-this.spanY);
}

//call the functions that move and draw each bird
function updateAndDrawBirds(){
    for (var i = 0; i < birds.length; i++){
        birds[i].fly();
        birds[i].drawB();
    }
}

//only keep birds that are still on the canvas, update array accordingly
function removeBirds(){
    var keepBirds = [];
    for (var i=0; i < birds.length; i++){
        if ((0 < birds[i].x < width) & (0 < birds[i].y < height)){
            keepBirds.push(birds[i]);
        }
    }
    birds = keepBirds;
}

//randomly add birds at a low probability
function addBirds(){
    var prob = 0.3;
    if (prob>random(0,1)){
        birds.push(makeBird(10,height/4));
    }
}


function draw() {
    stroke(255);
    strokeWeight(3);
    //draw background gradient
    var bgColor2 = color(200, 219, 216);
    var bgColor1 = color(99,112,145);
    gradient(0,0,width,height,bgColor1,bgColor2);

    //display star groups
    updateAndDisplayStars();
    removeStars();
    addStars();

    //set mountain colors
    var mCol1 = color(250,238,222);
    var mCol2 = color(31,43,98);

    //set terrain colors
    var wCol1 = color(35,45,101);
    var wCol2 = color(97,126,180);

    //draw mountain and waves with different variation of Perlin noise
    for (var x = 0; x < width; x++) {
        var t1 = (x * terrainDetail/5) + (millis() * terrainSpeed/2);
        var t2 = (x * terrainDetail/10) + (millis() * terrainSpeed*4);
        var y1 = map(noise(t1), 0,1, 0, height*2/3);
        var y2 = map(noise(t2), 0,1, height*3/4, height*4/5);
        //draw gradient mountain
        gradientLine(x,y1,height-y1,mCol2, mCol1);
        //draw gradient water waves
        gradientLine(x,y2,height-y2,wCol1, wCol2);
    }

    //display birds group
    updateAndDrawBirds();
    removeBirds();
    addBirds();
}

For this project I wanted to create the view of looking at the mountains and river passing by under the sky with stars.

I explored the use of gradient in rendering the mountain and water waves, but because iterating through every single pixel is slowing down the movement and making the animation extremely slow and incoherent. So I decided to render every 12 pixels of each vertical line with the same color to reduce the load on the algorithm.

I made the birds and stars into objects that can be easily controlled with different attributes.

[Note: this post was edited by RBD on Nov 5, 9:25am to work around some WordPress problems. Please do not take off any late points. I’ll post a reply on Piazza as well.]

Leave a Reply