The Concept
The idea has been changed a fair bit based on the class discussions I had with the Professor and I decided to revamp the whole game idea. Now, it is an exploration based game, where the player is an alien flying in a UFO, visiting our solar system for the first time. I wanted to be able to create a scaled version of the solar system, but also emphasize on the vastness of space, thus the canvas is kept at a massive size (5000,5000), and all the orbits are drawn relative to their actual distance from the sun, along with the size of the canvas, I also added a scale to aid with this effect. I still wanted to gamify my project, so I also added a TIMED mode, where the player must fly around the vast solar system and find all the planets. After the planets are all discovered, the time it taken is displayed on screen.
The Sketch
Due to the extensive use of the functions scale() and translate(), the experience is best viewed in full screen mode. Here is the link: https://editor.p5js.org/mhh410/full/9DprniReW
The project starts at the home screen, to give the user control instructions and a storyline, along with two different modes to play. The code itself is structured in a way that I hope it is easy for someone to understand even though it goes up to 900 lines. I did this by creating a bunch of functions in the beginning of the code.
There are several things I am proud in terms of coding.
Firstly, I was able to get to create all the planets in a way that their distances from each other are scaled in a mathematically accurate way.
//Create all Planets mercury = new Planet(19, 2); venus = new Planet(36, 4); earth = new Planet(50, 5); mars = new Planet(75, 3); jupiter = new Planet(250, 25); saturn = new Planet(500, 20); uranus = new Planet(950, 13); neptune = new Planet(1500, 11); pluto = new Planet(1950, 1);
The first number uses a formula I made to convert AU into dimensions I can use in the canvas. I used the formula 0.5(AU) * 100, this was the best way to fit all the different radii of planet orbits into a 5000,5000 scale.
Secondly, another aspect I am proud of is the function to create every planet on a random spot within their orbit.
class Planet { constructor(r, s) { this.rad = sunRad + r; this.size = s; let angle = Math.random() * Math.PI * 2; this.x = Math.cos(angle) * this.rad; this.y = Math.sin(angle) * this.rad; }
The math in the Planet class makes sure that a random point x and y always lie on the radius of the orbit corresponding to that planet.
Another aspect I liked working working on was is the radio feature. I wanted to add some tracks to keep the user engaged while they traversed empty space.
//runs the music, if any song is playing, first stops it and then runs a randomized song. function radio(next){ if(next==true){ if(track1.isPlaying()){track1.stop()} if(track2.isPlaying()){track2.stop()} if(track3.isPlaying()){track3.stop()} if(track4.isPlaying()){track4.stop()} if(track5.isPlaying()){track5.stop()} if(track6.isPlaying()){track6.stop()} let num = random(["1","2","3","4","5","6"]) if(num=="1"){track1.play()} if(num=="2"){track2.play()} if(num=="3"){track3.play()} if(num=="4"){track4.play()} if(num=="5"){track5.play()} if(num=="6"){track6.play()} } }
This function is triggered when the game mode starts and when a user clicks the music button in-game. The function is meant to play a song at random. When the code runs, all music stops first, and then a track is picked at random.
The Challenges
The project was filled with various challenged, some of them I had anticipated earlier. First of which was figuring out how to incorporate motion into the canvas and zoom in to the ufo moving around. I wanted to use camera() initially but then realized that I can’t use this feature in a 2D canvas. Thats when I moved to using translate() so the whole canvas moves when the keys are struck. Then, I used scale to create the zoom-in effect. Along with that, to extenuate on the motion, I decided to cover the dark canvas with star light.
// starlight creation, parameters based on motion of ufo function starlight(moveX, moveY) { for (let i = 0; i < 500; i++) { fill(255, 255, 255, random(100, 255)); // Set the fill to a slightly transparent white noStroke(); starsWidth[i] += moveX; starsHeight[i] += moveY; ellipse(starsWidth[i], starsHeight[i], random(1, 5)); // Draw a small ellipse at a random location with a random size } }
This starlight function moves all the stars in the back drop in the opposite direction of the motion of the UFO to emphasize on the direction the user is moving around in.
Another major issue was the leaderboard. This was a feature I really wanted to add as a way to track all the quickest times a user has achieved in TIMED mode. I worked on it for ages and tried a bunch of implementation like createWriter(), saveStrings() and local storage, but none of it worked. I have left my attempts as comments at the end of the code and eventually decided to drop this feature.