Charmaine Qiu – Project 11 – Generative Landscape

sketch

//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;
}

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

Leave a Reply