var ruins = [];
var farRuins = [];
var fog = [];
var skyColor;
function setup() {
createCanvas(480,300);
angleMode(DEGREES);
for (var c = 0; c < 10; c++) {
// populate arrays
var ruinX = random(width);
var farRuinX = random(width);
ruins[c] = makeRuin(ruinX);
farRuins[c] = makeFarRuin(farRuinX);
for(var d = 0; d<2; d++){
var fogX = random(width);
fog[c] = makeFog(fogX);
}
}
skyColor = color(220, 233, 239);
}
function draw() {
background(skyColor);
sunDraw();
sunMove();
fill(210, 223, 229);
noStroke();
rect(0, 180, width, 120);
// draw the rest of the objects in the scene
for(var i = 0; i < farRuins.length; i++) {
farRuins[i].draw();
farRuins[i].move();
}
for(var i = 0; i < ruins.length; i++) {
ruins[i].draw();
ruins[i].move();
}
for(var i = 0; i < fog.length; i++) {
fog[i].draw();
fog[i].move();
}
}
// FOG
function fogDraw() {
push();
translate(this.xPos, this.yOffset);
stroke(255, 255, 255, 40);
strokeWeight(this.fHeight);
line(0, 0, this.fSize, 0);
pop();
}
// move objects across canvas, when they hit the edge
// move them back to the far edge with randomized attributes
function fogMove() {
this.xPos += this.speed;
if(this.xPos < 0 - this.fSize - 30) {
this.fHeight = random(10, 50);
this.fSize = random(30, 150);
this.xPos = width + this.fSize + random(-25, 25);
}
}
function makeFog() {
var fog = {xPos: random(width), //, width*4
speed: random(-0.4, -0.3),
fSize: random(30, 150),
fHeight: random(20, 60),
yOffset: random(50, height),
draw: fogDraw,
move: fogMove};
return fog;
}
// END FOG
// SUN
var sun = {xPos: 20, size: 20, speed:.1};
function sunDraw() {
var sunColor = color(234, 229, 228);
noStroke();
fill(252, 202, 191);
ellipse(sun.xPos, 60, sun.size);
// make a gradient, centered around the sun
for (var s = 0; s <= width; s += 5) {
var amt = map(s, 0, height, 0, 1);
var gradient = lerpColor(sunColor, skyColor, amt);
noFill();
stroke(gradient);
strokeWeight(5);
ellipse(sun.xPos, 60, sun.size + s);
}
}
function sunMove() {
sun.xPos += sun.speed;
if (sun.xPos > width + sun.size) {
sun.xPos = 0 - sun.size;
}
}
// END SUN
// RUINS
function ruinDraw(){
push();
translate(this.xPos - this.rWidth/2, height-40+this.yPosOffset);
noStroke();
fill(245, 245, 255);
beginShape();
vertex(0 + this.rWidth/2, 0 + this.yOffset);
vertex(0 - this.rWidth/2, 0 + this.yOffset);
vertex(0 - this.rWidth/2 - this.lean, -this.rHeight - this.spike1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight + this.valley1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight - this.spike2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight + this.valley2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight - this.spike2);
endShape(CLOSE);
// draw reflections
scale(1, -1);
fill(245, 245, 255, 60);
beginShape();
vertex(0 + this.rWidth/2, 0 - this.yOffset);
vertex(0 - this.rWidth/2, 0 - this.yOffset);
vertex(0 - this.rWidth/2 - this.lean, -this.rHeight - this.spike1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight + this.valley1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight - this.spike2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight + this.valley2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight - this.spike2);
endShape(CLOSE);
pop();
}
// move objects across canvas, when they hit the edge
// move them back to the far edge with randomized attributes
function ruinMove(){
this.xPos += this.speed;
if (this.xPos < 0 - this.rWidth) {
this.rHeight = random(15, 40);
this.rWidth = random(10, 60);
this.lean = random(0, 20);
this.xPos = width + this.rWidth + this.lean + random(-5, 50);
}
}
function makeRuin(x) {
var ruin = {xPos: x,
rHeight: random(15, 60),
rWidth: random(10, 80),
lean: random(0, 20),
spike1: random(0, 10),
valley1: random(0, 10),
spike2: random(0, 10),
valley2: random(0, 10),
spike3: random(0, 10),
valley3: random(0, 10),
yOffset: random(-5, 5),
yPosOffset: random(-15, 15),
speed: random(-.4, -.5),
draw: ruinDraw,
move: ruinMove}
return ruin;
}
// END RUINS
// FAR RUINS
function farRuinDraw(){
push();
translate(this.xPos - this.rWidth/2, height-90);
noStroke();
fill(233, 237, 244);
beginShape();
vertex(0 + this.rWidth/2, 0 + this.yOffset);
vertex(0 - this.rWidth/2, 0 + this.yOffset);
vertex(0 - this.rWidth/2 - this.lean, -this.rHeight - this.spike1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight + this.valley1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight - this.spike2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight + this.valley2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight - this.spike2);
endShape(CLOSE);
// draw reflections
fill(233, 237, 244, 60);
scale(1, -1);
beginShape();
vertex(0 + this.rWidth/2, 0 - this.yOffset);
vertex(0 - this.rWidth/2, 0 - this.yOffset);
vertex(0 - this.rWidth/2 - this.lean, -this.rHeight - this.spike1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight + this.valley1);
vertex(0 - this.rWidth/2 + this.valley1, -this.rHeight - this.spike2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight + this.valley2);
vertex(0 - this.rWidth/2 + this.valley1 + this.valley2, -this.rHeight - this.spike2);
endShape(CLOSE);
pop();
}
// move objects across canvas, when they hit the edge
// move them back to the far edge with randomized attributes
function farRuinMove(){
this.xPos += this.speed;
if (this.xPos < 0 - this.rWidth) {
this.rHeight = random(50, 100);
this.rWidth = random(40, 100);
this.lean = random(0, 50);
this.xPos = width + this.rWidth + this.lean + random(-5, 50);
}
}
function makeFarRuin(x) {
var farRuin = {xPos: x,
rHeight: random(50, 100),
rWidth: random(40, 100),
lean: random(0, 50),
spike1: random(0, 10),
valley1: random(0, 10),
spike2: random(0, 10),
valley2: random(0, 10),
spike3: random(0, 10),
valley3: random(0, 10),
yOffset: random(-15, 15),
speed: random(-.4, -.2),
draw: farRuinDraw,
move: farRuinMove}
return farRuin;
}
// END FAR RUINS
I wanted to create a landscape that had something to do with water, and ended up going with icebergs or jagged ruins drifting through a pale sea. The size and shape of the icebergs are all randomly determined, as are the fog clouds. I had also wanted to extra “surprise” elements to the landscape (a sunken ship, and a glimpse of a sea serpent) but I ran out of time and wasn’t able to implement them the way I had planned.