Project-11: Generative Landscape

sketchDownload
/*Name:Camellia(Siyun) Wang; 
Section: C; 
Email Address: siyunw@andrew.cmu.edu;*/
//https://imgur.com/DBFXrXh  coral2
//https://imgur.com/nyf5GKY coral1
//https://imgur.com/JXohvV2 group
//https://imgur.com/4hO2HW1 weed
//https://imgur.com/N4zWoA4
//https://imgur.com/J8R7qyD beach

var beaches = [];
var corals1 = [];
var corals1n = [];
var corals2 = [];
var corals2n = [];
var corals2b = [];
var groups = [];
var weeds = [];
var weeds2 = [];
var stars = [];
var fishes = [];
var bubbles = [];
var a; 
var b; 
var c; 
var d; 
var a1;
var b1; 
var c1;
var d1; 

function preload(){
    backgroundImage = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/back.jpeg");
    coral1 = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/coral1.png");
    coral2 = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/coral-2.png");
    group = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/group.png");
    weed = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/weeds.png");
    beach = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/beach.png");
    star = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/starfish.png");
    fish = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/fish.png");
    fishschool = loadImage("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/fish-school.png");
}

function setup() {
    a = random(-150,300);
    b = random(-150,300);
    c = random(-150,300);
    d = random(-150,300);
    a1 = random(1,-30);
    b1 = random(1,-30); 
    c1 = random(1,-30);
    d1 = random(1,-30);

    createCanvas(480, 400); 
    //the beach
    var bea = makeBeach(1,400);
    beaches.push(bea);

    //coral1
    var cor1 = makeCoral1(150,200);
    corals1.push(cor1);
    //coral1n
    var cor1n = makeCoral1n(1000,175);
    corals1n.push(cor1n);

    //coral2
    var cor2 = makeCoral2(450,75);
    corals2.push(cor2);
    //coral2n
    var cor2n = makeCoral2n(1300,230);
    corals2n.push(cor2n);
    //coral2b
    var cor2b = makeCoral2b(1330,190);
    corals2b.push(cor2b);

    //group
    var gro = makeGroup(550,140);
    groups.push(gro);

    //weed
    var wee = makeWeed(220,55);
    weeds.push(wee);
    //weed2
    var wee2 = makeWeed2(850,30);
    weeds2.push(wee2);

    var star = makeStar(1200,325);
    stars.push(star);

    var fish = makeFish(1220,25);
    fishes.push(fish);

    var bubble = makeBubble(185,480);
    bubbles.push(bubble);

    frameRate(30);
}

//the beach
function makeBeach(xb,yb) {
    var B = {
        x: xb, 
        y: yb,
        move: beachMove,
        speed: -1.5,
        display: beachDisplay};
    return B;
}

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

function beachDisplay(xb) {
   image(beach, this.x, 0,1400,400);
}

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

function removeBeachThatHaveSlippedOutOfView(){
    for (var i = 0; i < beaches.length; i++){
        if (beaches[i].x < -1440) {
            beaches.shift(beaches[i]);
        }
    }
}

function addNewBeach(){
    var lastBeaches = beaches[beaches.length - 1];
    if(lastBeaches.x < -900){
        var a = makeBeach(480,400);
        beaches.push(a);
    }
}

//coral1
function makeCoral1(xc1,yc1){
    var C1 = {
        x: xc1, 
        y: yc1,
        move: coral1Move,
        speed: -1.5,
        display: coral1Display};
    return C1;
}

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

function coral1Display(xc1,yc1){
    image(coral1, this.x, this.y,200,200);
}

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

function removeCoral1ThatHaveSlippedOutOfView(){
    for (var i = 0; i < corals1.length; i++){
        if (corals1[i].x < -1440) {
            corals1.shift(corals1[i]);
        }
    }
}

function addNewCoral1(){
    var lastCoral1 = corals1[corals1.length - 1];
    if(lastCoral1.x < -900){
        var a = makeCoral1(480,200);
        corals1.push(a);
    }
}
//coral1n
function makeCoral1n(xc1n,yc1n){
    var C1n = {
        x: xc1n, 
        y: yc1n,
        move: coral1nMove,
        speed: -1.5,
        display: coral1nDisplay};
    return C1n;
}

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

function coral1nDisplay(xc1,yc1){
    image(coral1, this.x, this.y,200,200);
}

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

function removeCoral1nThatHaveSlippedOutOfView(){
    for (var i = 0; i < corals1n.length; i++){
        if (corals1n[i].x < -1440) {
            corals1n.shift(corals1n[i]);
        }
    }
}

function addNewCoral1n(){
    var lastCoral1n = corals1n[corals1n.length - 1];
    if(lastCoral1n.x < -900){
        var a = makeCoral1n(480,175);
        corals1n.push(a);
    }
} 


//coral2
function makeCoral2(xc2,yc2){
    var C2 = {
        x: xc2, 
        y: yc2,
        move: coral2Move,
        speed: -1.5,
        display: coral2Display};
    return C2;
}

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

function coral2Display(xc2,yc2){
    image(coral2, this.x, this.y,200,200);
}

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

function removeCoral2ThatHaveSlippedOutOfView(){
    for (var i = 0; i < corals2.length; i++){
        if (corals2[i].x < -1440) {
            corals2.shift(corals2[i]);
        }
    }
}

function addNewCoral2(){
    var lastCoral2 = corals2[corals2.length - 1];
    if(lastCoral2.x < -900){
        var a = makeCoral2(480,75);
        corals2.push(a);
    }
}
//coral2n
function makeCoral2n(xc2n,yc2n){
    var C2n = {
        x: xc2n, 
        y: yc2n,
        move: coral2nMove,
        speed: -1.5,
        display: coral2nDisplay};
    return C2n;
}

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

function coral2nDisplay(xc2n,yc2n){
    image(coral2, this.x, this.y,200,200);
}

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

function removeCoral2nThatHaveSlippedOutOfView(){
    for (var i = 0; i < corals2n.length; i++){
        if (corals2n[i].x < -1440) {
            corals2n.shift(corals2n[i]);
        }
    }
}

function addNewCoral2n(){
    var lastCoral2n = corals2n[corals2n.length - 1];
    if(lastCoral2n.x < -900){
        var a = makeCoral2n(480,230);
        corals2n.push(a);
    }
}
//coral2b
function makeCoral2b(xc2b,yc2b){
    var C2b = {
        x: xc2b, 
        y: yc2b,
        move: coral2bMove,
        speed: -1.5,
        display: coral2bDisplay};
    return C2b;
}

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

function coral2bDisplay(xc2b,yc2b){
    image(coral2, this.x, this.y,220,220);
}

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

function removeCoral2bThatHaveSlippedOutOfView(){
    for (var i = 0; i < corals2b.length; i++){
        if (corals2b[i].x < -1440) {
            corals2b.shift(corals2b[i]);
        }
    }
}

function addNewCoral2b(){
    var lastCoral2b = corals2b[corals2b.length - 1];
    if(lastCoral2b.x < -900){
        var a = makeCoral2b(480,190);
        corals2b.push(a);
    }
}

//group
function makeGroup(xg,yg){
    var G = {
        x: xg, 
        y: yg,
        move: groupMove,
        speed: -1.5,
        display: groupDisplay};
    return G;
}

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

function groupDisplay(xg,yg){
    image(group, this.x, this.y,350,350);
}

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

function removeGroupThatHaveSlippedOutOfView(){
    for (var i = 0; i < groups.length; i++){
        if (groups[i].x < -1440) {
            groups.shift(groups[i]);
        }
    }
}

function addNewGroup(){
    var lastGroup = groups[groups.length - 1];
    if(lastGroup.x < -900){
        var a = makeGroup(480,140);
        groups.push(a);
    }
}

//weed
function makeWeed(xw,yw){
    var W = {
        x: xw, 
        y: yw,
        move: weedMove,
        speed: -1.5,
        display: weedDisplay};
    return W;
}

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

function weedDisplay(xw,yw){
    image(weed, this.x, this.y,300,300);
}

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

function removeWeedThatHaveSlippedOutOfView(){
    for (var i = 0; i < weeds.length; i++){
        if (weeds[i].x < -1440) {
            weeds.shift(weeds[i]);
        }
    }
}

function addNewWeed(){
    var lastWeed = weeds[weeds.length - 1];
    if(lastWeed.x < -900){
        var a = makeWeed(480,55);
        weeds.push(a);
    }
}
//weed2
function makeWeed2(xw2,yw2){
    var W2= {
        x: xw2, 
        y: yw2,
        move: weed2Move,
        speed: -1.5,
        display: weed2Display};
    return W2;
}

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

function weed2Display(xw2,yw2){
    image(weed, this.x, this.y,300,300);
}

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

function removeWeed2ThatHaveSlippedOutOfView(){
    for (var i = 0; i < weeds2.length; i++){
        if (weeds2[i].x < -1440) {
            weeds2.shift(weeds2[i]);
        }
    }
}

function addNewWeed2(){
    var lastWeed2 = weeds2[weeds2.length - 1];
    if(lastWeed2.x < -900){
        var a = makeWeed2(480,30);
        weeds2.push(a);
    }
}

//stars
function makeStar(xs,ys){
    var S = {
        x: xs, 
        y: ys,
        move: starMove,
        speed: -1.5,
        display: starDisplay};
    return S;
}

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

function starDisplay(xs,ys){
    image(star, this.x, this.y,75,75);
}

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

function removeStarThatHaveSlippedOutOfView(){
    for (var i = 0; i < stars.length; i++){
        if (stars[i].x < -1440) {
            stars.shift(stars[i]);
        }
    }
}

function addNewStar(){
    var lastStar = stars[stars.length - 1];
    if(lastStar.x < -900){
        var a = makeStar(480,325);
        stars.push(a);
    }
}

//fish school
function makeFish(xf,yf){
    var F = {
        x: xf, 
        y: yf,
        move: fishMove,
        speed: -3.0,
        display: fishDisplay};
    return F;
}

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

function fishDisplay(xf,yf){
    image(fishschool, this.x, this.y,200,200);
}

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

function removeFishThatHaveSlippedOutOfView(){
    for (var i = 0; i < fishes.length; i++){
        if (fishes[i].x < -1440) {
            fishes.shift(fishes[i]);
        }
    }
}

function addNewFishRandomly(){
    var newFishLikelihood = 0.002; 
    if (random(0,2) < newFishLikelihood) {
        fishes.push(makeFish(480,25));
    }
}

//bubbles
function makeBubble(xb,yb){
    var B = {
        x: xb, 
        y: yb,
        yspeed: -3,
        move: bubbleMove,
        speed: -1.5,
        display: bubbleDisplay};
    return B;
}

function bubbleMove(){
    this.x +=this.speed;
    this.y +=this.yspeed;
}

function bubbleDisplay(xb,yb){
    noStroke();
    fill(255);
    ellipse(this.x,this.y,10,10);
    ellipse(this.x+a,this.y+a1,20,20);
    ellipse(this.x+b,this.y+b1,17,17);
    ellipse(this.x+c,this.y+c1,23,23);
    ellipse(this.x+d,this.y+d1,15,15);

}

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

function removeBubbleThatHaveSlippedOutOfView(){
    for (var i = 0; i < bubbles.length; i++){
        if (bubbles[i].x < -1440) {
            bubbles.shift(bubbles[i]);
        }
    }
}

function addNewBubbleRandomly(){
    var newBubbleLikelihood = 0.02; 
    if (random(0,2) < newBubbleLikelihood) {
        bubbles.push(makeBubble(185,480));
    }
}

function draw() {
    background(backgroundImage); 

    updateAndDisplayBubble();
    addNewBubbleRandomly();
    removeBubbleThatHaveSlippedOutOfView()

    updateAndDisplayWeed2();
    addNewWeed2();
    removeWeed2ThatHaveSlippedOutOfView();

    updateAndDisplayBeach();
    addNewBeach();
    removeBeachThatHaveSlippedOutOfView();

    updateAndDisplayWeed();
    addNewWeed();
    removeWeedThatHaveSlippedOutOfView();

    updateAndDisplayCoral2();
    addNewCoral2();
    removeCoral2ThatHaveSlippedOutOfView();

    updateAndDisplayFish();
    addNewFishRandomly();
    removeFishThatHaveSlippedOutOfView();

    updateAndDisplayCoral2b();
    addNewCoral2b();
    removeCoral2bThatHaveSlippedOutOfView();
    updateAndDisplayCoral2n();
    addNewCoral2n();
    removeCoral2nThatHaveSlippedOutOfView();

    updateAndDisplayGroup();
    addNewGroup();
    removeGroupThatHaveSlippedOutOfView();

    image(fish,140,100,200,230);

    updateAndDisplayCoral1();
    addNewCoral1();
    removeCoral1ThatHaveSlippedOutOfView();
    updateAndDisplayCoral1n();
    addNewCoral1n();
    removeCoral1nThatHaveSlippedOutOfView();

    updateAndDisplayStar();
    addNewStar();
    removeStarThatHaveSlippedOutOfView();

    
}

I find the code of this project not too complicated but rather a bit complex, because I need to create many objects to draw on the canvas. Also, the most difficult part is the first object. After successfully make the first object work, the others are much the same with subtle differences. The landscape I created is an under ocean landscape, narrating a fish’s journey wandering around.

Project 11: Generative Landscape

This is the concept sketch of my generative landscape. I wanted to create a road with hills in the background and cars driving across the road. If I had more time with the project, I would’ve added more randomized details to the hills like stripes or grass texture patterns.

My process was pretty simple. I created objects for the different elements that I would be randomizing. For example, I made an array of objects for the hills, the roads, and the cars. I would repeat the process of creating the different functions for the various elements—with minor adjustments to the movement and randomness of each element.

sketch
//Anthony Pan
//Section C

//objects to create:
    //hills
    //cars
    //road

//hold hills
var hillshowing = [];
//object for hills
var hills;

//hold road1
var road1showing = [];
//object for road1
var road1;

var road2;
var road2showing = [];

//car object
var car;
//array holding car object
var carShowing = [];

//car2 object
var car2;

//array holding car2 objects
var car2Showing = [];

//frame counter
var counter = 0;


function setup() {
    createCanvas(480, 300);

    //create hills
    for(var i = 0; i < 20; i++) {
        hills = makeHills(i*30, 245);
        hillshowing.push(hills);
    }

    //create road1
    for(var j = 0; j<10; j++) {
        road1 = makeRoad1(j*10, 280);
        road1showing.push(road1);

    }

    //create road2
    for(var k = 0; k<10; k++) {
        road2 = makeRoad2(k*10, 250);
        road2showing.push(road2);
    }

    //create cars on road1
    for(var h = 0; h < 5; h++) {
        car = makeCar(0, round(random(270, 290)), random(2,4));
        carShowing.push(car);
    }

    //create cars on road2
    for(var c = 0; c < 5; c++) {
        car2 = makeCar2(width, round(random(240, 255)), random(-4,-2));
        car2Showing.push(car2);
    }

}


function draw() {
    //sky 
    background(135, 221, 255);

    //sun
    drawSun();

    //hills
    updateandDrawhills();
    removeHillsOffScreen();
    addNewHill();


    //roads2 / upper roads
    fill(156, 117, 95);
    rect(0, 245, width, 40);
    updateandDrawRoad2();
    removeRoad2offScreen();
    addNewRoad2();

    //roads lower/ road1
    fill(0);
    rect(0, 270, width, 40);
    updateandDrawRoad1();
    removeRoad1offScreen();
    addNewRoad1();

    //draw cars on road2
    updateandDrawCar2();
    removeCars2OffScreen();
    addCar2();

    //draw cars
    updateandDrawCar();
    removeCarsOffScreen();
    addNewCar();

    

 
}


//draw sun
function drawSun() {
    fill("lightyellow");
    noStroke();
    circle(90,80, 40);

}

////////////////////////////////////////////////////////////////////////////////////////////////////
//MAKE Car2 Functions

//car 2 constructor
function makeCar2(cx, cy, zoom) {
    var car2 = {x: cx, y:cy,
        speed:zoom,
        r: random(255),
        g: random(255),
        b: random(255),
        move: car2Move,
        draw: drawCar2 }
    return car2;
}

//draw car2 object
function drawCar2() {
    fill(this.r, this.g, this.b);
    rect(this.x, this.y, 20, 10);

    fill(0);
    ellipse(3+this.x, 10+this.y, 4, 4);
    ellipse(this.x + 17, this.y +10, 4, 4);

}

//update and draw car2
function updateandDrawCar2() {
    for(var i = 0; i < car2Showing.length; i++) {
        car2Showing[i].move();
        car2Showing[i].draw();
    }
}

//move car2
function car2Move() {
    this.x += this.speed;
}

//remove car2s that are off screen 
function removeCars2OffScreen() {
    var cars2ToKeep = [];
    for (var i = 0; i < car2Showing.length; i++){
        if (car2Showing[i].x > 0) {
            cars2ToKeep.push(car2Showing[i]);
        }
    }
    car2Showing = cars2ToKeep; // remember the showing cars

}

//make new car2 based on probability 
function addCar2() {
    var newcarlikelihood = 0.03;
    if(random(0,1) < newcarlikelihood) {
         car2Showing.push(makeCar2(width, round(random(240, 255)), random(-4,-2)));
    }
}



////////////////////////////////////////////////////////////////////////////////////////////////////
//MAKE Car Functions

//car constructor
function makeCar(cx, cy, zoom) {
    var car = {x: cx, y:cy,
        speed:zoom,
        r: random(255),
        g: random(255),
        b: random(255),
        move: carMove,
        draw: drawCar }
    return car;
}

//draw car object
function drawCar() {
    fill(this.r, this.g, this.b);
    rect(this.x, this.y, 20, 10);

    fill(0);
    ellipse(3+this.x, 10+this.y, 4, 4);
    ellipse(this.x + 17, this.y +10, 4, 4);

}

//update car position and draw car
function updateandDrawCar() {
    for(var i = 0; i < carShowing.length; i++) {
        carShowing[i].move();
        carShowing[i].draw();
    }
}

//move car
function carMove() {
    this.x += this.speed;
}

//remove cars that are off screen
function removeCarsOffScreen() {
    var carsToKeep = [];
    for (var i = 0; i < carShowing.length; i++){
        if (carShowing[i].x < width) {
            carsToKeep.push(carShowing[i]);
        }
    }
    carShowing = carsToKeep; // remember the showing cars

}

//make new car every 100 frames
function addNewCar() {
    counter +=1;
    if (counter % 100== 0){
        carShowing.push(makeCar(0, round(random(270, 290)), random(2,4)));
    }

}




////////////////////////////////////////////////////////////////////////////////////////////////////
//MAKE ROAD2 Functions

//constructor for road2
function makeRoad2(rx, ry) {
    var road2 = {x:rx, y:ry,
        speed: -0.7,
        move: road2Move,
        draw: drawRoad2 }

    return road2;
}

//draw road2 
function drawRoad2() {
    fill(120);
    rect(this.x, this.y, width, 40);

    for(var i = 0; i < 50; i++) {
        var dx = i * 10;
        fill("yellow");
        rect(this.x + dx, this.y + 10, 6, 2);
    }
}

//update road2 position and draw
function updateandDrawRoad2() {
    for(var i = 0; i < road2showing.length; i++) {
        road2showing[i].move();
        road2showing[i].draw();
    }
}

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

//remove roads off the screen
function removeRoad2offScreen() {
    var road2ToKeep = [];
    for (var i = 0; i < road2showing.length; i++){
        if (road2showing[i].x + width > 0) {
            road2ToKeep.push(road2showing[i]);
        }
    }
    road2showing = road2ToKeep; // remember the showing roads
}

function addNewRoad2() {
    counter +=1;
    if (counter % 17 == 0){
        road2showing.push(makeRoad2(width,250));
    }

}



////////////////////////////////////////////////////////////////////////////////////////////////////
//MAKE ROAD1 FUNCTIONS

//constructor for road1
function makeRoad1(rx, ry) {
    var road1 = {x:rx, y:ry,
        speed: -0.5,
        move: road1Move,
        draw: drawRoad1 }

    return road1;
}


//draw road
function drawRoad1() {
    fill(120);
    rect(this.x, this.y, width, 40);

    for(var i = 0; i < 50; i++) {
        var dx = i * 10;
        fill("yellow");
        rect(this.x + dx, this.y + 10, 6, 2);
    }
}

//update road1 position and draw
function updateandDrawRoad1() {
    for(var i = 0; i < road1showing.length; i++) {
        road1showing[i].move();
        road1showing[i].draw();
    }
}

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

//remove roads off the screen
function removeRoad1offScreen() {
    var road1ToKeep = [];
    for (var i = 0; i < road1showing.length; i++){
        if (road1showing[i].x + width > 0) {
            road1ToKeep.push(road1showing[i]);
        }
    }
    road1showing = road1ToKeep; // remember the showing roads
}

function addNewRoad1() {
    counter +=1;
    if (counter % 25 == 0){
        road1showing.push(makeRoad1(width,280));
    }

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//MAKE HILLS FUNCTIONS

//update hill position and draw hill
function updateandDrawhills() {
    for(var i =0; i < hillshowing.length; i++){
        hillshowing[i].move();
        hillshowing[i].draw();
    }

}


//remove hills that have left the screen 
function removeHillsOffScreen(){
    var hillsToKeep = [];
    for (var i = 0; i < hillshowing.length; i++){
        if (hillshowing[i].x +20 > 0) {
            hillsToKeep.push(hillshowing[i]);
        }
    }
    hillshowing = hillsToKeep; // remember the showing hills
}


//make new hill from right side of canvas
function addNewHill() {
    counter +=1;
    if (counter % 25 == 0){
        hillshowing.push(makeHills(width+20,245));
    }
}

//hill constructor
function makeHills(hx, hy) {
    var hills = {x:hx, y:hy, 
        width:random(40, 70), 
        height:random(100, 300), 
        r:0, g:random(115,200), b: random(15, 35),
        speed: -1.0,
        move: hillsMove,
        draw: drawHills }
    return hills;

}

//draw hills
function drawHills() {
    fill(this.r, this.g, this.b);
    ellipse(this.x, this.y, this.width, this.height);
}


//move hill to left
function hillsMove() {
    this.x += this.speed;
}



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:

Project 11

sketch
function setup() {
    createCanvas(400,400);
    // create an initial collection of buildings
    for (var i = 0; i < 4; i++){
        var cx = random(width);
        var cy = random(320,350)
        cars[i] = makeCar(cx,cy,color(random(255),random(255),random(255)),random(25,45));
    }
    for (var i = 0; i < 3; i++){
        var bx = random(width);
        var by = random(20,150)
        birds[i] = makeBird(bx,by,color(random(255),random(255),random(255)));
    }
    frameRate(10);
}
var cars = [];
var birds = [];
function draw() {
    push()
    fill(170,170,255)
    rect(0,0,400,270)
    fill(0,170,0)
    rect(0,270,400,130)
    drawRoad()
    drawSun()
    for (i=0; i<=50; i++){
        drawTree(i*50+20,260)  
    }
    updateAndDisplayCars();
    removeCarsThatHaveSlippedOutOfView();
    addNewCarsWithSomeRandomProbability();
    updateAndDisplayBirds(); 
    removeBirdsThatHaveSlippedOutOfView();
    addNewBirdsWithSomeRandomProbability();
}
function drawSun(){
    fill(255,200,0)
    ellipse(0,0,100,100)
}
function drawTree(x,y){
    fill(0,255,0)
    triangle(x,y,x-7,y+15,x+7,y+15)
    fill(50,30,0)
    rect(x-2,y+15,4,10)
}
function drawRoad(){
    fill(0)
    rect(0,300,400,60)
    fill(255,255,0)
    for (i = 0; i <= 10; i++){
        rect(50*i+15,325,20,5)
    }
}
function removeCarsThatHaveSlippedOutOfView(){
    var carsToKeep = [];
    for (var i = 0; i < cars.length; i++){
        if (cars[i].x > 0) {
            carsToKeep.push(cars[i]);
        }
        print(cars[i])
    }
    cars = carsToKeep; // remember the surviving cars

}
function updateAndDisplayCars(){
    // Update the cars's positions, and display them.
    for (var i = 0; i < cars.length; i++){
        cars[i].move();
        cars[i].display();
    }
}
function addNewCarsWithSomeRandomProbability() {
    // With a probability, add a new car to the end.
    var newCarLikelihood = 0.05; 
    if (random(0,1) < newCarLikelihood) {
        cars.push(makeCar(0,random(305,345),color(random(255),random(255),random(255)),random(25,45)));
    }
}

// method to update position of cars every frame
function carMove() {
    this.x += this.speed;
}
// draw the cars
function carDisplay() {
    push()
    fill(this.c)
    rect(this.x,this.y,this.l,10)
    rect(this.x+8,this.y-10,14,10)
    ellipse(this.x+11,this.y+8,10,10)
    ellipse(this.x+26,this.y+8,10,10)
    pop()
}
//make new car with different XY location, color, length, and speed
function makeCar(birthLocationX,birthLocationY,color,carLength) {
    var car = {x: birthLocationX,
                y: birthLocationY,
                c: color,
                l: carLength,
                speed: random(2,10),
                move: carMove,
                display: carDisplay}
    return car;
}
function removeBirdsThatHaveSlippedOutOfView(){
    var birdsToKeep = [];
    for (var i = 0; i < birds.length; i++){
        if (birds[i].x > 0) {
            birdsToKeep.push(birds[i]);
        }
        print(birds[i])
    }
    birds = birdsToKeep; // remember the surviving cars
}
function updateAndDisplayBirds(){
    // Update the cars's positions, and display them.
    for (var i = 0; i < birds.length; i++){
        birds[i].move();
        birds[i].display();
    }
}
function addNewBirdsWithSomeRandomProbability() {
    // With a probability, add a new bird to the end.
    var newBirdLikelihood = 0.05; 
    if (random(0,1) < newBirdLikelihood) {
        birds.push(makeBird(width,random(20,160),color(random(255),random(255),random(255))));
    }
}

// method to update position of birds every frame
function birdMove() {
    this.x -= this.speedX;
    this.y += this.speedY
}
// draw the birds
function birdDisplay() {
    push()
    fill(this.c)
    triangle(this.x,this.y,this.x+6,this.y+1.5,this.x+6,this.y-1.5)//beak
    ellipse(this.x+9,this.y,7,7) //head
    ellipse(this.x+17,this.y+4,15,8)//body
    arc(this.x+18, this.y, 10, 10, -0.7, PI-0.7,CHORD)//wings
    ellipse(this.x+8,this.y-1,1,1)//eyes
    pop()
}
//make new bird with different location, color, speedXY
function makeBird(birthLocationX,birthLocationY,color) {
    var bird = {x: birthLocationX,
                y: birthLocationY,
                c: color,
                speedX: random(5,8),
                speedY: random(-1.5,1.5),
                move: birdMove,
                display: birdDisplay}
    return bird;
}

For this project, I created 2 arrays of objects: cars and birds. Cars have random color, length, speedX, and y position on the road; birds have random color, y position in the sky, speedX, and speedY.

Project 11: Generative Landscape

sketchDownload
// this program displays a landscape of a stone path along a stream in the woods.

// empty arrays for objects:
var bkgrndtrees = [];
var path = [];
var stream = [];
var trees = [];
var allArrays = [bkgrndtrees, path, stream, trees];

// speed of landscape shift, per frame
// adjusted for background+foreground so 'closer' objects move faster than 'far away' ones
var shift = -1;

function setup() {
    createCanvas(480, 300);
    background(80, 125, 60);
    frameRate(200);

    // create initial collections of objects:
    fillBkgrndtrees();
    fillPath();
    fillStream();
    fillTrees();

    // sort objects in arrays to be drawn properly:
    for (a=0; a<allArrays.length; a++) {
        if (allArrays[a]!=stream){          // stream should not be ordered
            orderObjects(allArrays[a]);
        }
    }
}

// fills backgroundTrees array with initial trees:
function fillBkgrndtrees() {
    for (var i = 0; i < 320; i++) {
        var rx = random(width+75);
        var ry = random(-height/25, 2*height/5);      // top of canvas = background
        bkgrndtrees[i] = makeTree(rx, ry);
    }
}

// fills foreground tree array with initial trees:
function fillTrees() {
    for (var i = 0; i < 5; i++) {
        var rx = random(width+75);
        var ry = random(4*height/5, 3*height/2);    // bottom of canvas = foreground
        trees[i] = makeTree(rx, ry);
    }
}

// fills path array with initial stones:
function fillPath() {
    for (var i = 0; i < 15; i++) {
        var size = random(width/25, width/10);
        var col = color(random(90, 120));
        var x = i*50;
        var ry = random(height/2, 3*height/5);
        path[i] = makeStone(x, ry, size, col);
    }
}

// fills stream array with objects based on stone path:
function fillStream() {
    for (var i = 0; i < path.length; i++) {
        var x = i*50;
        var y = path[i].y + path[i].size;
        stream[i] = makePoint(x, y);
    }
}

// creates a tree object
function makeTree(tx, ty) {
    // background trees:
    if (ty < height/2) {
        var tree = {x:tx,
                    y:ty,
                    age:random(2, 11),
                    trunkc: color(random(70, 90), random(55, 75), random(30, 55)),
                    leavesc: color(random(0, 75), random(65, 175), random(50)),
                    show: showTree,
                    move: moveObject,
                    speed: shift*.85 }
    }
    // foreground trees:
    else {
        var tree = {x:tx,
                    y:ty,
                    age:random(4, 7),
                    trunkc: color(random(50, 80), random(20, 50), random(10, 20)),
                    leavesc: color(random(0, 100), random(100, 200), random(30)),
                    show: showTree,
                    move: moveObject,
                    speed: shift*1.15 }
    }

    return tree;
}

// creates a stone object
function makeStone(sx, sy, ssize, scol) {
    var stone = {x:sx,
                 y:sy,
                 size:ssize,
                 c: scol,
                 show: showStone,
                 move: moveObject,
                 speed: shift}
    return stone;
}

// creates a point object (for stream curve);
function makePoint(px, py) {
    var pnt = {x:px,
               y:py,
               size:width/50,
               c: color(50, 125, 175),
               show: showStone,
               move: moveObject,
               speed: shift}
    return pnt;
}

function draw() {
    background(80, 125, 60);

    // draw all objects in all arrays:
    for (j=0; j<allArrays.length; j++) {
        thisArray = allArrays[j];
        drawObjects(thisArray);
        if (thisArray!=stream) {        // stream is updated with path
            // order and updates arrays:
            orderObjects(thisArray);
            updateArray(thisArray);
        }
    }
}

// draws and moves objects in an array
function drawObjects(array) {
    for (i=0; i<array.length; i++) {
        thisObj = array[i];
        thisObj.show();
        thisObj.move();
    }
    if (array==stream) {
        drawStream();
    }
}

// uses curve shape and array points ot draw stream
function drawStream() {
    push();
    noFill();
    stroke(50, 125, 175);
    strokeWeight(15);
    curveTightness(-.2);
    beginShape();
    curveVertex(stream[0].x, stream[0].y);
    curveVertex(stream[0].x, stream[0].y);
    for (var m=1; m<stream.length-1; m++){
        curveVertex(stream[m].x, stream[m].y);
    }
    curveVertex(stream[stream.length-1].x, stream[stream.length-1].y);
    endShape();
    pop();
}

// sorts objects in an array according to the y feild
// this ordering ensures accurate depth on canvas
function orderObjects(array) {
    for (var j=0; j<array.length-1; j++) {
        var counter = 0;
        for (var i=0; i<array.length-1; i++) {
            if (array[i].y > array[i+1].y) {
                var tmp = array[i];
                array[i] = array[i+1];
                array[i+1] = tmp;
                counter += 1;
            }
        }
        if (counter==0) {
            break;
        }
    }
}

// updates all allArrays
// adds new objects to end and deletes unused objects (off canvas)
function updateArray(array) {
    if (array==trees || array==bkgrndtrees) {
        // add new trees to array off-canvas:
        // background trees:
        var treeLikelihoodB = 320/555;
        if (random(1) < treeLikelihoodB) {
            var ry = random(-height/25, 2*height/5);    // top of canvas = background
            bkgrndtrees.push(makeTree(width+75, ry));
        }
        // foreground trees:
        var treeLikelihoodF = 5/555;
        if (random(1) < treeLikelihoodF) {
            var ry = random(3*height/4, 3*height/2);      // bottom of canvas = foreground
            trees.push(makeTree(width+75, ry));
        }
    }
    else {
        // path and stream use fixed x values:
        if (frameCount%50==0) {
            var size = random(width/25, width/10);
            var col = color(random(90, 120));
            var ry = random(height/2, 3*height/5);
            path.push(makeStone(700, ry, size, col));
            col = color(0, 50, 150);
                var y = ry + size;
            stream.push(makePoint(700, y));
        }
    }

    // remove any object no longer on canvas:
    var keep = [];
    for (var k=0; k<array.length; k++) {
        if (array[k].x > 0) {
            keep.push(array[k]);
        }
    }
    array = keep;
}

// draws tree based on age
function showTree() {
    if (this.y < height/2) {     // top of canvas = background
        var h = this.age*10;
        var w = this.age*2;
    }
    else {                      // bottom of canvas = foreground
        var h = this.age*12;
        var w = this.age*2.5;
    }
    var cx = this.x + w/2;
    var cy = this.y - h*1.5;

    if (this.age > 5) {             // older trees
        stroke(50, 40, 30);
        fill(this.trunkc);
        rect(this.x, this.y-h, w, h);
        fill(this.leavesc);
        for (var i=0; i<3; i++) {
            stroke(0, 75, 0);
            circle(cx - (this.age*4*i) + (this.age*4),
                   cy - (this.age*1.5) + (this.age*3*i),
                   this.age*5);
            circle(cx + (this.age*4*i) - (this.age*4),
                   cy - (this.age*1.5) + (this.age*3*i),
                   this.age*5);
            ellipse(cx - (this.age*6*i) + (this.age*6),
                    cy + this.age,
                    this.age*5,
                    this.age*6);
            ellipse(cx,
                    cy - (this.age*3) + (this.age*4*i),
                    this.age*7,
                    this.age*5);
        }
        noStroke();
        ellipse(cx, cy + this.age, this.age*12, this.age*9);
    }
    else {                          // younger trees
        stroke(50, 40, 30);
        fill(this.trunkc);   // tree trunk lighter brown
        rect(this.x, this.y-h, w/2, h);
        fill(this.leavesc);
        for (var i=0; i<3; i++) {
            stroke(0, 75, 0);
            circle(cx - (this.age*3*i) + (this.age*3),
                   cy - (this.age*1.5) + (this.age*2*i),
                   this.age*4);
            circle(cx + (this.age*3*i) - (this.age*3),
                   cy - (this.age*1.5) + (this.age*2*i),
                   this.age*4);
            ellipse(cx - (this.age*4*i) + (this.age*4),
                    cy + this.age,
                    this.age*4,
                    this.age*5);
            ellipse(cx,
                    cy - (this.age*4) + (this.age*4*i),
                    this.age*6,
                    this.age*4);
        }
        noStroke();
        ellipse(cx, cy + this.age/2, this.age*11, this.age*9);
    }
}

// draws stone for path
function showStone() {
    stroke(75);
    fill(this.c);
    ellipse(this.x, this.y, this.size, this.size/2);
}

// updates x values to move the landscape along
function moveObject() {
    this.x += this.speed;
}

For this project, I was inspired by a trail I used to walk a lot growing up. I struggled a bit to order the objects in a way that looks nice and is recognizable as a landscape, but I think the orderObjects() function that I created helped a lot with that. I also found it difficult to create the stream using a curve shape, but I am again really pleased with how well it came out. I wanted the path and stream to flow along together, and they do. To give more of a landscape effect, I adjusted the shift values for moving the objects so that things in the foreground move faster than things in the background.

My initial sketch of the stream in the woods.

Project 11: Generative Landscape

wpf-landscape.js
//Patrick Fisher, Section B, wpf@andrew.cmu.edu Assignment -11-project
var trackLines = []; //array for converyer belt
var robots = []; //array for the robots

function setup() {
    createCanvas(480,300);
    background(219.219,211);
    for(var i = 0; i <= 9; i++){
        trackLines[i] = i*48; //fills the track array
    }

    for(var i = 0; i <= 5; i++){
        robots[i] = makeRobot(i); //fills the robot array
        robots[i].centerX = -50 + (i*-200);
    }
}

function draw(){
    push();
    stroke(0);
    strokeWeight(4);
    fill(54,54,66);
    rect(0,50,width,200);
    fill(28,150,195);
    rect(0,25,width,25);
    rect(0,250,width,25);
    stroke(0);
    strokeWeight(3); //draws the lines and moves them forward
    for(var i = 0; i <= 9; i++){
        line(trackLines[i],50,trackLines[i],250);
        trackLines[i] += 1;

        if(trackLines[i] >= width){ //sends a line back to the start when it gets to big
            trackLines[i] = 0;
        }
    }
    pop();

    for(var i = 0; i <= 5; i++){
        robots[i].draw(); //draws the robots
        

        robots[i].centerX ++; //sends the robots forward
        
        if(robots[i].centerX >= 800){ //deletes a robot from the array when it gets too far off screen and makes a new one
            robots.shift();
            robots.push(makeRobot(0));
            robots[5].centerX = -400
        }
    }
}

function makeRobot(i) {
    var rob = {centerX: 0, //funciton for making the robot
               head: floor(random(0,3)),
               eyes: floor(random(0,4)),
               glowColor: clrSelect(floor(random(0,6))), //sends a random number to the color select function to set the color variable
               mouth: floor(random(0,3)), //5
               chest: floor(random(0,2)),
               chestPiece: floor(random(0,3)), //8
               arms: floor(random(0,3)), //4
               legs: floor(random(0,3)), //3
               draw: drawRobot,
               drawHead: drawRobotHead,
               drawBody: drawRobotBody,
               drawEye: robotEyes,
               drawMouth: robotMouth,
               drawPiece: robotChestPiece,
               drawArms: robotArms,
               drawLegs: robotLegs,
           }
    return rob;

}

function drawRobot(){// draws the robot in fragments
    this.drawHead();
    this.drawBody();

}

function drawRobotHead(){
    fill(101,108,127);
    if(this.head == 0){
        circle(this.centerX,90,60);
    }
    if(this.head == 1){
        push();
        rectMode(CENTER);
        rect(this.centerX,90,60,60);
        pop();
    }
    if(this.head == 2){
        triangle(this.centerX,120,this.centerX-50,70,this.centerX+50,70);
    }

    this.drawEye();

    this.drawMouth();
    

}

function drawRobotBody(){
    fill(101,108,127);
    if(this.chest == 0){
        rect(this.centerX-25,120,50,75);
    }
    if(this.chest == 1){
        ellipse(this.centerX, 157.5,50,75);
    }
    
    this.drawPiece();

    this.drawArms();

    this.drawLegs();


}

function robotEyes() {
    push();
    fill(this.glowColor);
    if(this.eyes == 0){
        circle(this.centerX + 15,85,20);
        circle(this.centerX - 15,85,20);
    }

    if(this.eyes == 1){
        push();
        rectMode(CENTER);
        rect(this.centerX + 15, 85, 15, 15);
        rect(this.centerX - 15, 85, 15, 15);
        pop();

    }
    if(this.eyes == 2){
        push();
        stroke(this.glowColor);
        strokeWeight(3);
        line(this.centerX + 20, 80 , this.centerX + 5, 80);
        line(this.centerX - 20, 80 , this.centerX - 5, 80);
        pop()
    }

    if(this.eyes == 3){
        push();
        stroke(this.glowColor);
        strokeWeight(3);
        line(this.centerX + 15, 90 , this.centerX + 15, 75);
        line(this.centerX - 15, 90 , this.centerX - 15, 75);
        pop()
    }
    pop();
}

function robotMouth() {
    if(this.mouth == 0){
        push();
        stroke(this.glowColor);
        strokeWeight(4);
        noFill();
        arc(this.centerX, 100, 20, 20, 0, PI);
        pop();
    }

    if(this.mouth == 1){
        push();
        stroke(this.glowColor);
        strokeWeight(4);
        line(this.centerX + 10, 105, this.centerX -10, 105);
        pop();
    }
    if(this.mouth == 2){
        push();
        fill(this.glowColor);
        rect(this.centerX - 10, 101, 20, 8);
        line(this.centerX -10, 105, this.centerX + 10, 105);
        pop();

    }

}

function robotChestPiece() {
    if(this.chestPiece == 0){
        push();
        fill(this.glowColor);
        circle(this.centerX, 147,20);
        pop();
    }
    if(this.chestPiece == 1){
        push();
        fill(this.glowColor);
        rectMode(CENTER);
        rect(this.centerX, 147,20,20);
        pop();
    }
    if(this.chestPiece == 2){
        push();
        fill(this.glowColor);
        translate(this.centerX,147);
        rotate(radians(45));
        rectMode(CENTER);
        rect(0,0,20,20);
        pop();
    }

}

function robotArms(){
    if(this.arms == 0){
        push();
        stroke(0);
        strokeWeight(2);
        line(this.centerX + 25, 147, this.centerX + 50, 147);
        line(this.centerX - 25, 147, this.centerX - 50, 147);
        pop();
        circle(this.centerX - 55, 147, 10);
        circle(this.centerX + 55, 147, 10);

    }
    if(this.arms == 1){
        ellipse(this.centerX+37.5,147,25,10);
        ellipse(this.centerX-37.5,147,25,10);
    }
    if(this.arms == 2){
        push();
        rectMode(CENTER);
        square(this.centerX+35,147,20);
        square(this.centerX-35,147,20);
        pop();

    }
}

function robotLegs(){
    if(this.legs == 0){
        push()
        stroke(0);
        strokeWeight(2);
        line(this.centerX + 20, 195, this.centerX + 20, 225);
        line(this.centerX - 20, 195, this.centerX - 20, 225);
        pop();
        circle(this.centerX + 20, 230, 10);
        circle(this.centerX - 20, 230, 10);

    }
    if(this.legs == 1){
        ellipse(this.centerX - 15, 215, 10,40);
        ellipse(this.centerX + 15, 215, 10,40);
    }
    if(this.legs == 2){
        triangle(this.centerX-15, 197.5, this.centerX - 10, 235, this.centerX - 20, 235);
        triangle(this.centerX+15, 197.5, this.centerX +10, 235, this.centerX + 20, 235);
    }
}

function clrSelect(i){
    if(i == 0){
        var c = color(128,196,99); //green
    }
    if(i == 1){
        var c = color(182,20,29); //red
    }
    if(i == 2){
        var c = color(10,201,239); //blue
    }
    if(i == 3){
        var c = color(217,16,207); //purple
    }
    if(i == 4){
        var c = color(248,241,25); //yellow
    }
    if(i == 5){
        var c = color(244,239,221); //off white
    }

    return c;

}

For my project, I did a robot factory line, with all the different parts of the robots changing. I started with getting the conveyor belt to look correct. Then I worked on making one look for the robot and getting it to loop continuously. Afterward, I started to separate the body parts into distinct functions and then implements the if statements to draw different types of body parts. I am very happy with how it worked out, I think the robots look kind of cute and I am happy with how seamless the loop is. I also think I have a good amount of variety so the robots do not get immediately boing.

Project 11: Generative Landscape

As winter approaches, I wanted create a landscape that resembles the cold weather and loneliness of the season. That’s why I decided to keep a greyscale color scheme.

sketch
// Christy Zo
// andrew id: czo
// Section C

var hill = [];
var hill2 = [];
var noiseParam = 0;
var noiseStep = 0.05;
var noiseParam2 = 0;
var noiseStep2 = 0.05

var snowflakePerLayer = 200;
var maxSize = 3;
var gravity = 0.75;
var layerCount = 5;
var snowflakes = [];

var walkImage = [];
var newCharacter = [];
var airplane;
var newPlane = [];

var buildings = [];



function preload() {
    var filenames = [];
    filenames[0] = "https://i.imgur.com/Uz3ltZC.png";
    filenames[1] = "https://i.imgur.com/ofNc4Wv.png";
    filenames[2] = "https://i.imgur.com/7hMA7W6.png";
    filenames[3] = "https://i.imgur.com/3RBTODb.png";
    filenames[4] = "https://i.imgur.com/FliwTsj.png";

    for (var i = 0; i < filenames.length; i++) {
        walkImage[i] = loadImage(filenames[i]);
    }
    airplane = loadImage("https://i.imgur.com/dbPwlhp.png");
}

//airplane 
function makePlane(px, pdx, py, pdy) {
    var p = {x: px, dx: pdx, y:py, dy: pdy,
            stepFunction: stepPlane,
            drawFunction: drawPlane
        }
    return p;
}

function stepPlane() {
    this.x += this.dx;
    this.y += this.dy;

    if (this.x > 480) {
        this.x = 0;
        this.y = 100;
    }
}

function drawPlane() {
    image(airplane, this.x, this.y, 20, 20);
}

//person
function makeCharacter(cx, cdx) {
    var c = {x: cx, dx: cdx,
             // walkingRight: true, 
             imageNum: 0,
             stepFunction: stepCharacter,
             drawFunction: drawCharacter
         }
    return c;
}

function stepCharacter() {
    this.x += this.dx;
    this.imageNum += 1;
    
    if (this.imageNum == 4 ) {
        this.imageNum = 0;
    }

    if (this.x >= 680) { 
        this.x = 200;
    } 
}

function drawCharacter() {
    image(walkImage[this.imageNum], this.x, 430);
    
}

//snowflake update
function updateSnowflake(snowflake) {
    var diameter = (snowflake.l * maxSize) / layerCount;
    if (snowflake.y > height + diameter) {
        snowflake.y = -diameter;
    } else {
        snowflake.y += gravity * snowflake.l * snowflake.mass;
    }
}

//buildings
function updateAndDisplayBuildings(){
    // Update the building's positions, and display them.
    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

function removeBuildingsThatHaveSlippedOutOfView(){
    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep; // remember the surviving buildings
}

function addNewBuildingsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newBuildingLikelihood = 0.007; 
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}

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

// draw the building and some windows
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(255); 
    noStroke; 
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    stroke(200); 
    fill(200);
    for (var i = 0; i < this.nFloors; i++) {
        rect(5, -15 - (i * floorHeight), this.breadth - 10, 10);
    }
    pop();
}

function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 50,
                speed: -1.0,
                nFloors: round(random(2,8)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}


function setup() {
    createCanvas(480, 480);
    noStroke();
    frameRate(20);
    for (i=0; i<width/5+1; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 100, height);
        
        hill.push(value);
        noiseParam += noiseStep;

    }


// snowflakes
    for (let l = 0; l < layerCount; l++) {
        snowflakes.push([]);
        for (let i = 0; i < snowflakePerLayer; i++) {
            snowflakes[l].push({
            x: random(width),
            y: random(height),
            mass: random(0.75, 1.25),
            l: l + 1
            });
        }
    }
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }

    imageMode(CENTER);

    var d = makeCharacter(50, 1);
    newCharacter.push(d);

    var p = makePlane(10, 5, 100, -1);
    newPlane.push(p);
    
}

function draw() {
    background(0);

    for (let l = 0; l < snowflakes.length; l++) {
        var layer = snowflakes[l];

        for (let i = 0; i < layer.length; i++) {
            var snowflake = layer[i];
            fill(255);
            circle(snowflake.x, snowflake.y, (snowflake.l * maxSize) / layerCount);
            updateSnowflake(snowflake);
        }
    }

    beginShape();
        vertex(0, height);
        for (i=0; i<width/5+1; i++) {
            noStroke();
            fill(200);
            vertex(i*5, hill[i]);
 

        }
        vertex(width, height);
        endShape();

        var n = noise(noiseParam);
        var value = map(n, 0, 1, 100, height);
        hill.shift();
        // append(hill, value);
        hill.push(value);
        noiseParam += noiseStep;
    fill(150);
    rect(0, 430, width, height);


    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 


    newCharacter[0].stepFunction();
    newCharacter[0].drawFunction();

    newPlane[0].stepFunction();
    newPlane[0].drawFunction();
    // image(walkImage[1], 100,100);

}

*Due to the way I saved my png drawing of the person, you have to wait a little long for the person to appear!*

After I created this work, I realized that the mountain behind moves significantly faster than everything else, making it look like this space is not on earth. Maybe this could be what winter looks like in a different planet.

Generative Landscape

sketchDownload
var cld = [];
var shl = [];

function setup() {
    createCanvas(480, 320);
    background(200);
    noStroke();
}

function draw() {
    //static background
    fill(57, 16, 115);
    rect(0, 0, 480, 40);
    fill(129, 21, 150);
    rect(0, 40, 480, 40);
    fill(189, 28, 119);
    rect(0, 80, 480, 40);
    fill(224, 47, 31);
    rect(0, 120, 480, 40);
    fill(230, 107, 50);
    rect(0, 160, 480, 40);
    fill(255, 185, 64);
    circle(240, 200, 60);
    fill(179, 161, 91);
    rect(0, 200, 480, 120);

    //cloud code
    if(random() > 0.95) cld.push(makeCloud((random()*120), color(random()*30+220, 220, random()*30+220))); //chance to draw new cloud
    for(let i = 0; i < cld.length; i++) { //draws and updates clouds
      cld[i].drawCloud();
      cld[i].moveCloud();
    }
    if(cld[0].x > 480) cld.shift(); //removes clouds that move too far

    //shell code
    if(random() > 0.85) shl.push(makeShell(random()*200+120, color(random()*255, random()*255, random()*255), random()*3)); //chacne to draw new drawShell
    for(let i = 0; i < shl.length; i++) { //draws and updates shells
      shl[i].drawShell();
      shl[i].moveShell();
    }
    if(shl[0].x > 480) shl.shift(); //removes shells that move too far
}

function makeCloud(ty, tc) {
    var cloud = {x: 0, y: ty, c: tc};
    return cloud;
}

function drawCloud() {
    fill(this.c);
    ellipse(this.x, this.y, 40, 20);
}

function moveCloud() {
    this.x += 10;
}

function makeShell(ty, tc, ts) {
    var shell = {x: 0, y: ty, c: tc, s: ts}
    return shell;
}

function drawShell() {
    fill(this.c);
    if(this.s < 1) circle(this.x, this.y, 20);
    else if(this.s < 2) square(this.x, this.y, 20);
    else triangle(this.x, this.y, this.x+10, this.y+20, this.x+20, this.y);
}

function moveShell() {
    this.x += 10;
}

This isn’t running correctly right now and I can’t figure out why ?-?

I made a sunset landscape because I thought I could incorporate some really cool colors into the background. First I coded the hard landscape. Since the sun is so far away, it will look like it isn’t moving. Next I created very simple clouds. To create randomness and variety in my landscape the clouds have a randomized color and height. I created a method that updated their x position so that they’d look like they were “moving” across the screen. After that I made shells. I followed a similar procedure, but I also added shape as a random variable. Having different shaped/colored shells in different locations helps make the landscape more exciting. I wish the code was displayed properly so you could see the final product 🙁

Landscape: Tulip Fields

I worked too hard on this project. I ended up drawing all of the images in my code on procreate, so I do not have many sketches except for some resizing issues.

Math on Bottom side
Trying to figure out tulip configuration

The code was easier to figure out than I thought, but because I decided to use so many elements it got repetitive fast, there are a few things I could have tried i think in ways of getting my stuff to show up more randomly, but because of the way I wrote my code I found that setting that up farther would have not been worth the time for the effect.

Drawing took a few days, but I really like my images.

a cat
very many tulips(color added with code)

Some of the math I had to do really made me think and I can’t quite decide if using images made this take longer or shorter to code.

sketchfile

var szex = 550; // x size for some images
var szey = 365; //y size for some images
var szex2 = 367.2; //x size for smaller img
var szey2 = 240; //y size for smaller img
var tulip = [];
var offset = 0;
var skys = [];
var mountains = [];
var airballoons = [];
var trees = [];
var windmillBottoms = [];
var birds = [];
var electric = [];
var bunnys = [];
var fullWind = [];
var treeLines = [];
var cats = [];



function preload() {
    flowerImg = loadImage("https://i.imgur.com/VSMWH0A.png");
    tree1Img = loadImage("https://i.imgur.com/s66n2RJ.png");
    mountainsImg = loadImage("https://i.imgur.com/FCSY9xA.png");
    birdImg = loadImage("https://i.imgur.com/2zN4jIk.png");
    windmillBottomImg = loadImage("https://i.imgur.com/xGOhbMn.png");
    electricWindmillImg = loadImage("https://i.imgur.com/0R2RKsz.png");
    airballoonImg = loadImage("https://i.imgur.com/HPmyDXQ.png");
    bunnyImg = loadImage("https://i.imgur.com/tOtLTev.png");
    fullWindmillImg = loadImage("https://i.imgur.com/EUCzk9P.png");
    treeLineImg = loadImage("https://i.imgur.com/ipeIQSL.png");
    catImg = loadImage("https://i.imgur.com/d9pAL7i.png");
    skyImg = loadImage("https://i.imgur.com/AykCYLx.png");
}



function tulips(tx) {
    var p = {x: tx, 
        right: tulipsRight,
        display: tulipsDisplay};
    return p;
}

function tulipsRight() {
    return this.x + 900;
}

function tulipsDisplay(tx) {
    flower2Img.resize(flower2Img.width - 100, flower2Img.height);
   image(flower2Img, this.x, 190, 900, 105);//left
}


function bird(bx) {
    var b = {x: bx, 
        right: birdRight,
        display: birdDisplay};
    return b;
}

function birdRight() {
    return this.x + szex2 + width * 9;
}

function birdDisplay(tx) {
   image(birdImg, this.x + 200, 0, 165.4, 100); //move faster across the screen
}



function airballoon(ax) {
    var a = {x: ax, 
        right: airballoonRight,
        display: airballoonDisplay};
    return a;
}

function airballoonRight() {
    return this.x + szex2 + width * 1.5;
}

function airballoonDisplay(tx) {
   image(airballoonImg, this.x, 110, szex2, szey2);
}



function sky(sx) {
    var s = {x: sx, 
        right: skyRight,
        display: skyDisplay};
    return s;
}

function skyRight() {
    return this.x + 500;
}

function skyDisplay(tx) {
   image(skyImg, this.x, 0, 500, 300);
}


function mountain(mx) {
    var  m = {x: mx, 
        right: mountainRight,
        display: mountainDisplay};
    return m;
}

function mountainRight() {
    return this.x + 827 + width * 5;
}

function mountainDisplay(tx) {
   image(mountainsImg, this.x - 20, -85, 827, 500);
}


function tree(tx) {
    var  t = {x: tx, 
        right: treeRight,
        display: treeDisplay};
    return t;
}

function treeRight() {
    return this.x + szex + width * 1.5;
}

function treeDisplay(tx) {
   image(tree1Img, this.x, 20, szex, szey);
}


function treeLine(tx) {
    var  t = {x: tx, 
        right: treeLineRight,
        display: treeLineDisplay};
    return t;
}

function treeLineRight() {
    return this.x + szex + width * 1.7;
}

function treeLineDisplay(tx) {
   image(treeLineImg, thisx, 25, szex, szey); //with mountains or without
}
   

function windmillBottom(wx) {
    var  w = {x: wx, 
        right: windmillBottomRight,
        display: windmillBottomDisplay};
    return w;
}

function windmillBottomRight() {
    return this.x + szex2 + width * 2.2;
}

function windmillBottomDisplay(tx) {
   image(windmillBottomImg, this.x + 150, 87, szex2, szey2);//dont show with mountain
}


function windmill(wx) {
    var  w = {x: wx, 
        right: windmillRight,
        display: windmillDisplay};
    return w;
}

function windmillRight() {
    return this.x + 248 + width * 3.2;
}

function windmillDisplay(tx) {
   image(fullwindmillImg, this.x + 20, 100, 248, 150);
}
 

function electricwindmill(wx) {
    var  w = {x: wx, 
        right: electricwindmillRight,
        display: electricwindmillDisplay};
    return w;
}

function electricwindmillRight() {
    return this.x + szex + width * 10.2;
}

function electricwindmillDisplay(tx) {
   image(electricWindmillImg, this.x , 5, szex, szey); //dont show with other windmills
}
    

function bunny(bx) {
    var  b = {x: bx, 
        right: bunnyRight,
        display: bunnyDisplay};
    return b;
}

function bunnyRight() {
    return this.x + szex2 + width * 7.3;
}

function bunnyDisplay(tx) {
   image(bunnyImg, this.x, 130, szex2, szey2);
}


function cat(cx) {
    var  c = {x: cx, 
        right: catRight,
        display: catDisplay};
    return c;
}

function catRight() {
    return this.x + width * 5.5;
}

function catDisplay(tx) {
   image(catImg, this.x + 200, 160, 206.75, 125);
}





function setup() {
    createCanvas(480, 280);
    var sk = sky(1);
    skys.push(sk);
    var tul = tulips(1);
    tulip.push(tul);
    var ar = airballoon(1);
    airballoons.push(ar);
    var mount = mountain(1);
    mountains.push(mount);
    var bunn = bunny(1);
    bunnys.push(bunn);
    var kitten = cat(1);
    cats.push(kitten);
    var bid = bird(1);
    birds.push(bid);
    var tr = tree(1);
    trees.push(tr);
    var tre = treeLine(1);
    treeLines.push(tre);
    var wmb = windmillBottom(1);
    windmillBottoms.push(wmb);
    var fw = windmill(1);
    fullWind.push(fw);
    var ew = electricwindmill(1);
    electric.push(ew);
}




function draw() {
    noStroke();
    //SKY
    for (var i = 0; i < skys.length; i++) {
        var s = skys[i];
        image(skyImg, s.x - offset, 0, 500, 400);//left
    }
    // clean up statement
    if (skys.length > 0 & skys[0].right() < offset) {
        skys.shift();
    }
    // make a new sky
    var lastSky = skys[skys.length-1];
    if (lastSky.right() - offset < width) {
        var s = sky(lastSky.right()); 
        skys.push(s);
}


//MOUNTAIN
     for (var i = 0; i < mountains.length; i++) {
        var m = mountains[i];
        image(mountainsImg, m.x - offset, -78, 827, 500);
    }
    // make a new mountain
    var lastMountain = mountains[mountains.length-1];
    if (lastMountain.right() - offset < width) {
        var m = mountain(lastMountain.right()); 
        mountains.push(m);
}


//TREE
for (var i = 0; i < trees.length; i++) {
        var tr = trees[i];
        image(tree1Img, tr.x - offset, 23, szex, szey);
    }
    // clean up statement
    if (trees.length > 0 & trees[0].right() < offset) {
        trees.shift();
    }
    // make a new tree 
    var lastTree = trees[trees.length-1];
    if (lastTree.right() - offset < width) {
        var tr = tree(lastTree.right()); 
        trees.push(tr);
}
   
   //TREELINE
for (var i = 0; i < treeLines.length; i++) {
        var tre = treeLines[i];
        image(treeLineImg, tre.x - offset, 25, szex, szey); //with mountains or without
    }
    // clean up statement
    if (treeLines.length > 0 & treeLines[0].right() < offset) {
        treeLines.shift();
    }
    // make a new treeline
    var lastTreeLine = treeLines[treeLines.length-1];
    if (lastTreeLine.right() - offset < width) {
        var tre = treeLine(lastTreeLine.right()); 
        treeLines.push(tre);
} 



//WINDMILLBOTTOM
    for (var i = 0; i < windmillBottoms.length; i++) {
        var wnd = windmillBottoms[i];
        image(windmillBottomImg, wnd.x - offset, 87, szex2, szey2);
    }
    // clean up statement
    if (windmillBottoms.length > 0 & windmillBottoms[0].right() < offset) {
        windmillBottoms.shift();
    }
    // make a new windmill
    var lastwindmillBottom = windmillBottoms[windmillBottoms.length-1];
    if (lastwindmillBottom.right() - offset < width) {
        var wnd = windmillBottom(lastwindmillBottom.right()); 
        windmillBottoms.push(wnd);
}
    


//ELECTRIC WINDMILL
for (var i = 0; i < electric.length; i++) {
        var ew = electric[i];
        image(electricWindmillImg, ew.x - offset, 5, szex, szey); //dont show with other windmills
    }
    // clean up statement
    if (electric.length > 0 & electric[0].right() < offset) {
        electric.shift();
    }
    // make a new windmill
    var lastElectricWindmill = electric[electric.length-1];
    if (lastElectricWindmill.right() - offset < width) {
        var ew = electricwindmill(lastElectricWindmill.right()); 
        electric.push(ew);
}
    

//WINDMILL
for (var i = 0; i < fullWind.length; i++) {
        var full = fullWind[i];
         image(fullWindmillImg, full.x - offset, 100, 248, 150); //can be anytime show up
    }
    // clean up statement
    if (fullWind.length > 0 & fullWind[0].right() < offset) {
        fullWind.shift();
    }
    // make a new windmill
    var lastWindmill = fullWind[fullWind.length-1];
    if (lastWindmill.right() - offset < width) {
        var full = windmill(lastWindmill.right()); 
        fullWind.push(full);
}



//AIRBALLOONS
    for (var i = 0; i < airballoons.length; i++) {
        var air = airballoons[i];
        image(airballoonImg, air.x - offset, 110 - offset/10, szex2, szey2);
    }
    // clean up statement
    if (airballoons.length > 0 & airballoons[0].right() < offset) {
        airballoons.shift();
    }
    // make a new balloom
    var lastAirballoon = airballoons[airballoons.length-1];
    if (lastAirballoon.right() - offset < width) {
        var air = airballoon(lastAirballoon.right()); 
        airballoons.push(air);
}

//background for tulips
for(var i = 0 ; i < width; i ++){
    fill(253, 218 - offset / 75, 42);
    rect(0, 195, 480, 100);
}
//slight change every time offset increases so slight won't notice till big change




//TULIPS
    for (var i = 0; i < tulip.length; i++) {
        var t = tulip[i];
        image(flowerImg, t.x - offset, 190, 900, 105);//left
    }

    // clean up statement
    if (tulip.length > 0 & tulip[0].right() < offset) {
        tulip.shift();
    }

    // make a new tulip
    var lastTulip = tulip[tulip.length-1];
    if (lastTulip.right() - offset < width) {
        var t = tulips(lastTulip.right()); 
        tulip.push(t);
}





//BIRD ??NEEDS FIX
 for (var i = 0; i < birds.length; i++) {
        var bids = birds[i];//need to change spawn pnt
        image(birdImg, bids.x - (offset + offset), 0, 165.4, 100); //move faster across the screen
    }
    // clean up statement
    if (birds.length > 0 & birds[0].right() < offset) {
        birds.shift();
    }
    // make a new bird //make less often
    var lastBird = birds[birds.length-1];
    if (lastBird.right() - (offset + offset) < width) {
        var bids = bird(lastBird.right()); 
        birds.push(bids);
}





    //BUNNY
 for (var i = 0; i < bunnys.length; i++) {
        var buns = bunnys[i];
        image(bunnyImg, buns.x - offset, 130, szex2, szey2);
    }
    // clean up statement
    if (bunnys.length > 0 & bunnys[0].right() < offset) {
        bunnys.shift();
    }
    // make a new rabbit //make less often
    var lastBunny = bunnys[bunnys.length-1];
    if (lastBunny.right() - offset < width) {
        var buns = bunny(lastBunny.right()); 
        bunnys.push(buns);
}




    //CAT
 for (var i = 0; i < cats.length; i++) {
        var kittens = cats[i];
        image(catImg, kittens.x - offset , 160, 206.75, 125);
    }
    // clean up statement
    if (cats.length > 0 & cats[0].right() < offset) {
        cats.shift();
    }
    // make a new cat //make less often
    var lastCat = cats[cats.length-1];
    if (lastCat.right() - offset < width) {
        var kittens = cat(lastCat.right()); 
        cats.push(kittens);
}



    offset ++;
}

Project 11: Landscape

sketch

//Alana Wu
//ID: alanawu
//Project 11

var planets = [];
var stars = [];
var dots = [];

function setup()
{
    createCanvas(400, 400);
    for (var i = 0; i < 2; i++) //creates initial planets
    {
        var pX = random(width);
        var pC = [random(50, 255), random(50, 255), random(50, 255)];
        var pSize = random (20, 120);
        var faceNum = random (1);
        var o = random (0,1);
        planets[i] = makePlanet(pX, pC, pSize, faceNum, o);
    }

    for (var i = 0; i < 5; i++) //creates initial dot clusters
    {
        var aX = random(50, width*2-50);
        var aCol = [random(0, 255), random(0, 255), random(0, 255), 75];
        var aSize = random (10, 150);
        var locationX = [];
        var locationY = [];
        for (var j = 0; j < 200; j++)
        {
            var bX = randomGaussian(0, 30);
            locationX.push(bX);
            var bY = randomGaussian(0, 30);
            locationY.push(bY);
        }
        dots[i] = makeDots (aX, aCol, aSize, locationX, locationY);
    }
    frameRate(10);
}

function draw()
{
    background (0);

    updateAndDisplayDots();
    removeDots();
    addDots();

    updateAndDisplayStars();
    removeStars();
    addStars();

    updateAndDisplayPlanets();
    removePlanets();
    addPlanets();
    astronaut();

    if (keyIsPressed) //massive sun appears when key is pressed
    {
        sun();
    }
}

function updateAndDisplayPlanets () //moves and draws planets
{
    for (var i = 0; i < planets.length; i++)
    {
        planets[i].move();
        planets[i].display();
    }
}

function updateAndDisplayStars () //moves and draws stars
{
    for (var i = 0; i < stars.length; i++)
    {
        stars[i].move();
        stars[i].display();
    }
}

function updateAndDisplayDots () //moves and draws dots
{
    for (var i = 0; i < dots.length; i++)
    {
        dots[i].move();
        dots[i].display();
    }
}

function removePlanets() //removes planets above the canvas from array
{
    var planetsKeep = [];
    for (var i = 0; i < planets.length; i++)
    {
        if (planets[i].y + planets[i].size/2 > 0)
        {
            planetsKeep.push(planets[i]);
        }
    }
    planets = planetsKeep; //remember surviving planets
}

function removeStars() //removes stars above the canvas from array
{
    var starsKeep = [];
    for (var i = 0; i < stars.length; i++)
    {
        starsKeep.push(stars[i]);
    }
    stars = starsKeep;
}

function removeDots() //removes dots above the canvas from array
{
    var dotsKeep = [];
    for (var i = 0; i < dots.length; i++)
    {
        dotsKeep.push(dots[i]);
    }
    dots = dotsKeep;
}

function addPlanets() //add new planets from bottom
{
    var chance = .05;
    if (random(1) < chance)
    {
        planets.push(makePlanet(random(width), [random(50, 255),
            random (50, 255), random (50, 255)], random (20, 120), random (1)));
    }
}

function addStars() //adds new stars from bottom
{
    var chance = .05;
    if (random(1) < chance)
    {
        stars.push(makeStars(random (width)));
    }
}

function addDots() //adds new dots from bottom
{
    var chance = .5;
    if (random(1) < chance)
    {
        var aX = random(0, width*2-50);
        var aCol = [random(0, 255), random(0, 255), random(0, 255), 75];
        var aSize = random (10, 150);
        var locationX = [];
        var locationY = [];
        for (var j = 0; j < 200; j++)
        {
            var bX = randomGaussian(0, 30);
            locationX.push(bX);
            var bY = randomGaussian(0, 30);
            locationY.push(bY);
        }
        var a = makeDots (aX, aCol, aSize, locationX, locationY);
        dots.push(a);
    }
}

function makePlanet (planX, c, size, f, o) //makes planet object
{
    var planet = 
    { x: planX,
    y: height,
    size: size,
    color: c,
    speed: -3,
    faceNum: f,
    move: planetMove,
    display: planetDisplay,
    orbit: o
    }
    return planet;
}

function makeStars(sX) //makes star object
{
    var star = 
    {x: sX,
    y: height,
    speed: -3,
    move: starMove,
    display: starDisplay
    }
    return star;
}

function makeDots (aX, col, size, locationX, locationY) //makes dots object
{
    var dot =
    {x: aX,
    y: height*2,
    locX: locationX,
    locY: locationY,
    size: size,
    color: col,
    speed: -3,
    move: dotMove,
    display: dotDisplay
    }
    return dot;
}

function planetMove () //moves planets upwards
{
    this.y += this.speed;
}

function starMove () //moves stars upwards
{
    this.y += this.speed;
}

function dotMove () //moves dots upwards
{
    this.y += this.speed;
}

function planetDisplay () //draws planet
{
    fill (this.color);
    noStroke();
    circle (this.x, this.y, this.size); //colored circle
    stroke(0);
    strokeWeight(this.size/20);
    if (this.faceNum < .33) //dead face, surprised when mouse is pressed
    {
        line (this.x - this.size/6, this.y - this.size/12, this.x - this.size/6, this.y - this.size/6);
        line (this.x + this.size/6, this.y - this.size/12, this.x + this.size/6, this.y - this.size/6);
        push();
        strokeWeight(this.size/14);
        stroke(200);
        noFill();
        if (this.orbit > .5) //2 possible orbital rings around planet
        {
            arc (this.x, this.y + this.size/10, this.size*1.4, this.size/3, TWO_PI*.973, PI*1.07); //wide orbital ring
        }
        else
        {
            arc (this.x, this.y + this.size/10, this.size*1.1, this.size/6, TWO_PI*.995, PI*1.01); //narrow orbital ring
        }

        pop();
        if (mouseIsPressed) //surprised mouth when mouse is pressed
        {
            noFill();
            ellipse(this.x, this.y, this.size/8, this.size/10);
        }
        else
        {
            line (this.x - this.size/12, this.y, this.x + this.size/12, this.y);
        }
    }
    else if (this.faceNum >= .33 & this.faceNum < .66) //eyes on left, smile, frown if mouse is pressed
    {
        fill (0);
        circle (this.x - this.size/3, this.y - this.size/12, this.size/8);
        circle (this.x - this.size/6, this.y - this.size/12, this.size/8);
        strokeWeight (this.size/20);
        noFill();
        if (mouseIsPressed) //frowns when mouse is pressed
        {
            arc (this.x - this.size/4, this.y + this.size/12, this.size/20, this.size/30, PI, 0 , OPEN);
        }
        else
        {
            arc (this.x - this.size/4, this.y + this.size/12, this.size/20, this.size/30, 0, PI, OPEN);
        
        }
        fill (255);
        noStroke();
        circle (this.x - this.size/3 - this.size/20, this.y - this.size/12, this.size/18);
        circle (this.x - this.size/6 - this.size/20, this.y - this.size/12, this.size/18);
    }
    else //eyes on right, smile, frowns if mouse is pressed
    {
        fill (0);
        circle (this.x + this.size/3, this.y - this.size/12, this.size/8);
        circle (this.x + this.size/6, this.y - this.size/12, this.size/8);
        noFill();
        if (mouseIsPressed) //frowns when mouse is pressed
        {
            arc (this.x + this.size/4, this.y + this.size/12, this.size/20, this.size/30, PI, 0, OPEN);
        }
        else
        {
            arc (this.x + this.size/4, this.y + this.size/12, this.size/20, this.size/30, 0, PI, OPEN);
        }
        fill (255);
        noStroke();
        circle (this.x + this.size/3 - this.size/20, this.y - this.size/12, this.size/18);
        circle (this.x + this.size/6 - this.size/20, this.y - this.size/12, this.size/18);
    }
}

function starDisplay() //draws stars
{
    fill (255, 255, 200);
    noStroke();
    beginShape();
    vertex (this.x + 10, this.y);
    vertex (this.x + 3, this.y - 1);
    vertex (this.x, this.y - 8);
    vertex (this.x - 3, this.y - 1);
    vertex (this.x - 10, this.y);
    vertex (this.x - 4, this.y + 3);
    vertex (this.x - 7, this.y + 10); //bottom left triangle
    vertex (this.x, this.y + 5); //middle inner vertex
    vertex (this.x + 7, this.y + 10);//bottom right triangle
    vertex (this.x + 4, this.y + 3);
    vertex (this.x + 10, this.y);
    endShape();
}

function dotDisplay() //draws colored dots
//dotDisplay is called EVERY frame, so the randomGaussians change every frame
//get program to push of randomGaussian locations into an array of locaitons when a set of dots is created
//then call those same locations for every frame for that set of dots
{
    push();
    scale(.5);
    stroke(this.color); 
    for (var i = 0; i < this.locX.length; i++)
    {
        push();
        translate (this.x, this.y);
        point(this.locX[i], this.locY[i]);
        pop();
    }
    pop();
}




function astronaut () //draws astronaut hanging from moon balloon
{  
    //moon balloon
    push();
    translate (0, -30);
    fill (255, 200, 50);
    noStroke();
    circle (width/2, height/2, 100);
    triangle (width/2, height/2 + 30, width/2 - width/43, height/2 + 58, width/2 + width/43, height/2 + 58);
    fill (150, 75, 0, 100);
    stroke(0);
    strokeWeight(3);
    arc (width/2 - width/14, height/2 + height/20, 10, 10, PI/6, PI*1.8, OPEN);
    arc (width/2, height/2, 20, 20, 0, PI*1.5, OPEN);
    arc (width/2 + width/20, height/2 - height/17, 25, 25, PI/2, TWO_PI, OPEN);
    arc (width/2 - width/15, height/2 - height/18, 15, 15, PI*2.7, PI*1.7, OPEN);
    arc (width/2 - width/30, height/2 + height/12, 12, 12, TWO_PI, PI*7/8, OPEN);
    arc (width/2 + width/16, height/2 + height/18, 22, 22, PI*1.7, PI, OPEN);
    stroke(255);
    line (width/2, height/2 + 58, width/2, height/2 + 82);

    push();
    translate (width*.59, height*.68);
    fill(255);
            push(); //balloon arm
            rotate (radians(-40));
            ellipse (-30, 5, 15, 50);
            rotate(radians(48));
            ellipse (24, 30, 15, 25); //non balloon arm
            pop();
    ellipse(-5, 35, 45, 55); //body
    ellipse (-14, 60, 15, 35); //left leg
    ellipse (6, 60, 15, 35); //right leg
        push(); //helmet
        rotate (radians(25));
        fill (255);
        ellipse (-25, 0, 10, 20);
        ellipse (25, 0, 10, 20);
        ellipse (0, 0, 50, 45);
        fill (0, 0, 100); //navy part
        ellipse (0, 0, 50, 35);
        noStroke();
        fill (255, 255, 255);
        ellipse (14, -2, 8, 12); //large white bubble
        rotate (radians(-10));
        ellipse (-17, 3, 3, 5); //smaller white bubble
        strokeWeight(8); //belt
        stroke(220);
        line (-13, 45, 24, 39);
        strokeWeight(2);
        stroke(0);
        fill(220);
        rotate(radians(-10));
        rect (-11, 37, 20, 10);
        pop();
    pop();
    pop();
}   

function sun () //massive sun appears when key is pressed
{
    noStroke();
    fill (255, 255, 0);
    circle (width/2, height/2, 300);
    strokeWeight(10);
    stroke(255, 255, 0);
    push();
    translate (width/2, height/2);
    for (var i = 0; i < 36; i ++)
    {
        line (0, -170, 0, -230);
        rotate (radians (30));
    }
    pop();
}








For this project, I decided to depict an astronaut floating through space. The elements I have passing by are various types of planets, individual stars, and faraway colorful clusters of stars. This project prompt let me play around with lots of fun colors and shapes, while also helping me learn how objects work. I started with the planets object, and ended with the colorful clusters of dots. I also added features where the facial expressions of the planets change when you press the mouse and a sun appears if you press a key.