(The illustration file wasn’t loading properly so I had to embed it twice!)
Since Nintendo recently announced that Hyrule Warriors: Age of Calamity is coming out soon, I decided to create a clock inspired by The Legend of Zelda’s Breath of the Wild. The sky changes color depending on the hour, the clouds move across the sky every minute, and pink sparkles appear every second.
breath of the wild
var dusk;
var dawn;
var sparkleX = [];
var sparkleY = [];
var randomW = [];
var randomH = [];
let yPerl = 0.0;
function preload() {
mySon = loadImage("link_illustration.png");
}
function setup() {
createCanvas(480, 300);
//angleMode(DEGREES);
greenDusk = color(162, 219, 202); //dusk sky color
yellowDawn = color(252, 246, 211); //dawn sky color
mountainColor = color(56, 116, 150); //color of the mountains
cloudColor = color(225, 223, 184); //colod of the clouds
ledgeColor = color(19, 68, 97); //color of Link's ledge
ledgeShadow = color(4, 42, 50, 75); //color of ledge shadow
hyrulePink = color(255, 145, 203); //color of the sparkles
lerpValue = 0;
dusk = "nightfall";
dawn = "daybreak";
sunlight = "sunrise";
moonlight = "twilight";
//sparkles
for (i = 0; i < 60; i++) {
sparkleX[i] = random(width);
sparkleY[i] = random(175, 300);
randomW[i] = random(3, 6);
randomH[i] = random(3, 6);
}
}
function draw() {
background(0);
noStroke();
sky(); //sky incremently changes color based on hour
push(); //clouds move across sky based on minute
var m = minute();
driftingCloud = map(m, 0, 60, 0, width);
translate(driftingCloud, 0);
clouds();
pop();
mountains(); //randomly generated mountains
castle(); //castle in the distance
//sparkles in the horizon
fill(hyrulePink);
for (i = 0; i < second(); i++) {
rect(sparkleX[i], sparkleY[i], randomW[i], randomH[i]);
}
//ledge that Link stands on
ledge();
//illustration of Link
scale(0.2);
image(mySon, 1100, 350);
}
//sky incremently changes color each hour
function sky() {
var h = hour();
if (dawn === "daybreak") {
lerpValue = map(h, 23, 0, 0, 1);
}
else {
lerpValue = map(h, 0, 23, 0, 1);
}
if (h < 12) {
lerpValue = map(h, 0, 11.5, 0, 1);
} else {
lerpValue = map(h, 11.5, 23, 1, 0);
}
var skyChange = lerpColor(greenDusk, yellowDawn, lerpValue);
fill(skyChange);
rect(0, 0, width, height);
}
//mountain horizon
function mountains() {
fill(mountainColor);
beginShape();
let xPerl = 0;
for (let x = 0; x <= width; x += 10){
let y = map(noise(xPerl), 0, 1, 150, 200);
vertex(x, y);
xPerl += 0.2;
}
yPerl += 0.2;
vertex(width, height);
vertex(0, height);
endShape(CLOSE);
}
//clouds based on minute
function clouds() {
fill(cloudColor);
var m = minute();
for (var c = 0; c <= m; c++) {
//top left middle cloud
push();
scale(0.75);
translate(0, -50);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
//middle cloud
push();
translate(150, -20);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
//top left small cloud
push();
scale(0.5);
translate(-70, -80);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
//bottom left large cloud
push();
scale(1.25);
translate(-90, -20);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
//top right cloud
push();
scale(0.75);
translate(320, -80);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
//top middle cloud
push();
scale(0.5);
translate(50, -110);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
//far left middle cloud
push();
translate(-250, -50);
beginShape();
curveVertex(0, 150);
curveVertex(10, 140);
curveVertex(25, 130);
curveVertex(45, 135);
curveVertex(70, 115);
curveVertex(100, 120);
curveVertex(140, 100);
curveVertex(190, 140);
curveVertex(210, 150);
endShape(CLOSE);
pop();
}
}
//ledge where Link is standing
function ledge() {
push();
fill(ledgeColor);
translate(width/1.8, height + 10);
beginShape();
vertex(-30, -50);
vertex(0, -90);
vertex(90, -85);
vertex(130, -40);
vertex(160, 50);
vertex(-60, 50);
endShape(CLOSE);
pop();
push();
fill(ledgeShadow);
translate(width/1.8, height + 10);
beginShape();
vertex(-10, -75);
vertex(0, -90);
vertex(90, -85);
vertex(130, -40);
vertex(160, 50);
endShape(CLOSE);
pop();
}
//castle in the horizon
function castle() {
fill(mountainColor);
rect(125, 110, 30, 100); //castle tower
rect(102, 150, 75, 100); //castle building
rect(90, 165, 100, 50); //castle ledge
rect(122.5, 125, 35, 10); //lower level of castle
triangle(120, 110, 140, 50, 160, 110); //main spire
triangle(100, 150, 107.5, 110, 115, 150); //left spire
triangle(165, 150, 172.5, 110, 180, 150); //right spire
triangle(85, 200, 92.5, 130, 100, 200); //bottom left spire
triangle(180, 200, 187.5, 130, 195, 200); //bottom right spire
//windows
fill(greenDusk);
rect(135, 110, 5, 10);
rect(130, 110, 2, 10);
rect(135, 140, 10, 10);
//jagged rocks from mountain
push();
fill(mountainColor);
rectMode(CENTER);
translate(450, 225);
rotate(PI/1.2);
rect(0, 0, 50, 250);
rotate(PI/4.0);
rect(415, -150, 40, 250);
rect(200, -50, 35, 250);
pop();
}