I had started out wanting to do a sunset, with the view of a car driving by it. I didn’t want to create a jagged moving landscape, so I decided to do a desert instead. I was first going to make cactuses, but then I made the ground black and realized I wanted a more futuristic look. So I decided my image would have the sunset, black ground, and then geometric shapes with their shadows. Because I had used the bezier() function in the past, I decided to use that for the sunset, having the anchor parts react with the sun, almost like the sky was melting.
During the project I changed my objects from pyramids to stars to, finally, sailboats. I added to the black water horizon, putting color lines under the sun to look like a water reflection, and adding vertical lines to the water with an invisible ball pushing them to look like the boats were pushing the current.
var quarW = 120;//width divided by 4
var quarW2 = 360;//qaurW times 3
var bezH = 40;//height of bezier anchors
var bezW = 48;//width of ground bezier anchors
var bezWS = 48;//width of ground bezier side points
var sunX = 240;//x value placement of sun in sky
var sunH = 100;//height of sun in sky
var currX = 480;//x placement of horizontal circle
var bzHorLn1 = 360;//horizon line of the bezier anchors
var bzHorLn2 = 360;//horizon line of the bezier anchors
var bzHorLn3 = 360;//horizon line of the bezier anchors
var bzHorLn4 = 360;//horizon line of the bezier anchors
var bzHorLn5 = 360;//horizon line of the bezier anchors
var bzHorLn6 = 360;//horizon line of the bezier anchors
var bzHorLn7 = 360;//horizon line of the bezier anchors
var bzHorLn8 = 360;//horizon line of the bezier anchors
var horLn = 360;//horizon line of the bezier non anchors
var boats = [];
function setup() {
createCanvas(480, 480);
frameRate(10);//faster framerate
// create an initial collection of boats
for (var i = 0; i < 10; i++){
var rx = random(width);
boats[i] = makeBoat(rx);
}
frameRate(20);
}
function draw() {
background(38,59,103);//dark blue
fill(244,182,103);//brighter orange
bezier(0,320, quarW,bezH * 8, quarW2,bezH * 8, 480,320);//8
fill(213,131,87);//bright orange
bezier(0,280, quarW,bezH * 7, quarW2,bezH * 7, 480,280);//7
fill(185,106,82);//orange
bezier(0,240, quarW,bezH * 6, quarW2,bezH * 6, 480,240);//6
fill(207,63,57);////bright orange
bezier(0,200, quarW,bezH * 5, quarW2,bezH * 5, 480,200);//5
fill(167,62,72);//bright pink
bezier(0,160, quarW,bezH * 4, quarW2,bezH * 4, 480,160);//4
fill(141,80,94);//pink
bezier(0,120, quarW,bezH * 3, quarW2,bezH * 3, 480,120);//3
fill(93,80,109);//purple
bezier(0,80, quarW,bezH * 2, quarW2,bezH * 2, 480,80);//2
fill(67,88,122);//blue
bezier(0,40, quarW,bezH, quarW2,bezH, 480,40);//1
//-------------------------------SUN
push();
fill(0);
ellipse(sunX, sunH, 200,200);
pop();
sunH += 5;//sun speed
if(sunH > height + 100) {//resets sun placement if it moves past canvas
sunH = -100;
}
if(dist(sunX,sunH, quarW,quarW) < 210){//pushes down sunset blocks
bezH += 3;
}
noFill();
if(dist(sunX,sunH, horLn,horLn) < 170){//pushes down susnet lines
bzHorLn1 += .05;
bzHorLn2 += .1;
bzHorLn3 += .15;
bzHorLn4 += .2;
bzHorLn5 += .25;
bzHorLn6 += .3;
bzHorLn7 += .35;
bzHorLn8 += .4;
}
//-------------------------------
//-------------------------------GROUND
push();
fill(0);
stroke(0);
rect(0,360, 480,130);
stroke(255);
//vertical lines on black area
stroke(255);
strokeWeight(.1);
bezier(bezWS,360, bezW,400, bezW,440, bezWS,480);
bezier(bezWS * 2,360, bezW * 2,400, bezW * 2,440, bezWS * 2,480);
bezier(bezWS * 3,360, bezW * 3,400, bezW * 3,440, bezWS * 3,480);
bezier(bezWS * 4,360, bezW * 4,400, bezW * 4,440, bezWS * 4,480);
bezier(bezWS * 5,360, bezW * 5,400, bezW * 5,440, bezWS * 5,480);
bezier(bezWS * 6,360, bezW * 6,400, bezW * 6,440, bezWS * 6,480);
bezier(bezWS * 7,360, bezW * 7,400, bezW * 7,440, bezWS * 7,480);
bezier(bezWS * 8,360, bezW * 8,400, bezW * 8,440, bezWS * 8,480);
bezier(bezWS * 9,360, bezW * 9,400, bezW * 9,440, bezWS * 9,480);
pop();
//horizontal sunset lines
push()
stroke(244,182,103);//brighter orange
bezier(140,horLn, 190,bzHorLn1, 290,bzHorLn1, 340,horLn);
stroke(213,131,87);//bright orange
bezier(140,horLn, 190,bzHorLn2, 290,bzHorLn2, 340,horLn);
stroke(185,106,82);//orange
bezier(140,horLn, 190,bzHorLn3, 290,bzHorLn3, 340,horLn);
stroke(207,63,57);////bright orange
bezier(140,horLn, 190,bzHorLn4, 290,bzHorLn4, 340,horLn);
stroke(167,62,72);//bright pink
bezier(140,horLn, 190,bzHorLn5, 290,bzHorLn5, 340,horLn);
stroke(141,80,94);//pink
bezier(140,horLn, 190,bzHorLn6, 290,bzHorLn6, 340,horLn);
stroke(93,80,109);//purple
bezier(140,horLn, 190,bzHorLn7, 290,bzHorLn7, 340,horLn);
stroke(67,88,122);//blue
bezier(140,horLn, 190,bzHorLn8, 290,bzHorLn8, 340,horLn);
pop();
//water current (pushed by invisible ball)
push();
fill(50);
noFill();
noStroke();
ellipse(currX,420, 20,20);//current ball
currX -= 5;//speed of invisible ball
if(currX < width - 600) {//resets invisible ball if it moves off canvas
currX = 590;
}
if(dist(currX,currX, bezW,bezW) < 210){//moves vertical lines if ball nears
bezW -= .5;//pushes them forward
}
else {
bezW += .3;//pushes them back after ball leaves
}
pop();
updateAndDisplayBoats();
removeBoatsThatHaveSlippedOutOfView();
addNewBoatsWithSomeRandomProbability();
}
function updateAndDisplayBoats(){
// Update the boats positions, and display them.
for (var i = 0; i < boats.length; i++){
boats[i].move();
boats[i].display();
}
}
function removeBoatsThatHaveSlippedOutOfView(){
//If a boat has dropped off the left edge,
//remove it from the array.
//Copy boats I want to keep into a new array.
var boatsToKeep = [];
for (var i = 0; i < boats.length; i++){
if (boats[i].x + boats[i].breadth > 0) {
boatsToKeep.push(boats[i]);
}
}
boats = boatsToKeep; // remember the surviving boats
}
function addNewBoatsWithSomeRandomProbability() {
// With a very tiny probability, add a new boats to the end.
var newBoatLikelihood = 0.009;
if (random(0,1) < newBoatLikelihood) {
boats.push(makeBoat(width));
}
}
function boatMove() {//method to update position of boat every frame
this.x += this.speed - 3;
}
function boatDisplay() {//draw the boat and some windows
var floorHeight = 10;
var bHeight = this.hPoles * floorHeight;
fill(this.R, this.G, this.B);//star colors
stroke(0);
push();
translate(this.x, height - 135);
//boat
noFill();
stroke(255);
bezier(30,67, 50,70, 80,74, 90,73);//top
line(30,67, 37,83);//front side
bezier(85,83, 91,80, 90,75, 90,73);//back side
line(37,83, 85,83);//bottom
line(60,5 * -bHeight / 60, 60,71);//pole
triangle(40 / this.sailW,60, 60,5 * -bHeight / 60, 60,60);//flap large
triangle(60,58, 60,5 * -bHeight / 60, 75 * this.sailW,58);//flap small
pop();
}
function makeBoat(birthLocationX) {
var bldg = {x: birthLocationX,
breadth: 85,
speed: -1.0,
sailW: random(1,1.3),
R: random(142),
G: random(255),
B: random(130),
hPoles: round(random(-5,40)),
move: boatMove,
display: boatDisplay}
return bldg;
}