//Jasmine Lee
//jasmine4@andrew.cmu.edu
//Section C
//Project 11 (Generative Landscape)
var waterSpeed = 0.0002;
var waterDetailL1 = 0.0005; //controls amplitude of left side of waterfall
var waterDetailL2 = 0.0001;
var waterDetailL3 = 0.00025;
var waterDetailL4 = 0.00075;
var waterDetailR1 = 0.0001; //controls amplitude of right side of waterfall
var waterDetailR2 = 0.00025;
var waterDetailR3 = 0.0005;
var waterDetailR4 = 0.00075;
var waterDetailH1 = 0.0005; //controls amplitude of horizontal waves
var waterDetailH2 = 0.00095;
var waterDetailH3 = 0.00075;
var fish = [];
var newFishLikelihood = 2.9;
function setup() {
createCanvas(480, 480);
frameRate(20);
//makes fish and places them in random x and y positions
for (var i = 0; i < 8; i ++) {
fish.push(makeFish(floor(random(240, 480)), floor(random(300, 360))));
}
//displays the fish properly
for (var i = 0; i < fish.length; i ++) {
updateAndDisplayFish();
}
}
function draw() {
background(138, 212, 227); //teal
noFill();
stroke(255, 255, 255, 100); //transparent white
//LEFT SIDE OF WATERFALL---------------------------------------------
//1st line of waterfall
for (var y = 0; y < 240; y++) {
//t determines how far away the line is from x = 0 at y
//millis() * waterSpeed slows down how fast the line is traveling)
var t = ((y * waterDetailL1) + millis() * waterSpeed);
var x = map(noise(t), 0, 1, 0, 220);
line(x, y, (t - width), y);
}
//2nd line of waterfall
for (var y = 0; y < 240; y++) {
var t = ((y * waterDetailL2) + millis() * waterSpeed);
var x = map(noise(t), 0, 1, 10, 235);
line(x, y, (t - width), y);
}
//3rd line of waterfall
for (var y = 0; y < 240; y++) {
var t = ((y * waterDetailL3) + millis() * waterSpeed);
var x = map(noise(t), 0, 1, 20, 250);
line(x, y, (t - width), y);
}
//4th line of waterfall
for (var y = 0; y < 240; y++) {
var t = ((y * waterDetailL4) + millis() * waterSpeed);
var x = map(noise(t), 0, 1, 50, 220);
line(x, y, (t - width), y);
}
//RIGHT SIDE OF WATERFALL---------------------------------------------
//1st line of waterfall
for (var a = 0; a < 240; a ++) {
//c gives us how far away the line is from x = 0 at y
//millis() * waterSpeed slows down how fast the line is traveling)
var c = ((a * waterDetailR1) + millis() * waterSpeed);
var b = map(noise(c), 0, 1, 240, 480);
line(b, a, ((width + 60) - c), a);
}
//2nd line of waterfall
for (var a = 0; a < 240; a ++) {
var c = ((a * waterDetailR2) + millis() * waterSpeed);
var b = map(noise(c), 0, 1, 220, 480);
line(b, a, ((width + 60) - c), a);
}
//3rd line of waterfall
for (var a = 0; a < 240; a ++) {
var c = ((a * waterDetailR3) + millis() * waterSpeed);
var b = map(noise(c), 0, 1, 200, 480);
line(b, a, ((width + 60) - c), a);
}
//4th line of waterfall
for (var a = 0; a < 240; a ++) {
var c = ((a * waterDetailR4) + millis() * waterSpeed);
var b = map(noise(c), 0, 1, 300, 480);
line(b, a, ((width + 60) - c), a);
}
//HORIZONTAL WAVES--------------------------------------------
noFill();
stroke(41, 152, 217, 100);
//1st wave
for (var x = 0; x < width; x ++) {
//c gives us how far away the line is from x = 0 at y
//millis() * waterSpeed slows down how fast the line is traveling)
var t = ((x * waterDetailH1) + millis() * waterSpeed);
var y = map(noise(t), 0, 1, 210, 240);
line(x, y, x, height);
}
//2nd wave
for (var x = 0; x < width; x ++) {
var t = ((x * waterDetailH2) + millis() * waterSpeed);
var y = map(noise(t), 0, 1, 220, 250);
line(x, y, x, height);
}
//3rd wave
for (var x = 0; x < width; x ++) {
var t = ((x * waterDetailH3) + millis() * waterSpeed);
var y = map(noise(t), 0, 1, 240, 300);
line(x, y, x, height);
}
//functions used to display and control the fish
updateAndDisplayFish();
removeFish();
}
function updateAndDisplayFish() {
//update the fish position and display
for (var i = 0; i < fish.length; i ++) {
fish[i].move();
fish[i].displayF();
}
}
function removeFish() {
//Copy all fish we want to keep into a new array
var fishToKeep = [];
for (var i = 0; i < fish.length; i++) {
if (fish[i].x + fish[i].fishWidth > 0) {
fishToKeep.push(fish[i]);
}
}
fish = fishToKeep; //stores the surviving fish
}
function fishMove() {
//controls fish movement
this.x += this.speed;
//makes fish start back at right end of canvas once they reach the left
if (this.x < 0) {
this.x = width;
}
}
function fishDisplay() {
//fish body
fill(237, 175, 69, 100); //fish body
noStroke();
ellipse(this.x, this.y, this.fishWidth, this.fishHeight);
//fish tail
triangle(this.x + (this.fishWidth / 2) , this.y, this.x + 20, this.y + 5, this.x + 20, this.y - 5);
}
//creates fish object
function makeFish(birthLocationX, birthLocationY) {
var fs = {x: birthLocationX,
y: birthLocationY,
fishWidth: random(15, 30),
speed: -2.0,
fishHeight: random(7, 10),
move: fishMove,
displayF: fishDisplay}
return fs;
}
For my landscape, I wanted to depict a peaceful waterfall scene. Using different noise functions, I was able to create gently flowing water, and subtle waves. The fish in the freshwater loop continuously, as if they were swimming around in the water and looping back where we could not see them turn. The most difficult part was this project was creating the objects. I had trouble with getting the correct amount of fish to show up, and with keeping the fish on the page. Over time, the waterfall changes position until it seems as if there are two waterfalls. Each time the landscape is refreshed, the fish sizes and positions are randomized.