var mountains = [];
var grass = [];
var stars = [];
function setup() {
createCanvas(480, 480);
frameRate(10);
stars.push(makeStar());
for(var j = 0; j < 10; j++){
mountains.push(makeMountainPoint(width + j*80));
}
grass.push(makeGrass());
}
function draw() {
background(25, 25, 112);
drawGround();
updatePositions();
updateArrays();
newStar(); //one star per x position
newMountainPoint(); //one mountain point per x position
newGrass(); //one grass per x position
for(var i = 0; i < stars.length; i++){
stars[i].display();
}
mountainDisplay();
for(var k = 0; k < grass.length; k++){
grass[k].display();
}
// textSize(32);
//text(mountains.length, 240, 240);
}
function drawGround(){
noStroke();
fill('green');
rect(0, 320, 480, 160);
noFill();
}
function updatePositions(){
// Update positions of stars, mountains, and grass
for (var i = 0; i < stars.length; i++){
stars[i].move();
}
for (var j = 0; j < mountains.length; j++){
mountains[j].move();
}
for (var k = 0; k < grass.length; k++){
grass[k].move();
}
}
function updateArrays(){ //updating all arrays to delete objects that have gone offscreen
var starsremaining = []; //temporary transfer array
for (var i = 0; i < stars.length; i++){
if (stars[i].x > 0) { //if the star is still in frame, put in transfer array
starsremaining.push(stars[i]);
}
}
stars = starsremaining; //update normal array, oldest stars now deleted
var mountainsremaining = []; //temporary transfer array
for (var j = 0; j < mountains.length; j++){
if (mountains[j].x > -80) { //deletes the oldest mountain point only until the second oldest point is at the border
mountainsremaining.push(mountains[j]);
}
}
mountains = mountainsremaining; //update normal array, oldest mountain point now deleted
var grassremaining = []; //temporary transfer array
for (var k = 0; k < grass.length; k++){
if (grass[k].x > 0) { //deletes the oldest mountain point only until the second oldest point is at the border
grassremaining.push(grass[k]);
}
}
grass = grassremaining; //update normal array, oldest mountain point now deleted
}
function newMountainPoint() {
if (mountains[6].x < 480 & mountains.length < 10) { //generates new point only if last point has passed onto the screen
var onebefore = mountains[mountains.length-1].x;
mountains.push(makeMountainPoint(onebefore + 80));
}
}
function newStar(){
if (random(0, 100) < 10){ //makes a star at x position 10% of the time
stars.push(makeStar());
}
}
function newGrass(){
if (random(0,10) < 8){ //makes a grass stalk at x position 80% of the time
grass.push(makeGrass());
}
}
// method to update position of building every frame
function starMove() {
this.x -= this.speed;
}
function mountainMove(){
this.x -= this.speed;
}
function grassMove(){
this.x -= this.speed;
}
// draw the building and some windows
function starDisplay() {
stroke('white');
strokeWeight(this.starsize);
point(this.x, this.y);
}
function mountainDisplay(){ //displays mountain range all at once, as each line segment uses two array elements
strokeWeight(1);
stroke('grey');
for(var j = 0; j < mountains.length - 1; j++){
line(mountains[j].x, mountains[j].y, mountains[j+1].x, mountains[j+1].y);
}
}
function grassDisplay(){
strokeWeight(3);
stroke('green');
line(this.x, 320, this.x, 320 - this.stalkheight);
if(this.flower < 1){ //grows a flower 10% of the time
strokeWeight(8);
stroke('yellow');
point(this.x, 320-this.stalkheight);
}
}
function makeStar(){
var star = {x: width, //stars spawn at the right edge
pointdistance: 40,
speed: 3,
starsize: round(random(0, 4)),
y: round(random(0,160)),
move: starMove,
display: starDisplay}
return star;
}
function makeMountainPoint(spawnpoint) {
var mountain = {x: spawnpoint, //mountain peaks spawn past the right edge
pointdistance: 40,
speed: 5,
y: round(random(160,280)), //height of the point
move: mountainMove}
return mountain;
}
function makeGrass(){
var stalk = {x: 480, //grass at the right edge
pointdistance: 40,
speed: 7,
stalkheight: round(random(0,30)), //height of the grass stalk
move: grassMove,
flower: random(0,10), //determines whether stalk grows a flower or no
display: grassDisplay}
return stalk;
}
This project was inspired by Tiny Wings, specifically the peaceful nighttime scene in which a starry night sky slowly drifts by. I wanted to have a green lawn foreground for extra serenity.
The stars and grass were easy to implement, but I had trouble rendering and generating new instances of the mountain peaks. Because I wanted a continuous mountain ridge, the objects being generated were points, and so the display function was an external function that processed the entire mountains array. Difficulty was also had in timing when a new mountain point would be generated; while grass and stars were generated all the time and deleted whenever they went off-screen, mountain points could only be deleted when the second oldest point started to go offscreen in order to leave no gaps. In the same vein, new mountain points needed to be generated off-screen on the other side.