sketch
/*
* Eric Zhao
* ezhao2@andrew.cmu.edu
*
* Generative ladnscape
*
*/
var hillHeights = [];
var mountainHeights = [];
//arrays for foreground and background
var noiseParam = 0;
var noiseParam2 = 0;
var noiseStep = 0.01;
var numpoints = 80;
//bottom 4 used as placemarkers and attempts
//to make the hobbit holes not disappear on screen
var xInc;
var circleRad;
var breadth = 25;
var marginRatio = (numpoints+breadth)/numpoints;
function drawMountain(hill, numpoints){
//draws a perlin noise mountain
beginShape();
vertex(width - width*marginRatio, height);
vertex(width - width*marginRatio, height);
for(let i = -breadth; i <= numpoints+breadth; i++){
vertex(i * xInc, hill[i]);
}
vertex(width*marginRatio, height);
vertex(width*marginRatio, height);
endShape();
}
function stepMountain(param, step, hill, numpoints){
//generates array of perlin values used for mountain and trees
hill.shift();
for(let i = -breadth; i <= numpoints+breadth; i++){
var n = noise(param);
var value = map(n, 0, 1, 0, height);
hill.push(value);
param += step;
}
noiseParam = param;
}
function drawHole(circleRad){
//hobbit hole draw function
fill(22, 98, 71);
ellipse(0, 0, circleRad, circleRad);
fill(random(0, 360), 94, 25);
ellipse(0, 0, circleRad*0.8, circleRad*0.8);
stroke(0);
noFill();
for(var i = 0; i <= 8; i ++){
arc(0, 0, circleRad*0.8, circleRad*0.8, i*(PI/8), -i*(PI/8), CHORD);
}
fill(50, 80, 90);
ellipse(0, 0, max(10, circleRad*0.1), max(10, circleRad*0.1));
}
function setup() {
createCanvas(600, 400);
colorMode(HSB);
frameRate(30);
noStroke();
strokeWeight(2);
stepMountain(noiseParam, noiseStep, hillHeights);
}
function draw() {
xInc = width/numpoints;
background(183, 33, 95);
//draws background/dark green mountain
fill(120, 100, 20);
stepMountain(noiseParam2, 0.4, mountainHeights, 320)
drawMountain(mountainHeights, 320);
//draws foreground scenery
fill(110, 64, 52);
stepMountain(noiseParam, noiseStep, hillHeights, numpoints);
drawMountain(hillHeights, numpoints);
push();
translate(0, 20);
fill(42, 30, 90);
drawMountain(hillHeights, numpoints);
//at peaks of hill, add a hobbit hole
for(let i = -breadth; i <= numpoints+breadth; i++){
if(i != -breadth & i !=numpoints+breadth){
if (hillHeights[i] < hillHeights[i-1] &&
hillHeights[i] < hillHeights[i+1]){
push();
fill(0);
translate(i * xInc, (height + hillHeights[i])/2);
drawHole((height-hillHeights[i])/1.5);
pop();
}
}
}
pop();
}
My idea was to generate a rolling hill and place hobbit holes at random locations or peaks under the hill, with their basic shape looking something like this:
Unfortunately, I realized too late that the program I wrote didn’t utilize objects and made changing variables about the holes (ex. colors and varying designs) very difficult without restructuring the program significantly.