Project 11: Generative Landscape

generative landscape
var wood; // wooden table
var belt = []; // conveyer belt
var sushi = [];
var plate = [];
var sushiTypes = [];
var terrain = [];
var noiseParam = 0;
var noiseStep = 0.01;
var sky;
var clouds = [];

var sushiLinks = [
    "https://i.imgur.com/fm2adto.png",
    "https://i.imgur.com/Q2z9Ki8.png",
    "https://i.imgur.com/tUeehNx.png",
    "https://i.imgur.com/H2lTaNf.png",
    "https://i.imgur.com/t7TbPiI.png",
    "https://i.imgur.com/dNH5jvD.png",
    "https://i.imgur.com/YJ7h1Hl.png",
    "https://i.imgur.com/Hu1TVEI.png",
    "https://i.imgur.com/ZyAzhTq.png",
    "https://i.imgur.com/X8sFOwk.png",
    "https://i.imgur.com/t3pzPkC.png",
    ]

function preload() {
    wood = loadImage("https://i.imgur.com/5cpfZzh.png");
    belt = loadImage("https://i.imgur.com/s1SR1ru.png");
    sky = loadImage("https://i.imgur.com/qvwpqNr.png");
    
    for (var i = 0; i < 11; i ++) {
        var sushiImage;
        sushiImage = loadImage(sushiLinks[i]);
        sushiTypes.push(sushiImage);
    }
}

function setup() {
    createCanvas(450, 400);
    imageMode(CENTER);
    wood.resize(450, 0);
    belt.resize(450, 0);
    sky.resize(450, 0);

    // make collection of sushi
    for (var i = 0; i < 5; i++) {
        var sx = random(width);
        sushi[i] = makeSushi(sx);
    }

    // make background terrain
    for (var i = 0; i <= width; i ++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height);
        terrain.push(value);
        noiseParam += noiseStep;
    }

    // make clouds
    for (var i = 0; i < 5; i ++) {
        var cloudx = random(width);
        var cloudy = random(height);
        clouds[i] = makeClouds(cloudx, cloudy);
    }

}


function draw() {
    image(sky, width/2, height/2);
    drawTerrain();
    image(wood, width/2, 250);
    image(belt, width/2, 250);

    updateAndDisplaySushi();
    removeSushiThatHaveSlippedOutOfView();
    addNewSushiWithSomeRandomProbability(); 

    updateAndDisplayClouds();
    removeCloudsThatHaveSlippedOutOfView();
    addNewCloudsWithSomeRandomProbability(); 
}

// all cloud related functions

function updateAndDisplayClouds() {
    for (var i = 0; i < clouds.length; i ++) {
        clouds[i].move();
        clouds[i].display();
    }
}

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

function addNewCloudsWithSomeRandomProbability() {
    var newCloudLikelihood = 0.01; 
    if (random(0,1) < newCloudLikelihood) {
        var newcloudX = random(width);
        var newcloudY = random(200);
        clouds.push(makeClouds(newcloudX, newcloudY));
    }
}

function makeClouds(CLOUDX, CLOUDY) {
    var c = {x: CLOUDX,
             y: CLOUDY,
             speed: -2,
             move: cloudMove,
             display: cloudDisplay}
    return c;
}

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

function cloudDisplay() {
    fill(255, 254, 246); // cream color
    noStroke();
    ellipse(this.x, this.y - 5, 60, 50);
    ellipse(this.x - 20, this.y + 10, 60, 50);
    ellipse(this.x + 15, this.y - 5, 70, 50);
    ellipse(this.x + 5, this.y + 20, 60, 50);
    ellipse(this.x + 30, this.y + 10, 80, 50);
}

// all terrain functions

function drawTerrain() {
    fill(73, 133, 115); 
    noStroke();
    beginShape();
    vertex(0, height);
    for (i = 0; i <= width/5 + 1; i += 1) {
        vertex(i*5, terrain[i]);
        vertex((i+1)*5, terrain[i+1]);
    }
    vertex(width, height);
    endShape();

    // make terrain continuous
    terrain.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    terrain.push(value);
    noiseParam += noiseStep;

}

// all sushi related functions

function updateAndDisplaySushi() {
    for (var i = 0; i < sushi.length; i ++) {
        sushi[i].move();
        sushi[i].display();
    }
}

function removeSushiThatHaveSlippedOutOfView() {
    var sushiToKeep = [];
    for (var i = 0; i < sushi.length; i++){
        if (sushi[i].x + sushi[i].breadth > 0) {
            sushiToKeep.push(sushi[i]);
        }
    }
    sushi = sushiToKeep;
}

function addNewSushiWithSomeRandomProbability() {
    var newSushiLikelihood = 0.007; 
    if (random(0,1) < newSushiLikelihood) {
        sushi.push(makeSushi(450));
    }
}


function makeSushi(birthLocationX) {
    var s = {x: birthLocationX,
                breadth: 50,
                speed: -1,
                sushiType: random(sushiTypes),
                move: sushiMove,
                display: sushiDisplay}
    return s;
}


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

function sushiDisplay() {
    image(this.sushiType, this.x, 310, this.breadth+10, this.breadth);
}

For this project, I decided to create a sushi conveyer belt that’s located outdoors. I started off by drawing all the different types of sushi that’ll be randomized in the landscape. I also drew the conveyer belt and the wooden table. Then I implemented the background which is the sky with a randomized terrain/hill and clouds. I struggled a bit with creating an array of objects using images, so I couldn’t quite figure how to make the sushi not overlap each other. I also tried to create plates under the sushi, but I ended up removing them because they weren’t quite matching up with the sushi.

This is all the variations of the sushi:

Leave a Reply