creyes1-Project-10-Landscape

creyes1 Project-10 (Generative Landscape)

//Christopher Reyes
//Section D
//creyes1@andrew.cmu.edu
//Project-10 (Generative Landscape)

//Colors
var green1 = [152, 186, 157];
var green2 = [169, 200, 172];
var green3 = [122, 153, 126];

//Shape Arrays
var orbs = [];
var cords = [];
var clouds = [];
var landlines = [];

var inc = 0; //Value for noise command

function setup() {

    createCanvas(480, 480);
    background(green1);
    noStroke();
    angleMode(DEGREES);

    //Generates random land form
    for (var x = 0; x < width; x++) {
        landlines.push(makeLandscape(x, 1));
    }

    //Draws initial set of orbs
    for (var i = 0; i < 5; i++) {
        var rx = random(width);
        var ry = random(height);
        orbs[i] = makeOrb(rx, ry);
    }

    //Adds cord properties to array
    for (var i = 0; i < 10; i++) {
        cords.push(makeCord());
    }


}



function draw() {

    background(green1);

    //Lighter background shapes
    fill(green2);
    noStroke();
    ellipse(width/2, height/2, 100, 300);
    ellipse(width/2 + 120, height/2, 75, 200);
    ellipse(width/2 - 120, height/2, 75, 200);

    //Renders and moves landscape
    for (var x = 0; x < landlines.length; x++) {
        landlines[x].display();
        landlines[x].move();
    }

    //Removes first in the array, or the line that goes off-canvas
    landlines.shift();

    //Increases increment by 1, pushes a new land line onto array
    inc += 1;
    landlines.push(makeLandscape(width-1, inc));

    //Layers lines and orbs for depth
    for (var i = 0; i < 7; i++) {
        cords[i].display();
    }

    updatePositions();

    for (var i = 7; i < 10; i++) {
        cords[i].display();
    }

    addOrb();
    addCloud();
}



//GENERAL FUNCTIONS-------------------------------------------------------------

function updatePositions() {

    //Update orb position and display
    for (var i = 0; i < orbs.length; i++) {
        orbs[i].move();
        orbs[i].display();
    }

    //Update cloud position and display
    for (var i = 0; i < clouds.length; i++) {
        clouds[i].move();
        clouds[i].display();
    }

}


//Removes orbs and clouds after passing edge of canvas
function removeFalloff() {

    var orbsToKeep = [];

    for (var i = 0; i < orbs.length; i++) {
        if (orbs[i].x + orb[i].breadth > 0) {
            orbsToKeep.push(orbs[i]);
        }
    }

    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i++) {
        if (clouds[i].x) {
            cloudsToKeep.push(clouds[i]);
        }
    }

}

//ORB FUNCTIONS-----------------------------------------------------------------

//Orb & orb properties
function makeOrb(spawnPositionX, spawnPositionY) {

    var orb = {x: spawnPositionX,
               y: spawnPositionY,
               breadth: 216 * this.scale,
               scale: random(.25, 1),
               speed: random(-.75, -.15),
               angle: random(0, 360),
               move: orbMove,
               display: displayOrb}

    return orb;
}

//Base orb drawing, capabable of scaling and rotation
function displayOrb() {

    var orbSize = 216 * this.scale;
    var px = this.x-(orbSize/2);
    var py = this.y-(orbSize/2);

    //center position 108, 108
    //Inside pink shell rim
    fill(216, 154, 196);
    push();
    translate(px, py);
    rotate(this.angle);
    beginShape();
    vertex((53.8 * this.scale), (15.2 * this.scale));
    bezierVertex((1.781 * this.scale), (45.703 * this.scale),
                 -(15.078 * this.scale), (112.01 * this.scale),
                 (15.42 * this.scale), (163.31 * this.scale));
    bezierVertex((45.919 * this.scale), (214.601 * this.scale),
                 (112.226 * this.scale), (231.46 * this.scale),
                 (163.52 * this.scale), (200.96 * this.scale));
    bezierVertex((214.817 * this.scale), (170.462 * this.scale),
                 (231.676 * this.scale), (104.155 * this.scale),
                 (201.18 * this.scale), (52.86 * this.scale));
    bezierVertex((170.679 * this.scale), (1.564 * this.scale),
                 (104.372 * this.scale), -(15.295 * this.scale),
                 (53.8 * this.scale), (15.2 * this.scale));
    endShape();

    //Inside purple
    fill(158, 90, 146);
    beginShape();
    vertex(134.1 * this.scale, 40.76 * this.scale);
    bezierVertex(97.698 * this.scale, 46.405 * this.scale,
                 62.946 * this.scale, 83.298 * this.scale,
                 56.3  * this.scale, 126.13 * this.scale);
    bezierVertex(49.074 * this.scale, 172.708 * this.scale,
                 77.436 * this.scale, 207.524 * this.scale,
                 119.85 * this.scale, 200.15 * this.scale);
    bezierVertex(161.836 * this.scale, 192.853 * this.scale,
                 196.48 * this.scale, 147.78 * this.scale,
                 197.52 * this.scale, 103.01 * this.scale);
    bezierVertex(198.488 * this.scale, 61.779 * this.scale,
                 170.188 * this.scale, 35.198 * this.scale,
                 134.1 * this.scale, 40.76 * this.scale);
    endShape();

    //Inside purple shadow
    rectMode(CENTER);
    fill(116, 55, 107);
    push();
    translate((83.78 * this.scale), (93.85 * this.scale));
    rotate(30);
    rect(0, 0, 35 * this.scale, 175 * this.scale);
    pop();

    push();
    translate((108.09 * this.scale), (108.64 * this.scale));
    rotate(30);
    rect(0, 0, 6.5 * this.scale, 175 * this.scale);
    pop();

    //Large pink shell, counter-clockwise winding
    fill(194, 112, 173);
    beginShape();
        vertex((53.8 * this.scale), (15.2 * this.scale));
        bezierVertex((1.781 * this.scale), (45.703 * this.scale),
                     -(15.078 * this.scale), (112.01 * this.scale),
                     (15.42 * this.scale), (163.31 * this.scale));
        bezierVertex((45.919 * this.scale), (214.601 * this.scale),
                     (112.226 * this.scale), (231.46 * this.scale),
                     (163.52 * this.scale), (200.96 * this.scale));
        bezierVertex((214.817 * this.scale), (170.462 * this.scale),
                     (231.676 * this.scale), (104.155 * this.scale),
                     (201.18 * this.scale), (52.86 * this.scale));
        bezierVertex((170.679 * this.scale), (1.564 * this.scale),
                     (104.372 * this.scale), -(15.295 * this.scale),
                     (53.8 * this.scale), (15.2 * this.scale));

    //Ellipsoid cutout, clockwise winding
        beginContour();
            vertex((175.65 * this.scale), (50.62 * this.scale));
            bezierVertex((209.531 * this.scale), (65.455 * this.scale),
                         (222.219 * this.scale), (111.235 * this.scale),
                         (203.99 * this.scale), (152.87 * this.scale));
            bezierVertex((185.753 * this.scale), (194.502 * this.scale),
                         (143.504 * this.scale), (216.223 * this.scale),
                         (109.62 * this.scale), (201.38 * this.scale));
            bezierVertex((75.736 * this.scale), (186.544 * this.scale),
                         (63.049 * this.scale), (140.764 * this.scale),
                         (81.28 * this.scale), (99.13 * this.scale));
            bezierVertex((99.515 * this.scale), (57.497 * this.scale),
                         (141.764 * this.scale), (35.776 * this.scale),
                         (175.65 * this.scale), (50.62 * this.scale));
        endContour();

    endShape(CLOSE);

    //Shine
    fill(218, 179, 212);

    push();
    translate(  + (174.49 * this.scale),   + (117.35 * this.scale));
    rotate(25);
    ellipse(0, 0, 7 * this.scale, 30 * this.scale);
    pop();

    push();
    translate(  + (172.35 * this.scale),   + (140.86 * this.scale));
    rotate(25);
    ellipse(0, 0, 4 * this.scale, 17 * this.scale);
    pop();
    pop();
}

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

//Occasionally adds an additional orb to the array
function addOrb() {
    var spawnChance = 0.005;
    if (random(0, 1) < spawnChance) {
        orbs.push(makeOrb(width*1.5, random(height)));
    }
}

//CORD FUNCTIONS----------------------------------------------------------------

//Line properties
function makeCord() {
    var cord = {x1: 0,
               x2: width,
               y1: randomGaussian(height*(2/3), 40),
               y2: randomGaussian(height*(2/3), 40),
               col: [218, 179, 212],
               weight: 2,
               display: drawCord}
    return cord;
}

//Draws line
function drawCord() {
    stroke(this.col);
    strokeWeight(this.weight);
    line(this.x1, this.y1, this.x2, this.y2);
    noStroke();
}

//CLOUD FUNCTIONS---------------------------------------------------------------

//Cloud properties
function makeCloud() {
    var cloud = {
        x: width*1.5,
        y: random(height),
        h: random(3*4, 12*4),
        w: random(40*4, 85*4),
        move: cloudMove,
        speed: random(-.5, -.1),
        col: [255, 255, 255, 100],
        display: drawCloud}
    return cloud;
}

//Draws cloud
function drawCloud() {
    noStroke();
    fill(this.col);
    ellipse(this.x, this.y, this.w, this.h);

    //ellipse(this.x + this.w*1.3, this.y - this.h*.25, this.w*.33, this.h*.33);
}

//Cloud movement
function cloudMove() {
    this.x += this.speed;
}

//Occasionally adds cloud to array
function addCloud() {
    var spawnChance = 0.004;
    if (random(0, 1) < spawnChance) {
        clouds.push(makeCloud());
    }
}

//LAND FUNCTIONS----------------------------------------------------------------

//Landscape properties
function makeLandscape(x, i) {
    var noiseScale = 0.002;
    var noiseVal = noise((x+i)*noiseScale);
    var landline = {x: x,
                    y1: height - 50 - noiseVal*100,
                    y2: height,
                    col: green3,
                    weight: 1,
                    speed: -1,
                    move: panLand,
                    display: drawLandscape}
    return landline;
}

//Draws individual lines for landscape
function drawLandscape() {

        stroke(this.col);
        strokeWeight(this.weight);
        line(this.x, this.y1, this.x, this.y2);

}

//Moves landmass
function panLand() {
    this.x += this.speed;
}

I wound up running into more difficulty than usual with this assignment, although it was definitely an interesting process when it came to problem-solving. I kept the main components of the program fairly simple – objects with random properties moving across the page. However, I really wanted to try to figure out how the landscape in the Flags assignment work, and after a lot of trial and error made a variation of it using moving vertical lines to piece together that far-off hillside. While the main objects weren’t so difficult to implement, the landscape took up a sizable chunk of my time, but I’m still happy with the result, plus it forced me to really understand the order in which functions were performed, as well as the little nuances of arrays and objects.

Analog & Digital Sketches:

Leave a Reply