var terrainSpeed = 0.0005;
var terrainDetail = 0.01;
var buildings = [];
var stars = [];
var balls = [];
var clouds = [];
function preload() {
castleImage = loadImage("https://i.imgur.com/enlJeCX.png");
}
function setup() {
createCanvas(480, 320);
frameRate(10);
for (var i = 0; i < 3; i++){
var rx = random(width);
buildings[i] = makeBuilding(rx);
}
for (var g = 0; g < 150; g ++) {
var ry = random(width);
stars[g] = makeStar(ry);
}
for (var h = 0; h < 5; h ++) {
var rz = random(width);
clouds[h] = makeCloud(rz);
}
}
function draw() {
background(255);
var sky1 = color(33, 25, 64);
var sky2 = color(6, 41, 100);
var sky3 = color(135, 110, 168);
var sky4 = color(201, 159, 161);
var sky5 = color(254, 219, 155);
var sky6 = color(246, 179, 124);
for (var c = 0; c <= height/3.5; c += 1) {
var amt = map(c, 0, height/3.5, 0, 1);
var skygradient1 = lerpColor(sky1, sky2, amt);
noStroke();
fill(skygradient1);
rect(0, c, width, 1);
}
for (var d = 0; d <= height/2.5; d ++ ) {
var amt = map(d, 0, height/2.5, 0, 1);
var skygradient2 = lerpColor(sky2, sky4, amt);
noStroke();
fill(skygradient2);
rect(0, c + d, width, 1);
}
for (var e = 0; e <= height/5; e ++ ) {
var amt = map(e, 0, height/5, 0, 1);
var skygradient3 = lerpColor(sky4, sky2, amt);
noStroke();
fill(skygradient3);
rect(0, c + d + e, width, 1);
}
image(castleImage, 20, 70, 120,120);
updateAndDisplayStars();
removeStarsThatHaveSlippedOutOfView();
addNewStarsWithSomeRandomProbability();
createHill();
drawRectangle();
createHillShadow();
updateAndDisplayBuildings();
removeBuildingsThatHaveSlippedOutOfView();
addNewBuildingsWithSomeRandomProbability();
makeballs();
updateAndDisplayClouds();
removeCloudsThatHaveSlippedOutOfView();
addNewCloudsWithSomeRandomProbability();
newBalls = []; // Creates an empty array that will store the values of the newly-created balls
for (var i = 0; i < balls.length; i++) {
var p = balls[i];
p.speedy(); //returns the function speed() which makes the balls move
p.balls(); //returns the function balls() which assigns the balls their properties
newBalls.push(p);
}
balls = newBalls;
}
function updateAndDisplayStars(){
// Update the lantern's positions, and display them.
for (var i = 0; i < stars.length; i++){
stars[i].move();
stars[i].display();
}
}
function removeStarsThatHaveSlippedOutOfView(){
var starsToKeep = [];
for (var i = 0; i < stars.length; i++){
if (stars[i].x> 0) {
starsToKeep.push(stars[i]);
}
}
stars = starsToKeep;
}
function addNewStarsWithSomeRandomProbability() {
// With some possibility, add a new lantern
var newStarLikelihood = 0.5;
if (random(0,1) < newStarLikelihood) {
stars.push(makeStar(width));
}
}
// Makes the lanterns move
function starMove() {
this.x -= this.speed;
}
// Draws the lanterns
function starDisplay() {
fill(250, 254, 149);
rect(this.breadth, this.x, this.size, this.size*1.5)
}
function makeStar(birthLocationX) {
var star = {x: birthLocationX,
y: random(10,70),
breadth: random(width),
breadthy: random(height),
speed: random(0.1,4),
move: starMove,
display: starDisplay,
size: random(2,7)
}
return star;
}
function createHill() {
var noiseScale = 0.001;
var forestDetail = 0.0005;
var forestSpeed = 0.0005;
for (g = 0; g < width; g++) {
h = (g * forestDetail * 8 + millis() * forestSpeed/8);
i = map(noise(h), 0, 1, 40, 100);
stroke(30);
line(g, i+100, g, height-80);
}
}
function drawRectangle() {
var sky1 = color(33, 25, 64);
var sky2 = color(37, 55, 127);
var sky3 = color(135, 110, 168);
var sky4 = color(201, 159, 161);
var sky5 = color(254, 219, 155);
var sky6 = color(246, 179, 124);
for (var e = 0; e <= height/5; e ++ ) {
var amt = map(e, 0, height/5, 0, 1);
var skygradient3 = lerpColor(sky6, sky1, amt);
noStroke();
fill(skygradient3);
rect(0, 240+e, width, 1);
}
fill(sky1);
rect(0, 240+e, width, height-(240+e))
}
function createHillShadow() {
var noiseScale = 0.001;
var forestDetail = 0.0005;
var forestSpeed = 0.0005;
var noiseScale = 0.001;
var forestDetail = 0.0005;
var forestSpeed = 0.0005;
push();
translate(0,480)
scale(1,-1)
// 3rd "layer" of forest
for (g = 0; g < width; g++) {
h = (g * forestDetail * 8 + millis() * forestSpeed/8);
i = map(noise(h), 0, 1, 40, 100);
stroke(30,70);
line(g, i+150, g, height-80);
}
pop();
}
//Below: set of functions that create the boats
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 +30 > 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.009;
if (random(0,1) < newBuildingLikelihood) {
buildings.push(makeBuilding(width));
}
}
// method to update position of a boat every frame
function buildingMove() {
this.x -= this.speed;
}
// draw the boats
function buildingDisplay() {
var floorHeight = 20;
var bHeight = this.nFloors * floorHeight;
fill(this.R, this.G, this.B);
noStroke();
push();
translate(this.x, height-this.y);
rect(0, -bHeight, this.breadth, bHeight);
triangle(-30, -bHeight, 0, -bHeight, 0, 0);
triangle(this.breadth+30, -bHeight, this.breadth, -bHeight, this.breadth, 0)
stroke(200);
pop();
//draws the reflections of the boats
push();
fill(this.R, this.G, this.B, 80);
translate(this.x, height-this.y);
scale(1,-1)
rect(0, -bHeight/2, this.breadth, bHeight);
triangle(-30, -bHeight/2, 0, -bHeight/2, 0, 0);
triangle(this.breadth+30, -bHeight/2, this.breadth, -bHeight/2, this.breadth, 0)
stroke(200);
pop();
}
function makeBuilding(birthLocationX) {
var bldg = {x: birthLocationX,
cloudx: random(width),
y: random(10,70),
breadth: random(60,90),
speed: random(2,3),
cloudspeed: random(0.5,1),
R: random(70,90),
G: random(50,70),
B: random(10,40),
transparency: random(100,200),
nFloors: round(random(1,1.5)),
move: buildingMove,
display: buildingDisplay
}
return bldg;
}
//Below: set of functions that generate the clouds
function updateAndDisplayClouds(){
for (var i = 0; i < clouds.length; i++){
clouds[i].move();
clouds[i].display();
}
}
function removeCloudsThatHaveSlippedOutOfView(){
var cloudsToKeep = [];
for (var i = 0; i < clouds.length; i++){
if (clouds[i].x + clouds[i].breadth +30 > 0) {
cloudsToKeep.push(clouds[i]);
}
}
clouds = cloudsToKeep;
}
function addNewCloudsWithSomeRandomProbability() {
// With a very tiny probability, add a new building to the end.
var newCloudLikelihood = 0.02;
if (random(0,1) < newCloudLikelihood) {
clouds.push(makeCloud(width));
}
}
function cloudMove() {
this.x -= this.speed;
}
function cloudDisplay() {
push();
fill(255, this.transparency);
translate(this.x+50, 100 + this.y);
ellipse(0, 0, this.y, this.y*0.5);
pop();
}
function makeCloud(birthLocationX) {
var cloud = {x: birthLocationX,
y: random(10,70),
breadth: random(60,90),
speed: random(0.5,1),
transparency: random(100,200),
move: cloudMove,
display: cloudDisplay
}
return cloud;
}
function makeballs() {
var ix = constrain(floor(this.xx), 0, width-1);
var iy = constrain(floor(this.yy), 0, height-1);
fill(250, 254, 149)
noStroke();
rect(this.x, this.y, this.ballsize, this.ballsize*1.5); // Draws the ellipse at (x,y) with the width and the height dimension of 'ballsize' which is a random number between 2 and 8
}
function ballspeed() {
this.y += this.dy; // MouseY will be later assigned as 'y'
}
function drawPortrait(placeholderx, placeholdery, placeholderdy) {
p = {x: placeholderx,
y: placeholdery,
dy: placeholderdy,
speedy: ballspeed,
balls: makeballs,
ballsize : random(4,10)
}
return p;
}
// Lanterns generated when the mouse is moved
function mouseMoved() {
var newball = drawPortrait(mouseX, mouseY, random(-20, 20));
balls.push(newball);
x += random(x-3, x+3);
}
I wanted to recreate a scenic setting from my favorite Disney movie – Tangled!!!! There are total five components of the landscape, which are the moving clouds, the hill, the shadow of the hill, the lanterns, and the moving boats. There’s a little surprise hidden in this code; you could perhaps try moving your mouse to find out what it is!
Initially I wanted to make Rapunzel and Flynn Rider to randomly pop up on one of the boats but I had some difficulty coding it. It was a little annoying that I had to make multiple sets of the functions for different objects, but at the end it was rewarding because I got to recreate my favorite Disney movie.
Also I’d like to use one of my grace days for this project. Thank you!