For my generative landscape, I chose to make a desert with different types of cacti whose sizes and colors are randomly generated. For the sand and hills in the back, I referenced the lab from week 7. While the sand keeps moving, the hills in the back are still but change every time the page is refreshed.
var cacti = [];
var canyons = [];
var sand = [];
var ball = [];
var noiseParam = 0;
var noiseStep = 0.02;
function setup() {
createCanvas(640, 240);
background(0);
/*// create an initial collection of buildings
for (var i = 0; i < 10; i++){
var rx = random(width);
buildings[i] = makeBuilding(rx);
}*/
frameRate(20);
//canyon values
for(var i = 0; i <= width/5; i++){
var n = noise(noiseParam);
canyons[i];
var value = map(n, 0, 1, 0, height);
canyons.push(value);
noiseParam += noiseStep;
}
//sand values
for(var i = 0; i <= width/5; i++){
var n = noise(noiseParam);
sand[i];
var value = map(n, 0, 1, 0, height/2);
sand.push(value);
noiseParam += 0.5*noiseStep;
}
}
function draw() {
//sunset gradient
var gradRed = color(190, 60, 38); // darker red color
var gradYellow = color(250, 185, 21); // yellow
for (var i = 0; i < height; i++){
var gradient = map (i, 0, (height/3)*1.5, 0, 1);
var bgColor = lerpColor(gradRed, gradYellow, gradient);
stroke(bgColor);
line(0, i, width, i);
}
// draw a setting sun
push();
noStroke();
fill(255, 226, 161);
circle(500, 110, 180);
pop();
drawCanyons();
drawSand();
// taller cacti
updateAndDisplayCacti();
removeCactiThatHaveSlippedOutOfView();
addNewCactiWithSomeRandomProbability();
updateAndDisplayBalls();
removeBallsThatHaveSlippedOutOfView();
addNewBallsWithSomeRandomProbability();
}
//draws background canyons (still)
function drawCanyons(){
// canyon values
var n = noise(noiseParam);
var value = map(n, 0, 1, 0, height);
noiseParam += noiseStep;
// draws shape for canyons
beginShape();
vertex(0, height);
for(var i = 0; i <= width/5; i++){
//filling the canyons with translucent brown
fill(178, 108, 55, 180);
noStroke();
//vertex function to fill the canyon
vertex((i * 5), canyons[i]);
vertex((i + 1) * 5, canyons[i + 1]);
}
vertex(width, height);
endShape(CLOSE);
}
// draws sand (moving)
function drawSand(){
push();
translate(0, 130)
sand.shift();
var n = noise(noiseParam);
var value = map(n, 0, 1, 0, height/2);
sand.push(value);
// draws shape for sand
beginShape();
vertex(0, height);
for(var i = 0; i <= width/5; i++){
//filling the sand color
fill(237, 197, 154);
noStroke();
//vertex function to fill the sand
vertex((i * 5), sand[i]);
vertex((i + 1) * 5, sand[i + 1]);
}
vertex(width, height);
endShape(CLOSE);
pop();
}
function updateAndDisplayCacti(){
// Update the building's positions, and display them.
for (var i = 0; i < cacti.length; i++){
cacti[i].move();
cacti[i].display();
}
}
function removeCactiThatHaveSlippedOutOfView(){
var cactiToKeep = [];
for (var i = 0; i < cacti.length; i++){
if (cacti[i].x + cacti[i].breadth > 0) {
cactiToKeep.push(cacti[i]);
}
}
cacti = cactiToKeep; // remember the surviving buildings
}
function addNewCactiWithSomeRandomProbability() {
// With a very tiny probability, add a new building to the end.
var newCactusLikelihood = 0.02;
if (random(0,1) < newCactusLikelihood) {
cacti.push(makeCactus(width));
}
}
// method to update position of cactus every frame
function cactusMove() {
this.x += this.speed;
}
//draw the cactus
function cactusDisplay() {
cacti.push();
strokeWeight(25);
stroke(this.color);
//main stalk
var y = 220;
line(this.x, this.cBottom, this.x, this.cBottom-this.cHeight)
strokeWeight(17);
stroke(204, 209, 135, 60);
line(this.x, this.cBottom, this.x, this.cBottom-this.cHeight)
// two stalks on side
strokeWeight(13);
stroke(this.color);
line(this.x-20, this.cBottom-this.s1Bottom, this.x-20, this.cBottom-this.s1Height);
// left stalk has a random height
line(this.x+20, this.cBottom-this.s2Bottom, this.x+20, this.cBottom-this.s2Height);
// right stalk has a random height
}
// makes taller cacti
function makeCactus(birthLocationX) {
var ccts = {x: birthLocationX,
breadth: 50,
speed: -4.5,
cHeight: random(30, 60), // height of cactus
cBottom: random(200, 225), // bottom of cactus
s1Height: random(20, 60), // top of the left stalk
s1Bottom: random(5, 20), // bottom of left stalk
s2Height: random(20, 60), // top of right stalk
s2Bottom: random(5, 20), // bottom of right stalk
color: color(random(40, 100), random(80, 200), 72), // varies shades of green
move: cactusMove,
display: cactusDisplay}
return ccts;
}
function addNewBallsWithSomeRandomProbability() {
// With a very tiny probability, add a new building to the end.
var newBallLikelihood = 0.02;
if (random(0,1) < newBallLikelihood) {
ball.push(makeBall(width));
}
}
function updateAndDisplayBalls(){
// Update the building's positions, and display them.
for (var i = 0; i < ball.length; i++){
ball[i].move();
ball[i].display();
}
}
function removeBallsThatHaveSlippedOutOfView(){
var ballsToKeep = [];
for (var i = 0; i < ball.length; i++){
if (ball[i].x + ball[i].breadth > 0) {
ballsToKeep.push(ball[i]);
}
}
ball = ballsToKeep; // remember the surviving buildings
}
function addNewBallWithSomeRandomProbability() {
// With a very tiny probability, add a new ball cactus to the end.
var newBallLikelihood = 0.02;
if (random(0,1) < newBallLikelihood) {
ball.push(makeBall(width));
}
}
// method to update position of ball shaped cactus every frame
function ballMove() {
this.x += this.speed;
}
// displays ball-shaped cacti
function ballDisplay(){
push();
noStroke();
fill(this.color);
ellipse(this.x, this.ey, this.ew, this.eh); // main ball cactus
fill(204, 209, 135, 60)
ellipse(this.x, this.ey, this.ew-5, this.eh-5); // highlight
fill(this.color);
ellipse(this.x, this.ey, this.ew-10, this.eh-10);
fill(251, 203, 188);
stroke(this.color);
strokeWeight(1);
ellipse(this.x, this.ey-(this.eh/2), 8, 5) // lil flower guy on top
pop();
}
// makes ball-shaped cacti
function makeBall(birthLocationX) {
var b = {x: birthLocationX,
breadth: 50,
speed: -4.5,
eh: random(20, 40), // height of ellipse
ey: random(200, 225), // y coord of ellipse
ew: random(20, 40), // width of ellipse
color: color(random(50, 150), 100, random(100, 200)), // varies shades of blue
move: ballMove,
display: ballDisplay}
return b;
}