nahyunk1 – Project 10 Landscape

sketch

//NaHyun Kim
//section B
//nahyunk1@andrew.cmu.edu
//Project 10 - landscape

var tSpeed = 0.0013;
var tDetail = 0.002;
var stars = [];
var r = 255;
var g = 255;
var b = 255;

function setup() {
    createCanvas(400, 500);
    frameRate(10);

    for (var s=0; s<1; s++){
      var place = random(width);
      stars[s] = makeStars(place);
    }
}

function draw() {
  var Col = color(25,0,51) //dark purple;
  var Col2 = color(51, 0, 102)// lighter purple;
  //background color
  for (var i=0; i < height; i++) {
   var gradi = map(i, 90, 300, 0, 1);
   var Lerp = lerpColor(Col, Col2, gradi);
    stroke(Lerp);
    line(0, i, width, i);
   }

   //stardust
  updateAndDisplayStars();
  removeStars();
  starGenerate();
  starDisplay();

   //moon
   for (var c=0; c<10; c++){
     noStroke();
     fill(217,154,100,(10-c)*1)
     ellipse(310, 30, 40+(10*c), 40+(10*c));
     noStroke();
     fill(255, 223, 181);
     ellipse(310, 30, 50, 50);
     fill(252, 240, 224);
     ellipse(313, 30, 45, 45);
   }

   //rolling mountains behind
   strokeWeight(0.1);
   stroke(random(0,r), random(0,g), random(0,b));
   fill(20);
   beginShape();
     for (var x = 0; x < width; x++) {
       var t = (5*x * tDetail) + (millis() * tSpeed/10);
       var y = map(noise(t/4), 0, 1, 0, 600);
       curveVertex(x, y);
     }
   curveVertex(500, 1000);
   curveVertex(0,width);
   endShape(CLOSE);

  noStroke();
  fill(0);  //rolling mountain tops
  beginShape();
    for (var x = 0; x < width; x++) {
        var t = (5*x * tDetail) + (millis() * tSpeed/2);
        var y = map(noise(t/2), 0,1, 1, 600);
        curveVertex(x, y);
     }
  curveVertex(500, 10000);
  curveVertex(0,width);
  endShape(CLOSE);
}

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

function removeStars(){
       var starsKeep = [];
       for (var i = 0; i < stars.length; i++){
           if (stars[i].x + stars[i].breadth > 0) {
               starsKeep.push(stars[i]);
           }
       }
       stars = starsKeep; //remaining stars.
}
function starGenerate() {
       // add stars
       var likelyStar = 0.009;
       if (random(0,1) < likelyStar) {
           stars.push(makeStars(width));
       }
   }
//update position
function starsMove() {
       this.x += this.speed;
   }
function starDisplay() {
       strokeWeight(random(0.5,3));
       fill(random(0,r), random(0,g), random(0,b));
       stroke(random(0,r), random(0,g), random(0,b));
       push();
       translate(this.x, 20);
       for (var i = 0; i < stars.length; i++) {
           point(random(10,200), random(10,200));
       }
       pop();
   }
function makeStars(birthLocationX) {
     var starr = {x: birthLocationX,
                 breadth: 30,
                 speed: -0.003,
                 move: starsMove,
                 display: starDisplay}
     return starr;
 }

I created this image based on the time when I was looking out the window of a car at night on a highway next to mountainous forests. I had multichromatic stars appear and disappear which made it seem like they were actual stars and had the background of the mountain respond to the starlights to emphasize the surreal scenery. I also created the brightness effect of the moon by creating a series of ellipses with fading hues of the color of the moon.

ablackbu-Project-10-Generative Landscape

sketch

var terrainSpeed = 0.0008;
var terrainDetail = 0.008;
var fiX = 450;
var fi2X = 500;
var fi3X = 475;
var scooba;
var scoobaX = 450


function preload() {
    scooba = loadImage('https://i.imgur.com/8HhJZHY.png')
}

function setup() {
    createCanvas(400, 200);

}
 
function draw() {
    background(70,200,250);
    //draw terrain
    terrain();
    //draw sub
    sub();
    //draw fish
    fish();
    //sand
    fill(226,226,176)
    rect(0,height-20,width,20)
    //scooba diver
    scoobaD();
    



}

function terrain() {
    noFill(); 
    beginShape(); 
    stroke(40,120,40)
    strokeWeight(2)
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 0, height);
        vertex(x, y); 
        
        

        //terrain
        push();
        fill(40,120,40);
        ellipse(x,y+25,20,20); //thick black hill
        ellipse(x,y+55,10,10); //thin black hill

        stroke(20,80,18);
        strokeWeight(1);
        if(x%2){
            line(x,y,x,y+200) //white lines
        }
        pop();

        
    }
    endShape();
}


function sub() {
        //sub
    push();
    rotate(random(-.01,.01));
    strokeWeight(0);
    fill('yellow');
    
    rect(170,100,70,35,15); //body
    rect(185,89,30,30,5); //top
    rect(150,107,15,20,3); //tail
    rect(162,112,10,10); //connector
    rect(190,85,5,10); //airtube
    ellipse(225,117.5,43,35); //nose


    fill(200);
    //windows
    ellipse(188,115,12,12);
    ellipse(205,115,12,12);
    ellipse(223,115,12,12);

    fill(100);
    //inside windows
    ellipse(188,115,9,9);
    ellipse(205,115,9,9);
    ellipse(223,115,9,9);
    pop();
}

function fish() {

    var fiS = 3.5;
    var fi2S = 2;
    var fi3S = 3;

    strokeWeight(0);
    fill(0);
    //fish1
    ellipse(fiX,50,25,10);
    triangle(fiX+10,50,fiX+16,45,fiX+16,55);
    fiX = fiX-fiS;
    if(fiX < 0){
        fiX = 450;
    }
    //fish2
    ellipse(fi2X,60,25,10);
    triangle(fi2X+10,60,fi2X+16,55,fi2X+16,65);
    fi2X = fi2X-fi2S;
    if(fi2X < 0){
        fi2X = 500;
    }
    //fish3
    ellipse(fi3X,70,25,10);
    triangle(fi3X+10,70,fi3X+16,65,fi3X+16,75);
    fi3X = fi3X-fi3S;
    if(fi3X < 0){
        fi3X = 475;
    }
}  

function scoobaD(){
    var scoobaS = 3.5;
    push();
    scale(.6);
    translate(50,10);
    image(scooba,scoobaX,0);
    //move scooba across screen
    scoobaX = scoobaX - scoobaS;
    if(scoobaX < -150){
        scoobaX = 550;
    }
    pop();
} 
    

For this project I wanted to play off of the Beatles’ song “Yellow Submarine.” I used some code from the example to generate the landscape which I then manipulated to create details in the underwater mountains. The sub in the middle is rotating a tenth of a degree every frame to create a turbulent look. fish and a scuba diver go past at randomly generated speeds.

What I learned while doing this project is that making separate functions for each part and then calling them in the draw function is a great way to change code and manipulate it.

heeseoc-Project-10-Landscape

sketch

//Steph Chun
//15-104 section #A
//heeseoc@andrew.cmu.edu
//Project-10

var buildings = [];
var terrainSpeed = 0.0005;
var terrainDetail = 0.008;
var c1, c2;
var lc1, lc2, lc3, lc4;

function setup() {
    createCanvas(480, 480); 
    //background gradient color
    c1 = color(60,1,29);
  	c2 = color(205,100,70);
  	//gradient color for reflected streetlight
  	lc1 = color(255,230,109,30);
  	lc2 = color(255,230,109,0);
  	//gradient color for reflected buildings
    lc3 = color(random(180,200), random(100,150), random(100,150), 50);
  	lc4 = color(random(180,200), random(100,150), random(100,150), 0);

    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    frameRate(20);
}

function draw() {
    setGradient(0, 0, width, height/2+50, c1, c2, 1);
    updateBuildings();
    removeBuildings();
    addBuildings(); 
    makeBushes();
    riverDisplay();
}

//gradient for the background(sky)
function setGradient(x, y, w, h, c1, c2, axis) {
  noFill();
    for (var i = y; i <= y+h; i++) {
      var inter = map(i, y, y+h, 0, 1);
      var c = lerpColor(c1, c2, inter);
      stroke(c);
      line(x, i, x+w, i);
    } 
}

//
function updateBuildings(){
    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

//remove buildings when they're out of frame
function removeBuildings(){
    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep;
}

//introduce new buildings
function addBuildings() {
    var newBuilding = 0.008; 
    if (random(0,1) < newBuilding) {
        buildings.push(makeBuilding(width));
    }
}

//move the buildings
function buildingMove() {
    this.x += this.speed;
}

//draw multiple buildings
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    push();
    noStroke();
    fill(this.bColor); 
    translate(this.x, height - 190);
    rect(0, -bHeight, this.breadth, bHeight);
    stroke(200); 
    for (var y = 0; y < this.nFloors; y++) {
    	for (var x = 0; x < 6; x++){
    		noStroke();
    		fill(random(165,255), random(180,255), random(200,220));
    		rect(x*10+8, -10-(y*floorHeight), 4, 7);
    	}
	}
    pop();
}

//determine the shape and movement of the building
function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 70,
                speed: -1.2,
                bColor: color(random(180,200), random(100,150), random(100,150)),
                nFloors: round(random(3,10)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

//make bushes
function makeBushes(){
    noStroke(); 

    //the farthest bush
    beginShape();
    for (var x = 0; x < width; x++) {
    	fill(93,15,11);
        var t = (terrainDetail * x) + (millis() * terrainSpeed);
        var y = map(noise(t*2), -.5, 1, 370, height/2-30);
        curveVertex(x, y); 
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE); 

    //second to the front 
    beginShape();
	for (var x = 0; x < width; x++) {
        fill(61,0,4);
        var t2 = (terrainDetail * x) + (millis() * terrainSpeed);
        var y2 = map(noise(t2*2), -.5, 1, 390, height/2-30);
        curveVertex(x, y2); 
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE);   

    //closest(darkest) bush
    beginShape();
	for (var x = 0; x < width; x++) {
        fill(31,7,6);
        var t3 = (terrainDetail * x) + (millis() * terrainSpeed);
        var y3 = map(noise(t3*2), -.7, 1.1, 420, height/2-10);
        curveVertex(x, y3); 
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE); 
}

function riverDisplay(){

	//river and road
    fill(31,4,9);
    rect(0, height/2+50, width, height/2+50); 
    fill(120,6,41);
    rect(0, height/2+50, width, 5);
    fill(161,12,44);
    rect(0, height/2+53, width, 2);

    for (var s = 0; s < width; s++) {

    	//streetlight
    	strokeWeight(1.3);
    	stroke(255,216,205);
    	line(s*80-7, height/2+30, s*80+7, height/2+30);
    	stroke(217,136,109);
    	line(s*80, height/2+50, s*80, height/2+30);
    	noStroke();
    	fill(255,246,109,60);
    	quad(s*80-7, height/2+30, s*80+7, height/2+30, s*80+15, height/2+50, s*80-15, height/2+50);
    	
    	//gradient for the reflected streetlights
    	setlGradient(s*80-8, height/2+55, 16, height/2-55, lc1, lc2, 1);
    	setl2Gradient(s*80-15, height/2+55, 30, height/2-55, lc1, lc2, 1);

    	//gradient for the reflected buildings 
    	setl3Gradient(s*30+(random(10,70)), height/2+55, 10, height/2-55, lc3, lc4, 2);
    }

    //road detail
    fill(31,4,9,80);
    rect(0, height/2+53, width, 10); 
 
}

//gradient for the reflected streetlights
function setlGradient(x, y, w, h, lc1, lc2, axis) {
	noFill();
	for (var i = y; i <= y+h; i++) {
	    var inter = map(i, y, y+h, 0, 1);
	    var lc = lerpColor(lc1, lc2, inter);
	    stroke(lc);
	    line(x, i, x+w, i);
    } 
}
function setl2Gradient(x, y, w, h, lc1, lc2, axis) {
	noFill();
	for (var i = y; i <= y+h; i++) {
	    var inter = map(i, y, y+h, 0, 1);
	    var lc = lerpColor(lc1, lc2, inter);
	    stroke(lc);
	    line(x, i, x+w, i);
    } 
}

//gradient for the reflected buildings 
function setl3Gradient(x, y, w, h, lc3, lc4, axis) {
	noFill();
	for (var i = y; i <= y+h; i++) {
	    var inter = map(i, y, y+h, 0, 1);
	    var lc = lerpColor(lc3, lc4, inter);
	    stroke(lc);
	    line(x, i, x+w, i);
    } 
}




I created a cityscape at night, with the lights reflected on the river. I immediately came up with the image when I first read the instructions, and then noticed that the sample code would be super helpful for me to get started on this. I modified the code so that the shapes are visually more pleasing, and played around a lot with gradients to achieve the reflected city on the surface of the water. I wanted to have multiple layers of buildings, but for some reason, my code got broken whenever I tried adding more. So I just settled with varying the colors of the building to be more random.

Jihee Kim_SectionD_Project-10-Landscape

jiheek1_project10_sketch

//Jihee Kim
//15-104 MWF 9:30
//jiheek1@andrew.cmu.edu
//Project 10 Landscape
//section D


var stars = []; // an array of all stars
var clouds = []; // an array of all clouds


function setup() {
    createCanvas(480, 380);
    // initialize stars
    for (var s = 0; s < 750; s++){ // loop through stars
        var starPositionX = random(width); // the x position of the cloud is
                                           // random along the width of canvas
                                           // the randomness is later set
                                           // in the replaceClouds() function
        var starPositionY = random(0, height-120);
        stars[s] = makeStars(starPositionX, starPositionY);
    }
    // initialize clouds
    for (var i = 0; i < 5; i++){ // loop through clouds
        var cloudPositionX = random(width); // the x position of the cloud is
                                            // random along the width of canvas
                                            // the randomness is later set
                                            // in the replaceClouds() function
        var cloudPositionY = random(height/3, height*2/3);
        clouds[i] = makeCloud(cloudPositionX, cloudPositionY);
    }
}


function draw() {
    //WATER
    fill(11, 19, 71);
    rect(0, height-100, width, 100); // set the very bottom of the canvas as
                                     // water
    //gradient background
    // draw the gradient background for the pink, night sky
    var top = color(198, 96, 113); // pink
	  var bottom = color(11, 19, 71); // deep blue
    Gradient(0, width, top, bottom);
    //STARS
    animateStars();
    hideStars();
    addStars();
    //MOON
    drawMoon();
    //CLOUDS (draw the clouds using functions: animate, hide, and add)
    animateClouds();
    hideClouds();
    addClouds();

}


//BACKGROUND
function Gradient (a, b, top, bottom) {
	  // top to bottom gradient (background)
    for (var i = a; i <= height-100; i++) {
        var mappedC = map(i, a, a+b, 0, 1);
        var c = lerpColor(top, bottom, mappedC);
        stroke(c);
        strokeWeight(2);
        line(a, i, a+b, i);
	  }
}


//STARS
function drawStars() {
	  noStroke();
	  // make stars seem like they're shining by manipulating transparency
	  var transparency = random(30, 100);
	  fill(255, transparency);
	  ellipse(this.x, this.y, 1.2, 1.2);
}


function animateStars() {
    for (var s = 0; s < stars.length; s++) {
        stars[s].move();
        stars[s].draw();
    }
}


function hideStars() {
    // make the clouds that are actually within the canvas to stay
    // if not, hide them
    var starsOnCanvas = [];
    for (var s = 0; s < stars.length; s++){ // go through all clouds
        // if the star is on the canvas
        if (0 < stars[s].x < width) {
            starsOnCanvas.push(stars[s]); // draw the stars that are on the
                                          // canvas
        }
    }
    stars = starsOnCanvas; // update the stars to the ones that are actually
                           // on the canvas
}


function addStars() {
    var randomValStar = 0.01; // a really small chance of stars randomly
                                // being added/generated
    if (random(0,1) < randomValStar) { // because it is not that likely for a
                                      // randomly chosen value to be less than
                                      // 0.0001, this will be a rare occasion
        var starPositionX = random(0, width);
        var starPositionY = random(0, height-120);
        stars.push(makeStars(starPositionX, starPositionY)); // generate new
                                                             // stars along
                                                             // the canvas
    }
}


function starMove() {
	//move stars by updating x coordinate
	this.x += this.speed;
}


function makeStars(starPositionX, starPositionY) {
	  var star = {x: starPositionX,
				       y: starPositionY,
				       speed: -random(0, .005),
				       move: starMove,
			         draw: drawStars}
	  return star;
}


//MOON
function drawMoon() {
    ellipseMode(CENTER);
    noStroke();
    fill(252, 202, 202, 80);
    ellipse(width/2+100, 150, 80); // overlay another ellipse for slight volume
    fill(234, 139, 139, 80);
    ellipse(width/2+100, 150, 75); // draw moon
}

// CLOUDS
function animateClouds() {
    for (var i = 0; i < clouds.length; i++){ // loop through all clouds
        clouds[i].move(); // update the clouds' positions on canvas
        clouds[i].display(); // display the clouds
    }
}


function hideClouds(){
    // make the clouds that are actually within the canvas to stay
    // if not, hide them
    var cloudsOnCanvas = [];
    for (var i = 0; i < clouds.length; i++){ // go through all clouds
        if ((clouds[i].x > 0) + (clouds[i].breadth > 0)) { // if the cloud is
                                                      // on the canvas
            cloudsOnCanvas.push(clouds[i]); // draw the clouds that are on the
                                            // canvas
        }
    }
    clouds = cloudsOnCanvas; // update the clouds to the ones that are actually
                           // on the canvas
}


function addClouds() {
    var randomVal = 0.005; // a really small chance of clouds randomly
                           // being added/generated
    if (random(0,1) < randomVal) { // because it is not that likely for a
                                   // randomly chosen value to be less than
                                   // 0.005, this will be a rare occasion
        var cloudPositionX = random(0, width);
        var cloudPositionY = random(height/3, height-50);
        clouds.push(makeCloud(cloudPositionX, cloudPositionY)); // generate new
                                                                // clouds along
                                                                // on canvas
    }
}


function cloudMove() { // update position of cloud each frame
    this.x += this.cloudSpeed;
}


function cloudDisplay() { // draw clouds
    var cloudHeightFactor = 7; // factor that determines cloud height
    var cloudHeight = this.nFloors * cloudHeightFactor;
    ellipseMode(CENTER);
    fill(242, 209, 214, this.transparency);
    noStroke();

    // higher line of clouds (further down on canvas)
    push();
    translate(this.x, height/2-130);
    ellipse(30, -cloudHeight+120, this.breadth, cloudHeight);
    pop();
    // middle line of clouds (middle on canvas)
    push();
    translate(this.x, height/2-70);
    ellipse(150, -cloudHeight+120, this.breadth, cloudHeight/1.5);
    pop();
    // lower line of clouds (further down on canvas)
    push();
    translate(this.x, height/2);
    ellipse(110, -cloudHeight+120, this.breadth, cloudHeight);
    pop();
}

function makeCloud(cloudPositionX, cloudPositionY) {
    var cloud = {x: cloudPositionX, // x position of clouds
                y: cloudPositionY, // y position of clouds
                transparency: random(10, 80),
                breadth: random(120, 250), // width of clouds
                cloudSpeed: random(0.07, 0.3), // speed at which clouds move
                nFloors: round(random(2,10)),
                move: cloudMove,
                display: cloudDisplay}
    return cloud;
}

For my ever-changing “landscape” I decided to draw a starry night. In order to make the image dynamic, I used components such as the stars and clouds that actually move and generate on it’s own based on a logic that incorporates randomness. I used a color gradient for a more engaging background as well.
I wanted to convey tranquility and I believe that I was able to achieve that goal through employing movements that speak to that.

Concept Sketch

project-10-generativeLandscape

For this project, the first thing that came to mind for a landscape was a sky with a sun, grass and people. It was a fairly simple and straight forward idea. To embellish it, I added some clouds and mushrooms. I used simple shapes to create the various objects: people, mushrooms, clouds.

I made slight differences in the height and y placement of the people, mushrooms and ground to create more depth and also layered the light clouds and dark clouds with the sun to add more depth. There are some randomized variables such as the colors of the dresses, and various sizes of things.

sketch

//array for each set of objects
var people = [];
var mushrooms = [];
var dclouds = [];
var lclouds = [];

function setup() {
  createCanvas(480, 300);
  frameRate(5); //slow down frame rate
  for(var i = 0; i < 5; i++){ //fills array with 5 people
    people.push(makePerson());
  }
  for(var j = 0; j < 7; j++){ //fills array with 7 mushrooms
    mushrooms.push(makeMushroom());
  }
  for(var k = 0; k < 3; k++){ //fills array with 3 dark clouds
    dclouds.push(makeDarkCloud());
  }
  for(var q = 0; q < 3; q++){ //fills array with 3 light clouds
    lclouds.push(makeLightCloud());
  }
}

function draw () {
  background(203, 238, 243);
  noStroke();
  fill(133, 183, 157);
  rect(0, 200, width, 100); //ground
  for(var k = 0; k < dclouds.length; k++){ //access dark clouds array
    dclouds[k].draw(); //draws dark clouds
    dclouds[k].move(); //moves dark clouds
  }
  fill(249, 220, 92);
  ellipse(400, -40, width/2, width/2); //sun
  for(var q = 0; q < lclouds.length; q++){ //access light clouds array
    lclouds[q].draw(); //draws light clouds
    lclouds[q].move(); //moves light clouds
  }
  for(var j = 0; j < mushrooms.length; j++){ //access mushrooms array
    mushrooms[j].draw(); //draws mushrooms
    mushrooms[j].move(); //moves mushrooms
  }
  for(var i = 0; i < people.length; i++){ //access people array
    people[i].draw(); //draws people
    people[i].move(); //moves people
  } 
}

function makePerson() { //creates people
  var person = {px: random(0, 480),       //person x position
                py: 205,                  //person y position
                pheight: random(20, 50),  //person height
                pcolor: random(0, 255),   //person color
                pspeed: -10               //person speed
                }
  person.draw = drawPerson; //sets draw function
  person.move = movePerson; //sets move function
  return person; 
}

function makeLightCloud() { //creates light clouds
  var lcloud = {lx: random(0, 480),       //light clouds x position
                ly: 70,                   //light clouds y position
                lspeed: -1,               //light clouds speed
                lwidth: random(140, 180)  //light clouds width
                }
  lcloud.draw = drawLightCloud; //sets draw function
  lcloud.move = moveLightCloud; //sets move function
  return lcloud;
}

function makeDarkCloud() { //creates dark clouds
  var dcloud = {dx: random(0, 480),       //dark clouds x position
               dy: 50,                    //dark clouds y position
               dspeed: -2,                //dark clouds speed
               dwidth: random(140, 180)   //dark clouds width
               }
  dcloud.draw = drawDarkCloud; //sets draw function
  dcloud.move = moveDarkCloud; //sets move function
  return dcloud;
}

function makeMushroom() { //creates mushrooms
  var mushroom = {mx: random(0, 480),     //mushroom x position
                  my: 200,                //mushroom y position
                  mheight: random(5, 20), //mushroom height
                  mspeed: -3,             //mushroom speed
                  mwidth: random(20, 40)  //mushroom width
                  }
  mushroom.draw = drawMushroom; //sets draw function
  mushroom.move = moveMushroom; //sets move function
  return mushroom;
}

function drawPerson() { //draws people
  fill(this.pcolor);
  triangle(this.px - 10, this.py, this.px + 10, this.py, this.px, this.py - this.pheight); //body
  fill(245, 228, 215);
  ellipse(this.px, this.py - this.pheight, this.pheight - 10, this.pheight - 10); //head
}

function drawMushroom() { //draws mushrooms
  fill(255);
  rect(this.mx - 5, this.my - this.mheight - 10, 10, this.mheight + 10, 5); //stem
  fill(237, 187, 187);
  arc(this.mx, this.my - this.mheight, this.mwidth, 20, PI, 0, PIE); //head
}

function drawDarkCloud() { //draws dark clouds
  fill(184, 215, 219);
  ellipse(this.dx, this.dy, this.dwidth, 50); //cloud
}

function drawLightCloud() { //draws light clouds
  fill(212, 247, 252);
  ellipse(this.lx, this.ly, this.lwidth, 50); //cloud
}

function movePerson() { //moves people
  this.px += this.pspeed; //x position decreasing
  if(this.px < 0){ //pops up on right edge of canvas once off left edge
    this.px = width;
  }
}

function moveMushroom() { //moves mushrooms
  this.mx += this.mspeed; //x position deacreasing
  if(this.mx < 0){ //pops up on right edge of canvas once off left edge
    this.mx = width;
  }
}

function moveDarkCloud() { //moves dark clouds
  this.dx += this.dspeed; //x position decreasing
  if(this.dx < 0 - this.dwidth/2){ //starts appearing on right edge once completely off left edge
    this.dx = width + this.dwidth/2;
  }
}

function moveLightCloud() { //moves light clouds
  this.lx += this.lspeed; //x position decreasing
  if(this.lx < 0 - this.lwidth/2){ //starts appearing on right edge once completely off left edge
    this.lx = width + this.lwidth/2;
  }
}

akluk-Project-10-Generative Landscape

Initially, I was going to make a generative landscape based on microscopic creatures. Such as what you would see under a microscope. However I later decided to go one layer more, and tried to portray the subatomic environment. For this project, I wanted to create a subatomic generative landscape. So the basis of in the subatomic environment, is the atom. And I had to decide how to create differing forms of atoms. Then I realized that atoms with different sizes also create different elements. I created 3 types of possible moving objects which are different sized atoms, with electrons wizzing around them. Below attached are some of my sketches.

Sketches for atoms

sketch

//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Project 10

var atoms = [];


function setup() {
    createCanvas(480, 480); 
    
    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        atoms[i] = makeAtom(rx);
    }
    frameRate(20);
}


function draw() {
    background(0); 
    
    push();
    
    stroke(0);
    fill(0); 
    rect(0,0, width, height);
    
    displayStatusString();

    updateAndDisplayAtoms();
    removeAtomsThatHaveSlippedOutOfView();
    addNewAtomsWithSomeRandomProbability(); 
    pop();
}


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


function removeAtomsThatHaveSlippedOutOfView(){
    // 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 atomsToKeep = [];
    for (var i = 0; i < atoms.length; i++){
        if (atoms[i].x + atoms[i].breadth > 0) {
            atomsToKeep.push(atoms[i]);
        }
    }
    atoms = atomsToKeep; // remember the surviving buildings
}


function addNewAtomsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newAtomLikelihood = 0.02; 
    if (random(0,1) < newAtomLikelihood) {
        atoms.push(makeAtom(width));
    }
}


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

// draw the building and some windows
function objectDisplay() {
    var floorHeight = 20;
    var particle_size = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(120); 
    noStroke(0); 
    push();
    translate(this.x, this.y);
    stroke(0);
    if (this.breadth == 1){
    	fill(color(255,0,0));
    	ellipse(0, 0, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(particle_size/4, particle_size/4 , particle_size, particle_size);
    }
    else if (this.breadth == 2){
    	fill(color(255,0,0));
    	ellipse(-particle_size/4, -particle_size/4, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(particle_size/4, -particle_size/4 , particle_size, particle_size);
    	fill(color(255,0,0));
    	ellipse(-particle_size/4, particle_size/4, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(particle_size/4, particle_size/4 , particle_size, particle_size);
    }
    else{
    	fill(color(255,0,0));
    	ellipse(-particle_size/3, particle_size/3, particle_size, particle_size);
    	fill(color(0,0,255));
    	ellipse(0, -particle_size/3 , particle_size, particle_size);
    	ellipse(particle_size/3, particle_size/3, particle_size, particle_size);
    }

    noStroke();
    fill(color(180,180,40));
    for (var i = 0; i < this.nFloors; i++) {
        ellipse(random(-particle_size,particle_size), random(-particle_size,particle_size), 5, 5);
    }
    pop();
}


function makeAtom(birthLocationX) {
    var bldg = {x: birthLocationX,
    			y: round(random(0,height)),
                breadth: random([1,2,3]),
                speed: -1.0,
                nFloors: round(random(2,8)),
                move: atomMove,
                display: objectDisplay}
    return bldg;
}


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


function displayStatusString(){
    noStroke(); 
    fill(0); 
    var statusString = "# Atoms = " + atoms.length;
    text(statusString, 5,20); 
}

mmirho – Project 10 – Inside a Submarine

This is supposed to show what it would be like to look out of a submarine!

Different color and sized fish fly by at different speeds, as you peek through the portholes.

I will admit, however, I was unable to figure out how to use objects effectively without blatantly copying the format given to me. Instead, I used loops and if statements, and I understand I did this project incorrectly. However, I hope it satisfies the requirement for a landscape! 🙂

I plan to schedule some office hours to more fully understand how objects function. Sorry!

sketch

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

//Creates fish x location for each 
//fish to increment with speed
var fishX1 = 0;
var fishX2 = 0;
var fishX3 = 0;

//Assigns speed values for each fish
var speed1 = 0;
var speed2 = 0;
var speed3 = 0;

//Assigns vertical location values for each fish
var up1 = 0;
var up2 = 0;
var up3 = 0;


//Assigns r, g, and b values for each fish
var r1 = 0;
var r2 = 0;
var r3 = 0;
var g1 = 0;
var g2 = 0;
var g3 = 0;
var b1 = 0;
var b2 = 0;
var b3 = 0;

//Assigns size variables to each of the three fish
var big1 = 0;
var big2 = 0;
var big3 = 0;


function draw() {
    background(255);

    //This assigns random variables to each fish
    //so they are a random size, speed, location, and color
    if (fishX1 < 1) {
        speed1 = random(0.1,2);
        up1 = height/2 + random(-50,50);
        r1 = random(0,200);
        g1 = random(0,200);
        b1 = random(0,200);
        big1 = random(10,30);
    } else if (fishX2 < 1) {
        speed2 = random(0.1,2);
        up2 = height/2 + random(-50,50);
        r2 = random(0,200);
        g2 = random(0,200);
        b2 = random(0,200);
        big2 = random(10,30);
    } else if (fishX3 < 1) {
        speed3 = random(0.1,2);
        up3 = height/2 + random(-50,50);
        r3 = random(0,200);
        g3 = random(0,200);
        b3 = random(0,200);
        big3 = random(10,30);
    }

    //Moves the fish at a random speed
    fishX1 += speed1;
    fishX2 += speed2;
    fishX3 += speed3;

    //Makes each fish
    fish(fishX1, up1, big1, r1,g1,b1)
    fish(fishX2, up2, big2, r2,g2,b2)
    fish(fishX3, up3, big3, r3,g3,b3)



    //Makes the submarine inside background
    subBackground();


    porthole(width/4, height/2);
    porthole(3*width/4, height/2);

    //resets the location of the fish at 0 when it 
    //reaches the end

    if (fishX1 > width) {
        fishX1 = 0;
    } else if (fishX2 > width) {
        fishX2 = 0;
    } else if (fishX3 > width) {
        fishX3 = 0;
    }
}

function porthole(x,y) {

    //Makes a porthole, with the inside slightly blue
    //but translucent, so it acts like a window

    fill(0, 0, 200, 80);
    strokeWeight(30);
    stroke(200);
    ellipse(x,y,height/3,height/3);

}

function fish(x,y,big,r,g,b) {

    //Makes a fish with an ellipse and a triangle

    fill(r,g,b);
    noStroke();
    ellipse(x,y,big*2,big)
    triangle(x-big/2,y,   x-big*1.5,y+big/2,   x-big*1.5,y-big/2);
    fill(0);

    //adds a little eye
    ellipse(x+3*big/5, y-big/4.5, 3,3);

}

function subBackground() {

    //Fills in the outside of the portholes with
    //green, indicating the inside of the submarine

    fill(0,70,0);
    rectMode(CENTER);
    rect(width/2, height/2, 100, height);
    rect(width/2 - 237, height/2, 100, height);
    rect(width/2 + 237, height/2, 100, height);
    rect(width/2, height/2-215, width, 300);
    rect(width/2, height/2+215, width, 300);

}

katieche-project-10

katieche-10

/*
katie chen
katieche@andrew.cmu.edu
project 10
section e
*/

var terrainSpeed = 0.0002;
var terrainDetail = 0.002;
var backdetail = 0.003;
var clouds = [];
var cacti = [];
var camelfr = [];
var cam = [];

function preload() {
	var camelfile = [];
		camelfile[0] = "https://i.imgur.com/bDUcYTm.png";
		camelfile[1] = "https://i.imgur.com/6dVVrob.png";
		camelfile[2] = "https://i.imgur.com/hbSKaEk.png";
		camelfile[3] = "https://i.imgur.com/7mLCzwN.png";
		camelfile[4] = "https://i.imgur.com/ajswkv9.png";
		camelfile[5] = "https://i.imgur.com/5PYiIL8.png";
		camelfile[6] = "https://i.imgur.com/izwJZyn.png";
		camelfile[7] = "https://i.imgur.com/bHlNbyH.png";

		for(var i =0; i < 8; i++){
			camelfr[i] = loadImage(camelfile[i]);
		}
}


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

    // making initial collection of objects
    for (var i = 0; i < 10; i++){
    	var rx = random(width);
        clouds[i] = makeCloud(rx);
        cacti[i] = makeCactus(rx);
        cam[i] = makeCam(rx);
    }

  	frameRate(10);
}
 
function draw() {
    background(185, 174, 176);
    push();
    noStroke();
    fill(188, 177, 178);
	rect (0, 140, width, height-140);
	fill(195, 180, 176);
    rect (0, 170, width, height-170);
   	fill(200, 185, 176);
    rect (0, 230, width, height-230);
    fill(207, 187, 172);
    rect (0, 260, width, height-260);
    pop();
    
    ground();

	updateAndDisplayCacti();
	cactusAdd();

	updateAndDisplayCam();
    camAdd();
    camDisplay();

    updateAndDisplayClouds();
	cloudAdd();
    
}

function ground() {
	// background
    push();
    beginShape(); 
    noStroke();
	fill(200, 164, 140); 
    for (var x = 0; x < width; x++) {
        var t = (x * backdetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 200, height-50);
        vertex(0,480);
        vertex(480,480);
        vertex(x, y); 
    }
    endShape();
    pop();

    // foreground
	push();
    beginShape(); 
    noStroke();
	fill(181, 121, 78); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 270, height);
        vertex(0,480);
        vertex(480,480);
        vertex(x, y); 
    }
    endShape();
    pop();
}

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


function cloudAdd() {
    // With a very tiny probability, add a new cloud to the end.
    var newcloudLikelihood = 0.02; 
    if (random(0,1) < newcloudLikelihood) {
        clouds.push(makeCloud(width));
    }
}

// moving the clouds
function cloudMove() {
    this.x += this.speed;

}
    
// drawing the clouds
function cloudDisplay() {
	push();
	translate(this.x, 50);
	noStroke();
	if (this.z < 30) {
		fill(225, 210, 192);
	}

	if (this.z > 30 & this.z < 50) {
		fill(222, 202, 182);
	}
	if (this.z > 50) {
		fill(218, 194, 174);
	}
	
	rect(23+this.x, 50+this.z, 100+this.l, 25+this.h, 200, 200, 200, 200);
	rect(60+this.x, 25+this.z, 50, 50, 200, 200, 200, 200);
	rect(50+this.x, 35+this.z, 30, 30, 200, 200, 200, 200);
	pop();

}

// making the clouds
function makeCloud(cx) {
    var cloud = {x: cx,
    			z: random(0, 150),
    			l: random(0,20),
    			h: random(0,20),
 				speed: -1.0,
                move: cloudMove,
                display: cloudDisplay
            }
    return cloud;
}

// CACTUS
function updateAndDisplayCacti(){
    // Update the cacti positions, and display them.
    for (var i = 0; i < cacti.length; i++){
        cacti[i].tmove();
        cacti[i].tdisplay();
    }
}

function cactusAdd() {
    // With a very tiny probability, add a new cactus to the end.
    var newcactusLikelihood = 0.02; 
    if (random(0,0.5) < newcactusLikelihood) {
        cacti.push(makeCactus(width));
    }
}

// moving the cactus
function cactusMove() {
    this.mx += this.mspeed;

}

// draw the cactus
function cactusDisplay() {
    push();
    noStroke();
    translate(this.mx, 200);
    fill(131-this.cr, 170, 124-this.cr);
    rect(50+this.mx,50+this.cacter,25+this.wid, 90+this.hei, 200, 200, 0,0);
    rect(50+this.mx+this.wid,80+this.cacter,40,10,200,200,200,200);
    rect(80+this.mx+this.wid,60+this.cacter,10,30,200,200,200,200);
    rect(30+this.mx,90+this.cacter,40,10,200,200,200,200);
    rect(30+this.mx,70+this.cacter,10,30,200,200,200,200);
    pop();
}

// making the cacti
function makeCactus(tx) {
    var cactus = {mx: tx,
 				mspeed: -2.5,
 				hei: random(-10,20), // tallness of main cactus body
 				wid: random(0,5), // fatness of main cactus body
 				cr: random(0,50), // color 
 				cacter: random(70, 180), // y value
                tmove: cactusMove,
                tdisplay: cactusDisplay
            }
    return cactus;
}

// CAMEL
function updateAndDisplayCam(){
    // Update the camel positions, and display them.
    for (var i = 0; i < cam.length; i++){
        cam[i].cmove();
        cam[i].cdisplay();
    }
}

function camAdd() {
    // With a very tiny probability, add a new camel to the end.
    var newcamLikelihood = 0.02; 
    if (random(0,1) < newcamLikelihood) {
        cam.push(makeCam(width));
    }
}

// moving the camel
function camMove() {
    this.camx += this.cspeed;

}

function camDisplay() {
    push();
    noStroke();
    scale(0.3);
    for (var i = 0; i < 10; i++) {
    var num = frameCount % 8;
        image(camelfr[num],600, 900);
    }
    pop();
}

// making the camel
function makeCam(ax) {
    var camel = {camx: ax,
 				cspeed: -1.0,
                cmove: cactusMove,
                cdisplay: cactusDisplay
            }
    return camel;
}

I had a lot of fun working on this project. I wanted to create a desert landscape, so I selected colors from an image of the grand canyon. I made the background sort of have a gradient to give more of a “never ending stretch of land” horizon line feeling. The cactuses were a fun addition that I created in p5.js before realizing that I could’ve made them in illustrator and uploaded them as image files. Upon realization, I decided to add the moving camel. The original gif is from here, but I took each frame and edited it in illustrator to make it look more uniform in my code.

mmiller5-Project-10

Don’t (or maybe do) get hit by the barrels!  Press any key to jump.

sketch

var clouds = [];
var barrels = [];
var ground = 320;
var character;
var spaceship = [];
var drop = [];
var gravity = .5;
var count = 0; //keeps track of time since last barrel was made
var ouch = 0; //opacity for Ouch! text

function setup() {
    createCanvas(480, 480);
    frameRate(48);
    strokeWeight(0);
    character = makeCharacter();
    textAlign(CENTER);
    initialClouds();
}

function draw() {
    makeCharacter()
    background(0, 100, 200);
    //cloud stuff
    stepClouds();
    removeClouds();
    addClouds();
    //ground
    midground();
    //spaceship barrel drop stuff
    stepDrop();
    removeDrop();
    //more ground
    closerMidground();
    fill(50, 35, 35);
    rect(0, ground, width, height - ground);
    //character stuff
    stepCharacter();
     //barrel stuff
    stepBarrels();
    removeBarrels();
    addBarrels();
    //spaceship stuff
    stepSpaceship();
    removeSpaceship();
    addSpaceship();
    //extra stuff
    hit();
    count += 1;
}

//cloudy-related stuff
function makeCloud() {
    var cloud = {x: width + 50,
		 y: 80 + random(-50, 50),
		 scale: random(.8, 1.5),
		 tufts: floor(random(1, 7)),//chooses how many parts in cloud
		 tuftX: [random(-15, 15), random(-15, 15), random(-15, 15),
			 random(-15, 15), random(-15, 15), random(-15, 15),
			 random(-15, 15)], //parts in cloud have random location  
		 tuftY: [random(-15, 15), random(-15, 15), random(-15, 15),
			 random(-15, 15), random(-15, 15), random(-15, 15),
			 random(-15, 15)],
		 speed: -.2,
		 move: cloudMove,
		 appearance: cloudAppearance}
    return cloud;
}

function initialClouds() { //make clouds when script starts
    for (var i = 0; i < random(5, 12); i ++) {
	clouds.push(makeCloud());
	clouds[i].x = random(width);
    }
}

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

function cloudAppearance() {
    fill(240, 100);
    strokeWeight(0);
    for(var i = 0; i < this.tufts; i ++) {
	rect(this.x + this.tuftX[i], this.y + this.tuftY[i],
	     40 * this.scale, 20 * this.scale, 5 * this.scale);
    }
}

function stepClouds() { //updates the cloud features to redraw them
    for (var i = 0; i < clouds.length; i ++) {
	clouds[i].move();
	clouds[i].appearance();
    }
}

function addClouds() { //spawns new clouds randomly
    if (clouds.length <= 15 & random(0, 1) < .01) {
	clouds.push(makeCloud());
    }
}

function removeClouds() { //gets rid of clouds when off screen
    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i ++) {
	if (clouds[i].x + (40 * clouds[i].scale) + 15 > 0) {
	    cloudsToKeep.push(clouds[i]);
	}
    }
    clouds = cloudsToKeep;
}

//character stuff
function makeCharacter() {
    var character = {x: 50,
		     y: ground - 10,
		     yf: 0,
		     width: 10,
		     height: 10,
		     color: color(0),
		     jump: false,
		     move: characterJump,
		     appearance: characterAppearance,
		     collision: collision}
    return character;
}

function characterJump() { //makes character move up and down when a key is pressed
    if (this.jump == true) {
	this.yf += gravity;
    }
    this.y += this.yf;
    this.y = min(this.y, ground - this.height);
    if (this.y == ground - this.height) {
	this.jump = false;
    }
    if (keyIsPressed == true & this.jump == false) {
	this.jump = true;
	this.yf -= 10;
    }
}

function characterAppearance() {
    fill(this.color);
    strokeWeight(1);
    stroke(0, 150);
    rect(this.x, this.y, this.width, this.height);
}

function stepCharacter() {
    character.move();
    character.appearance();
    character.collision();
}

function collision() { //when character hits a barrel, change color and say Ouch!
    for (var i = 0; i < barrels.length; i ++) {
	if (dist(this.x, this.y,
		 barrels[i].x, barrels[i].y) <= barrels[i].radius ||
	    dist(this.x + this.width, this.y,
		 barrels[i].x, barrels[i].y) <= barrels[i].radius ||
	    dist(this.x, this.y + this.height,
		 barrels[i].x, barrels[i].y) <= barrels[i].radius ||
	    dist(this.x + this.width, this.y + this.height,
		 barrels[i].x, barrels[i].y) <= barrels[i].radius) {
	    this.color = barrels[i].color;
	    barrelHit(i);
	    
	}	    
    }
}

//barrel stuff
function makeBarrel() {
    var barrel = {x: width + 50,
		  y: ground - random(50, 150),
		  ySpeed: 0,
		  xSpeed: -3,
		  radius: 10,
		  color: color(random(0, 150), random(0, 150), random(0, 150)),
		  move: barrelMove,
		  appearance: barrelAppearance}
    return barrel;
}

function barrelMove() {
    this.x += this.xSpeed;
    this.y += this.ySpeed;
    this.y = min(ground - 10, this.y);
    this.ySpeed += gravity;
    if (this.y == ground - 10) {
	this.ySpeed = -this.ySpeed * .82;
    }
}

function barrelAppearance() {
    fill(this.color);
    strokeWeight(1);
    stroke(0, 150);
    ellipse(this.x, this.y, this.radius * 2, this.radius * 2);
}

function stepBarrels() {
    for (var i = 0; i < barrels.length; i ++) {
	barrels[i].move();
	barrels[i].appearance();
    }
}

function addBarrels() {
    if (random(0, 1) < .01 & count >= 48/*prevents from being too close*/) { 
	barrels.push(makeBarrel());
	count = 0;
    }
}

function removeBarrels() {
    var barrelsToKeep = [];
    for (var i = 0; i < barrels.length; i ++) {
	if (barrels[i].x + 10 > 0) {
	    barrelsToKeep.push(barrels[i]);
	}
    }
    barrels = barrelsToKeep;
}

function barrelHit(index) { //deletes hit barrels and says Ouch!
    var barrelsToKeep = [];
    for (var i = 0; i < barrels.length; i ++) {
	if (i != index) {
	    barrelsToKeep.push(barrels[i]);
	}
    }
    barrels = barrelsToKeep;
    ouch = 255; //sets opacity for Ouch! to be visible
}

function hit() { //displays Ouch!
    fill(255, 0, 0, ouch);
    strokeWeight(0);
    textSize(100);
    text("Ouch!", 60, 100, width - 100, 200);
    ouch -= 5;
}

//landscape elements
function midground() { //makes ground randomly according to noise
    var terrainSpeed = 0.00005;
    var terrainDetail = 0.005;
    fill(50);
    strokeWeight(0);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, height / 4, ground);
        vertex(x, y); 
    }
    vertex(width, height);
    endShape();
}

function closerMidground() { //makes ground randomly according to noise
    var terrainSpeed = 0.0007;
    var terrainDetail = 0.05;
    fill(50, 80, 50);
    strokeWeight(0);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (100000 + millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, height / 2, ground);
        vertex(x, y); 
    }
    vertex(width, height);
    endShape();
}

//spaceship
function makeSpaceship() {
    var spaceship = {x: -50,
		     y: random(50, 150),
		     speed: 0,
		     speedBoost: random(0, 500),
		     move: spaceshipMove,
		     appearance: spaceshipAppearance}
    return spaceship;
}

function spaceshipMove() {
    //movement speeds up and slows down according to noise
    this.x += this.speed + .5 * (noise(millis() * .001 + this.speedBoost));
}

function spaceshipAppearance() {
    strokeWeight(1);
    fill(255, 200);
    ellipse(this.x + 25, this.y - 5, 15, 15);
    fill(150);
    ellipse(this.x + 25, this.y, 50, 10);
}

function stepSpaceship() {
    for (var i = 0; i < spaceship.length; i ++) {
	spaceship[i].move();
	spaceship[i].appearance();
	addDrop(i); //spawns in barrel drops from ship
    }
}

function addSpaceship() {
    if (random(0, 1) < .0009 - (spaceship.length * .0003)) {
	spaceship.push(makeSpaceship());
    }
}

function removeSpaceship() {
    var spaceshipToKeep = [];
    for (var i = 0; i < spaceship.length; i ++) {
	if (spaceship[i].x - 25 < width) {
	    spaceshipToKeep.push(spaceship[i]);
	}
    }
    spaceship = spaceshipToKeep;
}

//spaceship barrel drop
function makeDrop(i) {
    var drop = {x: spaceship[i].x + 27, //spawns at spaceship location
		y: spaceship[i].y,
		ySpeed: 0,
		color: color(random(0, 160), random(0, 160), random(0, 160)),
		radius: 3,
		move: dropMove,
		appearance: dropAppearance}
    return drop;
}

function dropMove() {
    this.y += this.ySpeed;
    this.ySpeed += gravity / 5;
}

function dropAppearance() {
    fill(this.color);
    strokeWeight(.5);
    stroke(0, 150);
    ellipse(this.x, this.y, this.radius * 2, this.radius * 2);
}

function stepDrop() {
    for (var i = 0; i < drop.length; i ++) {
	drop[i].move();
	drop[i].appearance();
    }
}

function addDrop(i) {
    if (random(0, 1) < .01) {
	drop.push(makeDrop(i));
    }
}

function removeDrop() {
    var dropToKeep = [];
    for (var i = 0; i < drop.length; i ++) {
	if (drop[i].y < ground) {
	    dropToKeep.push(drop[i]);
	}
    }
    drop = dropToKeep;
}

When thinking of generative landscapes, I started thinking about side-scrolling games, and so I decided to combine the two!  Most of the objects are pretty basic — stuff gets introduced and moves across the screen — so I decided to add some complexity to each of the objects, giving them things like different numbers of components, bouncing, and spawning new objects.  The part of this project I personally love the most is that when the character gets hit by a barrel, they become the same color as that barrel!  I just think that’s so neat (and it’s also kinda sad, because clearly getting hit by the barrel hurts, but it’s so cool to watch!).

hyt-Project-10: Generative Landscape

hyt-10-project

// helen tsui
// 15-104 section d
// hyt@andrew.cmu.edu
// project-10-Generative-Landscape

var frames = [];
var framesIndex = 0;
var dino = [];

var terrainSpeed = 0.001;
var terrainDetail = 0.005;

var SkySpeed = 0.0003;
var SkyDetail = 0.01;

var t; // terrain in for loop
var y; // terrain y coordinate



function preload() {
    var filenames = [];
    filenames[0] = "https://i.imgur.com/nNc7b23.png";
    filenames[1] = "https://i.imgur.com/XMA7PM4.png";
    filenames[2] = "https://i.imgur.com/kN7pKft.png";
    filenames[3] = "https://i.imgur.com/0BpdBta.png";
    filenames[4] = "https://i.imgur.com/FZ6hBbP.png";
    for (var i = 0; i < filenames.length; i++) {
        frames[i] = loadImage(filenames[i]); 
    }
}

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

    for (var i = 0; i < 5; i++) {
        var rx = random(width);
        dino[i] = makeDinosaur(rx);
    }
}    


function makeStar() {
    stroke(200, 0, 0);
    strokeWeight(8);
    var starx = random(0, width);
    var stary = random(0, height);
    line(starx, stary, starx + 7, stary + 7);
}

// function makeStar2() {
//     stroke(200, 0, 0);
//     strokeWeight(8);
//     var starx2 = random(0, width);
//     var stary2 = random(0, height);
//     line(starx2, stary2, starx2 + 7, stary2 + 7);
// }

// background desert
    
// foreground - terrain that changes color
function makeTerrain() {
    noFill();
    noStroke();
    beginShape(); 
    for (var x = 0; x < width; x++) {
        t = (x * terrainDetail) + (millis() * terrainSpeed);
        y = map(noise(t), 0, 1, 150, height);
        vertex(x, y); 
        stroke(200-frameCount*0.5, 141, 103);
        line(x, y, x, height);
    }
    endShape();
}

// background - make sky 
function makeSky() {
    noFill();
    noStroke();
    beginShape(); 
    for (var x = 0; x < width; x++) {
        t = (x * SkyDetail) + (millis() * SkySpeed);
        y = map(noise(t), 0, 1, 0, 200);
        vertex(x, y); 
        stroke(219, 239, 240, 200, 200); // sky color
        line(x, 0, x, y);
    }
    endShape();
}



// making an object - dinosaur
function makeDinosaur(birthPos) { 
    var dino = {x: birthPos, 
                speed: 1,
                display: displayDinosaur,
                move: moveDinosaur
                }
    return dino;
}

// create dinosaur movement by using frames[]
function displayDinosaur() {
    push();
    scale(0.5);
    //makeDinosaur();
    framesIndex = frameCount % 4; // frameIndex keeps track with the framecount
    image(frames[framesIndex], t, y + 100);
    pop();
}

// give dinosaur speed
function moveDinosaur() {
    this.x += this.speed;
}

function AddNewDinosaur() { 
// With a very tiny probability, add new dinosaur to the end
    var newDinoLikelihood = 0.7; 
    if (random(0,1) < newDinoLikelihood) {
        dino.push(makeDinosaur(width));
    }
}

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

// call function
function draw() {
    background(236, 163, 130, 200);
    makeTerrain();
    makeSky();
    makeStar();
    makeStar();
    UpdateAndDisplayDinosaur();
        AddNewDinosaur();
        displayDinosaur();
}




For this project, I had a concept of creating animation-like short clip of running away, and therefore I captured a GIF from found source and broken into five different images, and then created the foreground and background using the noise() function, and the different dimensions have a changing gradient and opacity based off of the frameCount. Unfortunately the results were not as good as I expected, and I struggled a bit to figure out the objects’ properties and creating the constant movement. Below is a sketch that I have, and I hope to make some other alterations more as I delve more into the concepts.