Project-11

sketch
//Diana McLaughlin, dmclaugh@andrew.cmu.edu, Section A
//A generative landscape that shows trees, clouds, and mountains on a fall day

var trees = [];
var clouds = [];
var mountain = [];
var noiseParam = 0;
var noiseStep = 0.04;

function setup() {
    createCanvas(480, 380);
    
    //set up mountains
    for (var i = 0; i <= 96; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height);
        mountain.push(value);
        noiseParam += noiseStep;
    }  
    
    //draw initial trees
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trees[i] = makeTree(rx);
    }
    
    //draw initial clouds
    for (var i = 0; i < 10; i++){
        var cx = random(width);
        clouds[i] = makeCloud(cx);
    }
    frameRate(10);
}


function draw() {
    background(0, 200, 255); //sky blue

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

    mountains();
    fill(0, 120, 0);
    rect(0, 335, width, 65);

    updateAndDisplayTrees();
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability();   
}


function updateAndDisplayTrees(){
    // Update the trees' positions
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}


function removeTreesThatHaveSlippedOutOfView(){
    //remove these trees from the array
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}


function addNewTreesWithSomeRandomProbability() {
    // Add a new tree to the end of the array
    var newTreeLikelihood = 0.05; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

function treeMove() {
    this.x += this.speed;
}
    
function treeDisplay() {
    //draw the tree
    var tHeight = 70; 
    fill(this.clr); 
    stroke(0); 
    push();
    translate(this.x, height - 40);
    triangle(0, -tHeight, -this.breadth/2, tHeight-90, this.breadth/2, tHeight-90);
    fill(255, 255, 150);
    rect(-5, tHeight-90, 10, 20);
    stroke(200); 
    pop();
}


function makeTree(birthLocationX) {
    var tr = {x: birthLocationX,
                clr: color(random(0, 255), random(0, 255), 0),
                breadth: 50,
                speed: -6.0,
                move: treeMove,
                display: treeDisplay}
    return tr;
}

//Clouds

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


function removeCloudsThatHaveSlippedOutOfView(){
    // remove clouds that are no longer visible
    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i++){
        if (clouds[i].x + clouds[i].breadth > 0) {
            cloudsToKeep.push(clouds[i]);
        }
    }
    clouds = cloudsToKeep;
}


function addNewCloudsWithSomeRandomProbability() {
    // Add clouds to the end of the arrayS
    var newCloudLikelihood = 0.02; 
    if (random(0,1) < newCloudLikelihood) {
        clouds.push(makeCloud(width));
    }
}

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

// draw the clouds
function cloudDisplay() {
    var cHeight = 250; 
    fill(255); 
    noStroke(); 
    push();
    translate(this.x, height - 40);
    ellipse(0, -cHeight, 30, 30);
    ellipse(15, -cHeight, 15, 15);
    ellipse(5, -cHeight+10, 50, 20);
    pop();
}


function makeCloud(birthLocationX) {
    var cld = {x: birthLocationX,
                breadth: 50,
                speed: -2.5,
                move: cloudMove,
                display: cloudDisplay}
    return cld;
}


function mountains() {
    //use random noise to draw mountains
    mountain.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    mountain.push(value);
    noiseParam += noiseStep;
    
    
    fill(0, 150, 0); //land green
    beginShape(); //shape the terrain
    vertex(0, height);
    for (var i = 0; i <= 96; i++) {
        vertex(i*5, mountain[i]);
    }
    vertex(width, height);
    endShape(); 
}

This shows a landscape of a fall day. The trees have random colors as they pass like colorful leaves. I also set the speeds so that the foreground (trees) moves the fastest, the mountains move less than the trees, and the clouds move more slowly than the mountains.

Project 11

To start with this project I wanted to make my landscape the outside of a plane window. I wanted to make it seem like someone was sitting in an airplane looking at mountain tops and a sunset as clouds and birds go by.

sketchDownload
var grass=[];
var noiseParam=0;
var noiseStep=0.04;
var x=[];
var cloud={x:200,xx:200,y:0,yy:0,r:50,v:-2,
  v2:-2.75};
var robin={x:100,y:25,dx:-2,dy:28,c:255,z:0,r:212,g:124,b:47,
  rr:48,gg:46,bb:59,r3:105,g3:107,b3:102};


function setup() {
    createCanvas(400, 400);    //setting up the grass
    for(var i=0; i<width/5+1; i++){
      var n=noise(noiseParam);
      var value=map(n,0,1,0,height-100);
      grass.push(value);
      noiseParam+=noiseStep;
    }
    frameRate(40);
}

function draw() {
  var c2=color(253,94,83);
  var c1=color(83,242,253);
  sunset(0,0,width,height,c1,c2,"C");   //background
  mountains();    //call mountains
  noFill();
  stroke(0);
  bird();   //call bird
  clouds();   //call clouds
  push();
  strokeWeight(0);
  rect(100,100,200,200);    //draw inside of plane
  fill(64,64,64);
  rect(0,0,width,75);
  rect(0,325,width,75);
  rect(0,75,100,250);
  rect(300,75,100,250);
  pop();
  wing();   //draw wings
  push();
  noStroke();   //draw window gray lining
  fill(186,194,202);
  rect(75,50,25,300);
  rect(100,50,200,25);
  rect(100,325,200,25);
  rect(300,50,25,300);
  pop();
  line(110,65,290,65);    //window shade pull down
}

function sunset(x,y,w,h,c1,c2,a) {
  noFill();
  if (a=="C") {   //color gradient of background
    for(var i=y;i<=y+h;i++){
      var cl=map(i,y,y+h,0,1);
      var color=lerpColor(c1,c2,cl);
      stroke(color);
      line(x,i,x+w,i);
    }
  }
  fill(253,94,83);
  circle(200,325,150);    //draw the sun
}

function wing(){    //drawing the planes wing
  push();
  fill(34,33,54);
  beginShape();
  vertex(300,250);
  vertex(201,225);
  vertex(191,225);
  vertex(300,300);
  vertex(300,250);
  endShape(CLOSE);
  fill(83,60,61);
  beginShape();
  vertex(198,225);
  vertex(185,215);
  vertex(180,215);
  vertex(191,225)
  endShape();
  fill(52,34,32);
  beginShape();
  vertex(191,225);
  vertex(189,235);
  vertex(192,235);
  vertex(201,225);
  endShape(CLOSE);
  pop();
}

function clouds(){
  push();
  fill(255);    //cloud white
  noStroke();
  translate(width/2,height/2);
  cloud.xx+=cloud.v2;
  cloud.x+=cloud.v;
  circle(cloud.x,cloud.y,cloud.r);    //top cloud
  circle(cloud.x+25,cloud.y,cloud.r);
  circle(cloud.x+12.5,cloud.y-25,cloud.r);
  circle(cloud.xx-100, cloud.yy+150,cloud.r);    //bottom cloud
  circle(cloud.xx-75,cloud.yy+150,cloud.r);
  circle(cloud.xx-87.5,cloud.yy+125,cloud.r);
  cloud.xx+=cloud.v2;
  cloud.x+=cloud.v;
  if(cloud.xx<-200){    //makes clouds reappear on left side of screen
    cloud.xx=400;
    cloud.yy=random(-100,100);
  };
  if(cloud.x<-200){
    cloud.x=400;
    cloud.y=random(-100,100);
  }
  pop();
}

 function bird(){  //bird helper function
   push();
   fill(robin.r,robin.g,robin.b);
   circle(robin.x,robin.y,50);
   fill(robin.rr,robin.gg,robin.bb);
   circle(robin.x-25,robin.y-13,25);
   fill(robin.r3,robin.g3,robin.b3);
   triangle(robin.x+35,robin.y+5,robin.x-5,
   robin.y+5,robin.x+25,robin.y-25);
   fill(robin.c,robin.c,robin.z);
   triangle(robin.x-38,robin.y-8,robin.x-43,
   robin.y-8,robin.x-38,robin.y-13);
   robin.x+=robin.dx;
   if(robin.x<-200){    //makes clouds reappear on right side of screen
     robin.x=400;
     robin.y=random(100,300);
   };
   pop();
 }
function mountains(){
  if(grass.length>80){    //allow the mountains to move
    grass.shift();
    for(var i=0;i<width/5+1;i++){
      var n=noise(noiseParam);
      var value=map(n,0,1,0,1.25*height);
      grass.push(value);
      noiseParam+=noiseStep;
      push();
      strokeWeight(3);
      x[i]=5*i;
      pop();
    }
  }
  fill(178, 168, 255);
  beginShape();    //set up the shape of the mountains
  for(var i=0; i<width; i++){
    vertex(i*5,grass[i]);
  }
  vertex(width,height);
  vertex(0,height);
  endShape(CLOSE);
}

Project 11- Landscape

sketch
var peakvalue = [];
var noiseParam = 0;
var noiseStep = 0.005;
var x = [];
var y = [];
var dx = [];
var dx1 = 0;
var c = [];
var seacoralshape = 0.002;
var seacoralspeed = 0.005


function preload(){
  cloud = loadImage("https://i.imgur.com/ZtLcxL9.png");
}



function setup() {
  createCanvas(400, 400);
  for (var i = 0; i <=width/5; i++) {
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 300, height);
    peakvalue.push(value);
    noiseParam += noiseStep;
  }

   for (var i=0; i<50; i++){
      x[i]= random(10, width-10);
      y[i] = random(250, 400);
      dx[i] = random(-5,-1);
      c[i] = color(random(255),255,240);
    }
}

function draw() {

  background(251, 164, 153);
  fill(246, 189, 192);
  ellipse(200,200,320,320);
  fill(241, 149, 155);
  ellipse(200,200,290,290);
  fill(240, 116, 112);
  ellipse(200,200, 260);
  fill(234, 76, 70);
  ellipse(200,200,230,230);
  fill(220, 28, 19);
  ellipse(200,200, 200,200);
  seacoral();
  cloud.resize(70,0);
  tint(255,127);
  image(cloud, -250 + dx1, 40);
  image(cloud, -100 +dx1, 100);
  image(cloud, 180 + dx1, 40);
  image(cloud, 20 + dx1, 30);
  image(cloud, 100 + dx1, 100);
  image(cloud, 300 + dx1, 100);
  dx1 += 0.5;
  peakvalue.shift();
  var n2 = noise(noiseParam);
    var value = map(n2, 0, 1, 0, height*1.5);
    peakvalue.push(value);
    noiseParam += noiseStep;

  beginShape();
  vertex(0, height);
  for (var i = 0; i <= width/5; i++) {
    fill(102, 179, 255);
  noStroke();
    vertex(i*5, peakvalue[i]);
    
  }
  vertex(width, height);
   endShape(); 

    for (i = 0; i<50; i++){
      if(x[i] < -30){
        x[i] = 450
      }
      fish(x[i], y[i], dx[i],c[i]);
      x[i] += dx[i]
  }
  frameRate(10);

}


function fish(x,y, dx,c){
  fill(c);
  ellipse(x,y,20,10);
  if(dx >= 0){
    triangle(x - 10, y, x -15, y - 5, x - 15, y + 5);
  }else if(dx < 0){
    triangle(x+10,y, x + 15, y - 5, x + 15, y + 5);
  }
}

function seacoral(){
  noStroke();
  fill(119, 158, 203);
  beginShape();

  for(var i = 0; i < width; i ++){
    var x = (i * seacoralshape) + (millis() * seacoralspeed);
    var y = map(noise(x), 0, 1.2, 200, 250);
    vertex(i, y);
  }

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


For this week’s project, I wanted to create a landscape that shows the ocean drifting and many fish swimming.

Project 11: Landscape

sketch
 /*
 Bon Bhakdibhumi
 bbhakdib
 Section D
 */
var backgroundX = 355;
var foregroundX = 250;
function preload() {
    train = loadImage("https://i.imgur.com/cMqi4AV.png");
    house = loadImage("https://i.imgur.com/KrNQaN2.png");
    tower = loadImage("https://i.imgur.com/P6WEAeL.png");
    montain = loadImage("https://i.imgur.com/04duSGs.png");
    backgroundHouse = loadImage("https://i.imgur.com/DgMNstF.png");
    backgroundTower = loadImage("https://i.imgur.com/AuMqECF.png");
}

 function setup() {
    createCanvas(480, 240);
 }

 function draw() {
// backdrop
    noStroke();
    fill(147, 129, 101);
    rect(0, 175, 480, 65);
    fill(164, 233, 244);
    rect(0, 0, 480, 174);
    imageMode(CENTER);
// background elements
    for (var i = 0; i < 3; i ++) {
        image(backgroundTower, backgroundX - (i * 200), 117, 200, 200);
        image(backgroundHouse, (backgroundX + 80) - (i * 200), 147, 200, 200);
    }
// foreground elements
    image(montain, foregroundX, 105, 250, 250);
    image(house, foregroundX - 140, 137, 210, 210);
    image(tower, foregroundX + 130, 105.5, 210, 210);
    image(train, 240, 120, 480, 240);
    backgroundX -= 2; 
    foregroundX -= 2;
// resetting foreground and background elements
    if (backgroundX <= -125) {
        backgroundX = 900;
    }

    if (foregroundX <= -150) {
        foregroundX = 825
    }
}

For this project, I chose to make a landscape of a town I visited by train for the first time.

Project-11-Landscape

For this project, I wanted to create a desert landscape with some cactus here and there.

sketch
//jiaqiwa2; Jiaqi Wang; Section C
var marketValue=[];
var noiseParam=0;

var noiseStep=0.03;
var cactus = [];

function setup() {
    frameRate(30);
    createCanvas(600, 240);
    stroke(89,158,90);
    noStroke();
    fill(89,158,90);
    //strokeWeight(5);
    //set up the y value for every 5 pixels across the canvas horizontally
    for(var i=0;i<=120;i++){
        var n=noise(noiseParam);
        var value=map(n,0,1,height/3,height);
    	marketValue.push(value);
    	noiseParam+=noiseStep;
    }
    frameRate(20);

    for (var i = 0; i < 10; i++){
        var rx = random(width);
        cactus[i] = makeCactus(rx);
    }

}

function draw() {
	background(234,197,119);
  fill(249,242,215);
  noStroke();
  ellipse(width/2,height/2,100,100);
  //remove the first point
    marketValue.shift();
    var n=noise(noiseParam);
    var value=map(n,0,1,height/3,height);
    //and add it to the last point
    marketValue.push(value);
    noiseParam+=noiseStep;
    //start shape from (0,height)
    noStroke();
    fill(186,109,78);

  beginShape();
  curveVertex(0,height);
  curveVertex(0,height);
	for(var i=0;i<width/10;i++){
       
       vertex(i*10, marketValue[i]);
       //check if the hill is close to the right end
        if(i==59){
         i+=1;
         vertex(i*10, marketValue[i]);
         vertex(width, height);
         vertex(0,height);
         vertex(0,height);
         endShape();
       }
  }

  beginShape();
  curveVertex(0,height);
  curveVertex(0,height);



  

 

  updateAndDisplayCactus();
  removeCactusThatHaveSlippedOutOfView();
  addNewCactusWithSomeRandomProbability(); 
     
	   
	//noLoop();
}



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


function removeCactusThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge,
    // remove it from the array.  This is quite tricky, but
    // we've seen something like this before with particles.
    // The easy part is scanning the array to find buildings
    // to remove. The tricky part is if we remove them
    // immediately, we'll alter the array, and our plan to
    // step through each item in the array might not work.
    //     Our solution is to just copy all the buildings
    // we want to keep into a new array.
    var cactusToKeep = [];
    for (var i = 0; i < cactus.length; i++){
        if (cactus[i].x + cactus[i].breadth > 0) {
            cactusToKeep.push(cactus[i]);
        }
    }
    cactus = cactusToKeep; // remember the surviving buildings
}


function addNewCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newCactusLikelihood = 0.007; 
    if (random(0,1) < newCactusLikelihood) {
         cactus.push(makeCactus(width));
    }
}


// method to update position of building every frame
function  cactusMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function  cactusDisplay() {
  
    push();
    fill(55,104,50);
    stroke(16,66,7);
    strokeWeight(5);
    translate(this.x, height+90);
    ellipse(0,-100,this.breadth,this.Tall);
    
    push();
    
    translate(this.breadth/2,-this.Tall/2);
    rotate(radians(-20));
    ellipse(0,-100,this.breadth/3*2,this.Tall/3*2);
    pop();

    translate(this.breadth/2,-this.Tall/2);

    push();
    rotate(radians(20));
    translate(-this.branch,0);
    ellipse(0,-100,this.breadth/3*2,this.Tall/3*2);
    pop();


   
    translate(-this.branch/5,-this.Tall/3);
    ellipse(0,-100,this.breadth/6*2,this.Tall/6*2);
    pop();

}


function makeCactus(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: round(random(20,40)),
                speed: -2,
                Tall:random(40,120),
                branch:random(30,40),
                theta: round(random(10,40)),
                move:  cactusMove,
                display:  cactusDisplay}
    return bldg;
}


function displayHorizon(){
    stroke(0);
    line (0,height-50, width, height-50); 
}





Project 11: Landscape

sketchDownload
var waveDetail = 0.003; // detail in shallow wave
var waveSpeed = 0.0002; // speed of waves
var waveDetail2 = 0.002; //detail of mid wave
var waveDetail3 = 0.001; //detail of deep wave
var seaGround = []
var sunset;

function preload() {
    sunset = loadImage("https://i.imgur.com/14AlgbU.png");
    seaweed = loadImage("https://i.imgur.com/JHftB8t.png");
    fish = loadImage("https://i.imgur.com/BFimCOm.png")
}
function setup() {
    createCanvas(600, 400);
    for (var i = 0; i < 5; i ++){
        var rx = random(width);
        var ry = random(10, 50)
        seaGround[i] = makeSeaweed(rx, ry);
    }
    frameRate(15);
}

function draw() {
    background(153, 153, 204);

    image(sunset, 0, 0, 600, 400);
    makeWaves();
    updateSeaweed();
    removeSeaweed();
    image(fish, 300, 200, 300, 200);  
    addSeaweed();

}

function makeWaves() {
    fill(95, 191, 254);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * waveDetail) + (millis() * waveSpeed);
        var y = map(noise(t), 0, 1, height / 8 * 2, height / 8 * 4);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();

    //second wave
    beginShape();
    fill(41, 160, 255);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t2 = (x * waveDetail2) + (millis() * waveSpeed);
        var y = map(noise(t2), 0, 1, 100, 300);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();

    //third wave
    beginShape();
    fill(19, 138, 233);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t3 = (x * waveDetail3) + (millis() * waveSpeed);
        var y = map(noise(t3), 0, 1, 300, height);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

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

function removeSeaweed(){
    var keepSeaweed=[];
    for (var i = 0; i < seaGround.length; i++) {
        if (seaGround[i].x < 600) {
            keepSeaweed.push(seaGround[i]);
        }
    }
}

function addSeaweed(){
    //little probability
    var newSeaweedLikelihood = 0.02; 
    if (random(0,1) < newSeaweedLikelihood) {
        seaGround.push(makeSeaweed(15, 15));
    }
}

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

function displaySeaweed(){
    fill(0);
    stroke(0);
    push();
    translate(this.x, height-300);
    image(seaweed, 0, 0, 400, 320);
    pop();

}

function makeSeaweed(birthLocationX, birthLocationY){
    var seaweeds = {x: birthLocationX,
                y:birthLocationY,
                speed:random(3, 7),
                move: moveSeaweed,
                display: displaySeaweed};
    return seaweeds;
}

I wanted to illustrate a fish swimming in the ocean, as the ocean waves and seaweed passed by. I was inspired by the sunset, and I started to think about how i can make the sunset a moving landscape. I drew the sunset, seaweed, and fish objects on Procreate.

No description available.
sunset that i drew that was the source of inspiration
No description available.
rough sketch
No description available.
final sketch

Project 11: Generative Landscape

For my project, I decided to create a relaxing underwater scene. Although it was a bit challenging to figure out how to execute my ideas, I had fun making my landscape and adjusting properties to make it more interesting. To create my landscape, I combined concepts that we learned in the past, such as arrays, objects, loops, noise, images, and functions. I randomized properties such as the x/y positions, sizes, colors, and speeds of my objects.

landscape-cb
var terrain = [];
var coral;
var bubbles = [];
var fish = [];

var noiseParam = 0;
var noiseStep = 0.05;

function preload() {
    coral = loadImage("https://i.imgur.com/S5HGpZa.png");
}

function setup() {
    createCanvas(480, 300);
    //setup noise for terrain
    for(var i=0; i<=width/5; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height);
        terrain.push(value);
        noiseParam += noiseStep;
    }
    //setup for fish
    for (var i = 0; i < 15; i++) {
        fishx = random(width);
        fish[i] = makeFish(fishx);
    }
    //setup for bubbles
    for (var i = 0; i < 10; i++) {
        bubblex = random(width);
        bubbley = random(height);
        bubbles[i] = makeBubble(bubblex, bubbley);
    }
    frameRate(10);
}

function draw() {
    background(0, 180, 200);

    noStroke();
    fill(0, 230, 255, 90);
    ellipse(240, 0, 600, 200);

    blueTerrain();
    
    updateAndDisplayFish();
    removeFish();
    addNewFish();
    
    displayBubbles();
}

//background terrain
function blueTerrain() {
    terrain.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    terrain.push(value);
    noiseParam += noiseStep;
    
    //blue terrain
    noStroke();
    fill(0, 66, 115);
    beginShape();
    vertex(0, height);
    for(var i=0; i<width/4; i++) {
        vertex(i*5, terrain[i]);
        //placement of coral on terrain
        if(terrain[i] < terrain[i-1] & terrain[i] < terrain[i+1]) {
            drawCoral(i*5, terrain[i]);
        }
    }
    vertex(width, height);
    endShape(CLOSE);
}

//draws coral on terrain
function drawCoral(x, y) {
    imageMode(CENTER);
    image(coral, x, y-10, 65, 80);
}

//update the fish positions and display them
function updateAndDisplayFish() {
    for (var i = 0; i < fish.length; i++) {
        fish[i].move();
        fish[i].draw();
    }
}

//remove fish that are off the canvas from the array
function removeFish() {
    var fishToKeep = [];
    for (var i = 0; i < fish.length; i++) {
        if (fish[i].x + fish[i].w > 0) {
            fishToKeep.push(fish[i]);
        }
    }
    fish = fishToKeep;
}

//with a small probability, add a new fish to end of the array
function addNewFish() {
    var newFishLikelihood = 0.3;
    if (random(0,1) < newFishLikelihood) {
        fish.push(makeFish(width+20));
    }
}

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

function drawFish() {
    push();
    translate(this.x, this.y);
    fill(this.color);
    ellipse(0, 0, this.w, this.h);
    strokeWeight(1.5);
    stroke(240);
    fill(50);
    ellipse(-15, -4, 8, 8);
    noStroke();
    fill(this.fincolor);
    triangle(0, -4, 0, 4, 15, 0);
    noFill();
    push();
    fill(this.color);
    triangle(this.w/2+20, -8, this.w/2+20, 8, (this.w/2)-2, 0);
    pop();
    pop();
}

//fish constructor
function makeFish(fishx) {
    var f = {x: fishx, y: random(height),
            w: random(40, 80), h: random(10, 45),
            color: color(random(100, 255), random(100, 255), random(100, 255)),
            fincolor: color(random(50, 200), random(50, 200), random(50, 200)),
            speed: random(-10, -20),
            move: moveFish,
            draw: drawFish
    }
    return f;
}

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

//bubbles float upwards
function moveBubbles() {
    this.x += this.speed;
    this.y += this.speed;
    if (this.x <= 0) {
        this.x = width;
    }
    if (this.y <= 0) {
        this.y = height;
    }
}

function drawBubbles() {
    push();
    strokeWeight(1);
    stroke(255, 255, 255, 80);
    fill(100, 255, 255, 60);
    ellipse(this.x, this.y, this.size, this.size);
    noFill();
    strokeWeight(2);
    arc(this.x - this.size/12, this.y - this.size/12, 15, 15, PI, PI + HALF_PI);
    pop();
}

//bubbles constructor
function makeBubble(bubblex, bubbley) {
    var b = {x: bubblex, y: bubbley,
            size: random(20, 40),
            speed: random(-1, -6),
            move: moveBubbles,
            draw: drawBubbles
    }
    return b;
}

Project 11: Generative Landscape

For this week’s project, I decided to visualize an NYC subway line I used often (pre-pandemic) and the views of the skyline you can see passing by when the subway tracks are outdoors. I first roughly sketched out the scene on paper and then used Professor Cortina’s sample code as a baseline and customized it further to meet my vision. I displayed the scene to be at night since that’s the time of day I liked most when watching the skyline. Also, although nighttime, the lights would always be on in the buildings, so I decided to have lit up windows on all the buildings as well as the light reflections.

sketch
var frontBuildings = [];
var backBuildings = [];
var moonAndStars;

function preload(){
  moonAndStars = loadImage("https://i.imgur.com/0JJlsGR.png");
}

function setup() {
  createCanvas(480, 270);
  // make initial array of buildings
  for(var i = 0; i < 20; i++) {
    var x = random(width);
    backBuildings[i] = makeBackBuilding(x);
  }
  for(var i = 0; i < 10; i++) {
    var x = random(width);
    frontBuildings[i] = makeFrontBuilding(x);
  }
  frameRate(50);
}

function draw() {
  // gradient night background
  setGradient(color("#655BCE"), color("#1A1449"));
  // moon
  image(moonAndStars, 0, 0, 480, 350);

  updateAndDisplayBuildings();
  removeBuildingsThatHaveSlippedOutOfView();
  addNewBuildingsWithSomeRandomProbability(); 
  // tracks
  drawTrack();
  // train
  drawTrain();

}

function drawTrain() {
  strokeWeight(1);
  stroke("#4A4954");
  // train body
  fill("#65656D");
  rect(0, 180, 220, 80);
  strokeWeight(5);
  line(0, 240, 218, 240);
  strokeWeight(2);
  line(0, 245, 218, 245);
  strokeWeight(5);
  line(0, 190, 218, 190);
  strokeWeight(2);
  line(0, 196, 218, 195);
  noStroke();
  // doors
  fill("#5D5C66");
  rect(10, 200, 36, 60);
  rect(130, 200, 36, 60);
  // windows
  fill("#383664");
  rect(12, 202, 32, 30);
  rect(132, 202, 32, 30);
  rect(58, 200, 60, 30);
  rect(200, 200, 20, 40);
  // train number
  fill("purple");
  circle(182, 220, 25);
  fill(255);
  textSize(20);
  text("7", 177, 227);
}

function drawTrack() {
  fill(20);
  rect(0, 220, width, 100);
  fill("#8F8F91");
  rect(0, 220, width, 30);
  fill("#F0D933");
  rect(0, 240, width, 5);
}

function removeBuildingsThatHaveSlippedOutOfView(){
  // If a building has dropped off the left edge,
  // remove it from the array.  This is quite tricky, but
  // we've seen something like this before with particles.
  // The easy part is scanning the array to find buildings
  // to remove. The tricky part is if we remove them
  // immediately, we'll alter the array, and our plan to
  // step through each item in the array might not work.
  //     Our solution is to just copy all the buildings
  // we want to keep into a new array.
  var frontBuildingsToKeep = [];
  var backBuildingsToKeep = [];
  for (var i = 0; i < frontBuildings.length; i++){
      if (frontBuildings[i].x + frontBuildings[i].width > 0) {
          frontBuildingsToKeep.push(frontBuildings[i]);
      }
  }
  for (var i = 0; i < backBuildings.length; i++){
      if (backBuildings[i].x + backBuildings[i].width > 0) {
          backBuildingsToKeep.push(backBuildings[i]);
      }
  }
  frontBuildings = frontBuildingsToKeep; // remember the surviving buildings
  backBuildings = backBuildingsToKeep;
}


function addNewBuildingsWithSomeRandomProbability() {
  // With a very tiny probability, add a new building to the end.
  var newBuildingLikelihood = 0.08; 
  if (random(0,1) < newBuildingLikelihood) {
      backBuildings.push(makeBackBuilding(width));
      frontBuildings.push(makeFrontBuilding(width));
  }
}

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

// method to update position of building every frame
function frontBuildingMove() {
    this.x += this.speed;
}
    
// draw the building and some windows
function frontBuildingDisplay() {
  noStroke();
  // building
  fill(this.color);
  var y = 220 - this.height;
  rect(this.x, y, this.width, this.height);
  // windows
  fill("#FFE9AD");
  for(var i = 0; i < 5; i ++) {
    rect(this.x + 5, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 20, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 35, y + 10 + 15*i, this.width/6, 8);
  }
}

function makeFrontBuilding(xlocation) {
  var building = {x: xlocation, 
                  width: random(40, 50), 
                  height: random(80, 120),
                  color: color(random(20, 70), random(20, 70), 130),
                  speed: -3,
                  move: frontBuildingMove, 
                  display: frontBuildingDisplay}
  return building;
}


// method to update position of building every frame
function backBuildingMove() {
  this.x += this.speed;
}
    
// draw the back building and some windows
function backBuildingDisplay() {
  noStroke();
  var y = 220 - this.height;
  // light reflections
  fill(255, 243, 180, 20);
  ellipse(this.x + this.width/2, y + 20, this.width*2);
  // building
  fill(this.color);
  rect(this.x, y, this.width, this.height);
  // windows
  fill("#FFE9AD");
  for(var i = 0; i < 8; i ++) {
    rect(this.x + 5, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 20, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 35, y + 10 + 15*i, this.width/6, 8);
  }
}

function makeBackBuilding(xlocation) {
  var building = {x: xlocation, 
                  width: random(40, 50), 
                  height: random(130, 160),
                  color: color(random(60, 80), random(60, 80), 180),
                  speed: -3,
                  move: backBuildingMove, 
                  display: backBuildingDisplay}
  return building;
}

// code from https://editor.p5js.org/REAS/sketches/S1TNUPzim
function setGradient(c1, c2) {
  noFill();
  for (var y = 0; y < height; y++) {
    var inter = map(y, 0, height, 0, 1);
    var c = lerpColor(c1, c2, inter);
    stroke(c);
    line(0, y, width, y);
  }
}



PROJECT-10 (generative landscape)

sketch
// 15-104
// SEAN CHEN

var bgbuildings = [];
var forebuildings = [];
var sidewalk = [];
var dash = [];
var light, bgCloud, foreCloud;
var frames = [];
var run = [];

function preload() {
    light = loadImage('https://i.imgur.com/147kNrs.png');
    bgCloud = loadImage('https://i.imgur.com/Fn6e7H6.png');
    foreCloud = loadImage('https://i.imgur.com/PNyKohG.png');
    frames[0] = loadImage('https://i.imgur.com/xxj2N5D.png');
    frames[1] = loadImage('https://i.imgur.com/ju233XV.png');
    frames[2] = loadImage('https://i.imgur.com/En4Sjg2.png');
    frames[3] = loadImage('https://i.imgur.com/KXPlTB9.png');
    frames[4] = loadImage('https://i.imgur.com/Ya0obgN.png');
    frames[5] = loadImage('https://i.imgur.com/wFN72zO.png');
    frames[6] = loadImage('https://i.imgur.com/DtMtZEq.png');
    frames[7] = loadImage('https://i.imgur.com/oEUisa6.png');
}

// update scene objects
function sceneUpdate(){
    for (var i = 0; i < bgbuildings.length; i++){
        bgbuildings[i].move();
        bgbuildings[i].display();
    }
    for (var i = 0; i < forebuildings.length; i++) {
        forebuildings[i].move();
        forebuildings[i].display();
    }
    for (var i = 0; i < dash.length; i++) {
        dash[i].move();
        dash[i].display();
    }
    for (var i = 0; i < run.length; i++) {
        run[i].move();
        run[i].display();
    }
    for (var i = 0; i < sidewalk.length; i++) {
        sidewalk[i].move();
        sidewalk[i].display();
    }
}

// adding and deleting excess objects
function shiftScene() {
    var buildingsToKeep = [];
    for (var i = 0; i < bgbuildings.length; i++) {
        if (bgbuildings[i].x + bgbuildings[i].breadth > 0) {
            buildingsToKeep.push(bgbuildings[i]);
        }
    }
    bgbuildings = buildingsToKeep;
    for (var i = 0; i < forebuildings.length; i++) {
        if (forebuildings[0].x + forebuildings[0].width < 0) {
            forebuildings.push(makeBuildingFore((forebuildings.length-1)*95));
            forebuildings.shift();
        }
    }
    for (var i = 0; i < sidewalk.length; i++) {
        if (sidewalk[0].x + 50 < 0) {
            sidewalk.push(makeSidewalk(width + width/7));
            sidewalk.shift();
        }
    }
    for (var i = 0; i < dash.length; i++) {
        if (dash[0].x + width/7 < 0) {
            dash.push(makeDash(width));
            dash.shift();
        }
    }
}

// randomly adding background buildings
function bldgProb() {
    var newBuildingLikelihood = 2.5; 
    if (random(0,100) < newBuildingLikelihood) {
        bgbuildings.push(makeBuilding(width));
    }
}

// method to update position of objects every frame
function buildingMove() {
    this.x += this.speed;
}

// draw background building and windows
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(53); 
    stroke(0); 
    push();
    translate(this.x, height - 60);
    rect(0, -bHeight, this.breadth, bHeight);
    for (var i = 0; i < this.nFloors; i++) {
        for (var j = 0; j < this.breadth/20; j++) {
            fill(155, 133, 38);
            circle(j*15+10, -10-(i * floorHeight), 10);
        }
    }
    pop();
}

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

// drawing foreground buildings with long windows
function buildingDisplayFore() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight;
    fill(120);
    stroke(0);
    push();
    translate(this.x, height - 60);
    rect(0, -bHeight, this.width, bHeight+10);
    for (var i = 0; i < this.nFloors; i++) {
        fill(155, 133, 38);
        rect(5, -10-(i*floorHeight), this.width-10, floorHeight-10, 5);
    }
    pop();
}

function makeBuildingFore(birthLocationX) {
    var bldg = {x: birthLocationX,
                width: 90,
                speed: -2,
                nFloors: round(random(3, 6)),
                move: buildingMove,
                display: buildingDisplayFore
                }
    return bldg;
}

// adding street lights
function sidewalkDisplay() {
    image(light, this.x, height-85, 57, 50);
}

function makeSidewalk(birthLocationX) {
    var swalk = {x: birthLocationX,
                 speed: -2.5,
                 width: width/4,
                 move: buildingMove,
                 display: sidewalkDisplay
                }
    return swalk;
}

// adding street dashes
function dashDisplay() {
    stroke(144, 133, 0);
    line(this.x, height-20, this.x + width/14, height-20);
}

function makeDash(birthLocationX) {
    var d = {x: birthLocationX,
             speed: -2.5,
             width: width/7,
             move: buildingMove,
             display: dashDisplay
            }
    return d;
}

// adding running dude
function charDisplay() {
    image(frames[this.frame], this.x, 243, 30, 27);
}

function frameMove() {
    if (this.frame == 7 & this.step%3 == 0) {
        this.frame = 0;
    } else if (this.step%3 == 0) {
        this.frame++;
    }
    this.step++;
}

function makeChar(birthLocationX) {
    var c = {x: birthLocationX,
             frame: 0,
             step: 0,
             move: frameMove,
             display: charDisplay
            }
    return c;
}

function setup() {
    createCanvas(450, 300);
    background(5, 5, 45);
    // create an initial collection of buildings
    for (var i = 0; i < 7; i++){
        var rx = random(width);
        bgbuildings[i] = makeBuilding(rx);
        forebuildings[i] = makeBuildingFore(i * 95);
        dash[i] = makeDash(i * width/6);
    }
    for (var i = 0; i < 5; i++) {
        sidewalk[i] = makeSidewalk(i * width/4);
    }
    for (var i = 0; i < frames.length; i++) {
        run[i] = makeChar(10);
    }
    frameRate(30);
}

function draw() {
    background(5, 5, 45);
    //backgournd cloud
    image(bgCloud, 0, 0, 600, 100);
    // road and sidewalk
    fill(0);
    rect(0, height-50, width, 60);
    fill(66);
    rect(0, height-60, width, 20);
    // updatinga and displaying scene objects
    sceneUpdate();
    shiftScene();
    bldgProb(); 
    push();
    // layering transparent clounds
    tint(255, 127);
    image(foreCloud, 0, 0, 600, 100);
    pop();
}

Project 11 – Generative Landscape

For this project, I wanted to create a bustling city environment. I created an iPhone in the middle with someone pressing the record button, imagining that they are in a driving car and want to take in the city.

sketch
/* 
 * Amy Lee 
 * amyl2
 * Section B 
 */ 

// Variables for people 
var px = [];
var py = [];
var pdx = [];
var pc = [];
var skin = []; 
var pWidth = []; 
var pHeight = []; 

// Variables for clouds 
var cx = [];
var cy = [];
var cdx = [];
var cWandH = []; 

var buildings = [];
var houses = []; 

function preload() {
    // loading image files 
    finger = loadImage("https://i.imgur.com/DPWPwwe.png"); 
    police = loadImage("https://i.imgur.com/9xYWNnM.png"); 
    taxi = loadImage("https://i.imgur.com/ywwvyoP.png")
} 

function setup() {
    createCanvas(480,480); 
    frameRate(20); 

    // Finger 
    fin = new Object(); 
    fin.image = finger; 
    fin.x = 200;
    fin.y = 460; 
    fin.dx = 1; 
    fin.dy = 1; 
    fin.width = 290; 
    fin.height = 200; 
    fin.move = fingerMove; 
    fin.draw = fingerDraw;

    pol = new Object(); 
    pol.image = police; 
    pol.x = 700; 
    pol.y = 255; 
    pol.dx = 15; 
    pol.width = 240; 
    pol.height = 240; 
    pol.move = polMove; 
    pol.draw = polDraw; 

    tax = new Object(); 
    tax.image = taxi; 
    tax.x = 900; 
    tax.y = 275; 
    tax.dx = 10; 
    tax.width = 230
    tax.height = 230 
    tax.move = taxiMove; 
    tax.draw = taxiDraw; 

    // People
    for (var i = 0; i < 10; i ++){
        px[i] = random(25, width - 25); 
        py[i] = 350; 
        pdx[i] = random(1,3); 
        pc[i] = color(random(255), random(255), random(255));
        skin[i] = color(random(55,200), 80, 90); 
        pWidth[i] = random(20,50); 
        pHeight[i] = random(30,80); 
    }

    // Clouds 
    for (var i = 0; i < 5; i ++){
        cx[i] = random(20,460); 
        cy[i] = random(30,90); 
        cdx[i] = 2; 
        // cloud width and height 
        cWandH[i] = random(20,30); 
    }

    // Building 
    for (var j = 0; j < 5; j ++){
        var bx = random(width); 
        buildings[j] = makeBuildings(bx); 
    }

    // House 
    for (var k = 0; k < 3; k ++){
        var hx = random(width); 
        houses[k] = makeHouses(hx); 
    }

    frameRate(10); 
} 

function draw() {
//  background(130,208,218); 
    background(200,241,208);

    sidewalk(); 
    road(); 

    // Draw clouds, make them move right, and reappear if they move off canvas 
    for (var i = 0; i < 5; i++){
       cloud(cx[i], cy[i], cdx[i], cWandH[i], cWandH[i]);
       cx[i] += cdx[i]; 

       if (cx[i] > width + 10){
           cx[i] = -40; 
       }
   }

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

    updateAndDisplayHouses();
    removeHousesThatHaveSlippedOutOfView();
    addNewHousesWithSomeRandomProbability(); 

    // Make buildings reappear if they go off the right side of the canvas 
    // Reappear on the left side 
    for (var j = 0; j < buildings.length; j++){
        if (buildings[j].x > width + 20) {
           buildings[j].x = -60; 
       }
   }

    // Make houses reappear if they go off the right side of the canvas 
    // Reappear on the left side 
    for (var k = 0; k < houses.length; k ++){
        if (houses[k].x > width + 20) {
            houses[k].x = -100; 
        }
    }

    // Make people reappear if they go off the right side of the canvas 
    // Reappear on the left side     
    for (var i = 0; i < 10; i ++){
        people(px[i], py[i], pdx[i], pc[i],skin[i],pWidth[i], pHeight[i]); 
        px[i] += pdx[i]; 

        if(px[i] > width+50){
           px[i] = -50; 
        }
    }

    pol.draw(); 
    pol.move(); 

    tax.draw(); 
    tax.move();  

    drawiPhone();  
    fin.draw(); 
    fin.move(); 

    if (frameCount >= 60){
    record(); 
    }

}

 function people(px, py, pdx, pc,skin, pWidth, pHeight){
    fill(pc); 
    noStroke(); 
    // Shirt 
    ellipse(px, py, pWidth, pHeight); 
    // Head 
    fill(skin); 
    ellipse(px,py-25,20,20); 
 }


function fingerDraw(){
    image(finger, this.x, this.y, this.width, this.height); 
}

// Move finger to record button 
function fingerMove(){ 
    if (fin.x > 142 & this.y > 378){
    this.x -= this.dx; 
    this.y -= this.dy; 
    }
}

function polDraw(){
    image(police, this.x, this.y, this.width, this.height); 
}

function polMove(){
    this.x -= this.dx; 
    if (this.x <= -800){
        this.x = 500; 
    }
}

function taxiDraw(){
    image(taxi, this.x, this.y, this.width, this.height); 
}

function taxiMove(){
    this.x -= this.dx; 
    if (this.x <= -1000){
        this.x = 500; 
    }
}

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

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

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

// Make buildings move to right 
function buildingsMove() {
    this.x += this.speed;

}

function buildingsDisplay() {
    var floorHeight = 30;
    var bHeight = this.nFloors * floorHeight; 
    push();
    noStroke(); 
    fill(this.col); 
    translate(this.x, height - 40);
    // Drawing the actual buildings
    rect(0, -bHeight-110, this.breadth, bHeight);
//    fill(18, 126, 190);  
    // Windows 
    for (var i = 0; i < this.nFloors; i++) {
        fill(18, 126, 190);  
        rect(5, -130 - (i * floorHeight), this.breadth - 10, 10);
    }
    // Building antennae 
    stroke(18,126,190); 
    strokeWeight(2); 
    line(5,-bHeight-110,5,-bHeight-120); 
    line(10,-bHeight-110,10, -bHeight-130); 
    noStroke(); 
    pop();
}

function makeBuildings(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 60,
                speed: 4.0,
                col: color(121,204,221),
                nFloors: round(random(5,10)),
                move: buildingsMove,
                display: buildingsDisplay}
    return bldg;
}

//              HOUSES                   //
function updateAndDisplayHouses(){
    for (var k = 0; k < houses.length; k++){
        houses[k].move(); 
        houses[k].display(); 
    }
}

function makeHouses(birthLocationX){
    var houses = {x: birthLocationX,
                 breadth: 100,
                 speed: 4.0, 
                 col1: color(232,175,104),
                 col2: color(182,110,125),
                 nFloors: round(random(2,4)), 
                 move: housesMove, 
                 display: housesDisplay}
    return houses; 
}

function removeHousesThatHaveSlippedOutOfView() {
    var housesToKeep = []; 
    for (var k = 0; k < houses.length; k++){
        if (houses[k].x + houses[k].breadth > 0) {
            housesToKeep.push(houses[k]); 
        }
    }
    houses = housesToKeep; 
}


function addNewHousesWithSomeRandomProbability() {
    var newHousesLikelihood = .0001; 
    if (random(0,1) < newHousesLikelihood) {
        houses.push(makeHouses(width)); 
    }
}

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

function housesDisplay() {
    var floorHeight = 20; 
    var hHeight = this.nFloors * floorHeight; 
    push(); 
    noStroke(); 
    fill(this.col1); 
    translate(this.x, height-30); 
    rect(0, -hHeight - 110, this.breadth, hHeight); 
    fill(this.col2); 
    triangle(0, -hHeight - 110, this.breadth, -hHeight - 110, this.breadth/2, -hHeight - 140); 
    rect(30, -hHeight - 90, this.breadth - 60, hHeight - 20); 
    fill(252, 197, 132); 
    ellipse(50, -hHeight - 110 , 8, 8); 
    pop(); 
}

function cloud(cx, cy, cdx, cWandH, cWandH){
    push(); 
    stroke(255); 
    strokeWeight(20); 
    line(cx, cy, cx+30, cy); 
    pop(); 
    fill(255);
    ellipse(cx,cy,cWandH, cWandH); 
    ellipse(cx+10,cy-10,cWandH, cWandH); 
    ellipse(cx+20,cy,cWandH, cWandH); 
}

function drawiPhone(){
    fill(0); 
    // top rectangle
    rect(130,40,200,60); 
    // left side 
    rect(130,40,20,400); 
    // right side 
    rect(330,40,20,400); 
    // bottom rectangle 
    rect(130,380,200,60) 
    // home button 
    fill(255); 
    ellipse(236,416,31,31); 
    fill(33);
    ellipse(240,416,33,33);  
    // small rectangle at top 
    fill(58); 
    rect(215,65,50,10); 
    // glass shine 
    push(); 
    stroke(255); 
    strokeWeight(10); 
    line(160,140,200,110); 
    line(160,170,240,110); 
    line(240,360,310,305); 
    line(272,370,315,336); 
    pop(); 
} 

function sidewalk(){
    noStroke(); 
    fill(236,205,158); 
    rect(0,330,480,70); 
    fill(132,64,64); 
    rect(0,390,480,10); 
}

function road(){
    fill(180,145,126); 
    rect(0,400,480,80); 
}

// REC button on iPhone 
function record(){
    fill(255,0,0); 
    ellipse(270,124,13,13); 
    textSize(20);     
    text("REC", 280, 130); 
}