For this project, I wanted to create a simple winter landscape, because Christmas is coming and it’s quite exciting. Take a close look at this landscape and close your eyes and imagine that you are Santa Claus on a nice warm sled on your way to California.
I used the noise function to generate the mountains, and objects to create snowflakes and buildings.
sketch
var buildings = [];
var mountains = [];
var noiseParam = 0;
var noiseStep = 0.03;
let snowflakes = [];
function setup() {
createCanvas(400, 240);
for(var i = 0; i < width/5; i++){
var n = noise(noiseParam);
mountains[i];
var value = map(n, 0, 1, 0, height);
mountains.push(value);
noiseParam += noiseStep;
}
// create an initial collection of buildings
for (var i = 0; i < 10; i++){
var rx = random(width);
buildings[i] = makeBuilding(rx);
}
frameRate(25);
}
function draw() {
background(23, 39, 174);
noStroke();
fill(187, 223, 250);
ellipse(200, 70, 70);
fill(255, 30);
cloud(40, 47, 1);
cloud(275, 15, 0.8);
cloud(380, 70, 1.5);
let t = frameCount / 20; // update time
// create a random number of snowflakes each frame
for (let i = 0; i < random(5); i++) {
snowflakes.push(new snowflake()); // append snowflake object
}
// loop through snowflakes with a for..of loop
for (let flake of snowflakes) {
flake.update(t); // update snowflake position
flake.display(); // draw snowflake
}
}
// snowflake class
function snowflake() {
// initialize coordinates
this.posX = 0;
this.posY = random(-50, 0);
this.initialangle = random(0, 2 * PI);
this.size = random(2, 5);
// radius of snowflake spiral
// chosen so the snowflakes are uniformly spread out in area
this.radius = sqrt(random(pow(width / 2, 2)));
this.update = function(time) {
// x position follows a circle
let w = 0.6; // angular speed
let angle = w * time + this.initialangle;
this.posX = width / 2 + this.radius * sin(angle);
// different size snowflakes fall at slightly different y speeds
this.posY += pow(this.size, 0.5);
// delete snowflake if past end of screen
if (this.posY > height) {
let index = snowflakes.indexOf(this);
snowflakes.splice(index, 1);
}
};
this.display = function() {
ellipse(this.posX, this.posY, this.size);
};
//for animating the mountains
mountains.shift();
var n = noise(noiseParam);
var value = map(n, 0, 1, 0, height);
mountains.push(value);
noiseParam += noiseStep;
//for mountains
beginShape();
for(var i = 0; i < width/5; i++){
//filling the mountain with color
fill(44, 67, 184);
noStroke();
//vertex funciton to fill the mountain
vertex((i * 5), mountains[i]);
vertex((i + 1) * 5, mountains[i + 1]);
vertex(width/2, 10000000);
}
endShape(CLOSE);
displayHorizon();
updateAndDisplayBuildings();
removeBuildingsThatHaveSlippedOutOfView();
addNewBuildingsWithSomeRandomProbability();
}
function updateAndDisplayBuildings(){
// Update the building's positions, and display them.
for (var i = 0; i < buildings.length; i++){
buildings[i].move();
buildings[i].display();
}
}
function removeBuildingsThatHaveSlippedOutOfView(){
var buildingsToKeep = [];
for (var i = 0; i < buildings.length; i++){
if (buildings[i].x + buildings[i].breadth > 0) {
buildingsToKeep.push(buildings[i]);
}
}
buildings = buildingsToKeep; // remember the surviving buildings
}
function addNewBuildingsWithSomeRandomProbability() {
// With a very tiny probability, add a new building to the end.
var newBuildingLikelihood = 0.007;
if (random(0,1) < newBuildingLikelihood) {
buildings.push(makeBuilding(width));
}
}
// method to update position of building every frame
function buildingMove() {
this.x += this.speed;
}
// draw the building and some windows
function buildingDisplay() {
var floorHeight = 20;
var bHeight = this.nFloors * floorHeight;
fill(105, 135, 213);
noStroke();
push();
translate(this.x, height - 40);
rect(0, -bHeight, this.breadth, bHeight);
fill(151, 186, 236);
for (var i = 0; i < this.nFloors; i++) {
rect(5, -15 - (i * floorHeight), this.breadth - 10, 3);
}
pop();
}
function makeBuilding(birthLocationX) {
var bldg = {x: birthLocationX,
breadth: 50,
speed: -3.0,
nFloors: round(random(2,8)),
move: buildingMove,
display: buildingDisplay}
return bldg;
}
function displayHorizon(){
fill(68, 91, 193);
rect(0, height-50, width, height-50);
}
function cloud(x, y, size) {
fill(68, 91, 193);
noStroke();
arc(x, y, 25 * size, 20 * size, PI + TWO_PI, TWO_PI);
arc(x + 10, y, 25 * size, 45 * size, PI + TWO_PI, TWO_PI);
arc(x + 25, y, 25 * size, 35 * size, PI + TWO_PI, TWO_PI);
arc(x + 40, y, 30 * size, 20 * size, PI + TWO_PI, TWO_PI);
}