thlai-Project-10-Landscape

Generative Landscape

I struggled a lot with this project. There were so many little things I wanted to do but didn’t know how to execute. I wanted to create a calming lake and mountains landscape with the sun in the background and used a purple color scheme and gradients to achieve this. The starter code helped me a lot with the clouds.  The most difficult part, I think, was creating the reflections in the water – I used the noise() function to create them and used a similar code to the mountains. In the end, I used fog image to spice things up and create atmosphere.

sketch

// Tiffany Lai
// 15-104, Section A
// thlai@andrew.cmu.edu
// Project 10 - Landsape

var clouds = []; // array for clouds
var waterX = []; // array for x position of reflection lines
var waterY = []; // array for y position of reflection lines
var speed1 = 0.0002; // for mountain1
var peaks1 = 0.03; // for mountain1
var speed2 = 0.0005; // for mountain2
var peaks2 = 0.03; // for mountain2
var boatX = 250; // x coordinates of boat
var img; // variable to store fog filter

function preload() {
	img = loadImage("https://i.imgur.com/aoZ4YwF.png"); // fog image
}

function setup() {
	createCanvas(480, 480);
	// initial collection of clouds
	for (var i = 0; i < 5; i++) {
		var rx = random(width);
		clouds[i] = makeClouds(rx);
	}
	for (var i = 0; i < 50; i++) {
		var sparkleX = random(0, width);
		var sparkleY = random(height * 2 / 3, height);
		waterX.push(sparkleX);
		waterY.push(sparkleY);
	}
}

function draw() {
	var num = height; // number of lines for gradient bg
	// gradient background
	for (var i = 0; i < num; i++) {
		strokeWeight(2);
		stroke(100 + 1.2 * i, 50 + i, 100 + 0.7 * i);
		line(0, i, width, i);
	}
	sun(); // draw sun
	updateClouds(); // update and display clouds
	removeClouds(); // remove clouds that have slippsed out of view
	addClouds(); // add new clouds with random probability
	mountain1(); // draw first mountains
	mountain2(); // draw second mountains
	water(); // draw water and reflections
	boat(boatX); // draw boat
	boatX -= 0.5; // boat speed
	if (boatX < -50) { // if boat exits left, make it come in right
		boatX = width;
	}
	image(img, 0, 0, width, height); // load fog
}

function sun() { // sun and rays
	noStroke();
	fill(255, 200);
	ellipse(width / 3, height / 3, 170, 170); // sun
	for (var i = 0; i < 55; i++) { // sun rays
		strokeWeight(1);
		stroke(color(220 + 2 * i, 120 + i, 130 + 1 * i, 100)); // gradient
		noFill();
		ellipse(width / 3, height / 3, 170 + i * i * 0.2, 170 + i * i * 0.2); // distance between circles
	}
}

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

function removeClouds() {
	var keepClouds = [];
	for (var i = 0; i < clouds.length; i++) {
		if (clouds[i].x + clouds[i].breadth > 0) {
			keepClouds.push(clouds[i]);
		}
	}
	clouds = keepClouds;
}

function addClouds() {
	// probability of cloud appearing
	var cloudChance = 0.007;
	if (random(0, 1) < cloudChance) {
		clouds.push(makeClouds(width));
	}
}

function moveClouds() { // speed of clouds
	this.x += this.speed;
}

function displayClouds() {
	fill(255, 50);
	noStroke();
	ellipse(this.x, this.y, this.width, this.height);
	ellipse(this.x + 10, this.y + 10, this.width - 10, this.height - 10);
	ellipse(this.x + 20, this.y - 10, this.width / 2, this.height / 2);
	ellipse(this.x - 20, this.y, this.width - 20, this.height - 10);
}

function makeClouds(cloudX) {
	var cloud = {
		x: cloudX,
		y: random(0, height / 2 - 100),
		speed: random(-1, -0.1),
		width: random(40, 100),
		height: random(20, 50),
		breadth: 50,
		move: moveClouds,
		display: displayClouds,
	}
	return cloud;
}

function mountain1() { // background mountains
	noStroke();
	fill(135, 86, 110);
	beginShape();
	for (var x = 0; x < width; x++) {
		var t = (x * peaks1) + (millis() * speed1);
		var y = map(noise(t), 0, 1, height / 5, height / 2);
		vertex(x, y);
	}
	vertex(width, height);
	vertex(0, height);
	endShape();
}

function mountain2() { // middleground mountains
	// noStroke();
	stroke(70, 63, 86);
	strokeWeight(1);
	// beginShape();
	for (var x = 0; x < width; x++) {
		var t = (x * peaks2) + (millis() * speed2);
		var y = map(noise(t), 0, 2, height / 2, height / 3);
		line(x, 330 + y / 2, x, 330 - y / 2);
	}
}

function water() { // water and reflections
	noStroke();
	fill(170, 120, 126, 100);
	rect(0, height - height / 3, width, height);

	for (var i = 0; i < 15; i++) {
		var t = (i * peaks2) + (millis() * speed2);
		var widthChange = (map(noise(t), 0, 1, 0, 100));
		stroke(255, 70);
		line(waterX[i] - widthChange, waterY[i], waterX[i] + widthChange, waterY[i]);
	}
}

function boat(boatX) { // make boat
	noStroke();
	fill(50, 43, 76);
	triangle(boatX + 31, 367, boatX + 31, 393, boatX + 16, 393);
	triangle(boatX + 33, 374, boatX + 34, 393, boatX + 47, 393);
	quad(boatX + 15, 396, boatX + 23, 405, boatX + 40, 405, boatX + 47, 396);

	stroke(255, 50);
	line(boatX + 15, 405, boatX + 45, 405);
}

Leave a Reply