If you use Google Chrome, you surely know the mini-game
you can play, when you don't have an internet connection:
The famous Dino Game!
In this project you will create your own version of this game.
- inline styling
- event listeners for user input
- DOM manipulation
- game loop using
setInterval
- running code delayed using
setTimeout
- AABB collision detection
- getting element positions using
getBoundingClientRect
- browser data storage using
localStorage
We need a game loop to run some code every frame.
This game loop will handle almost all our game logic,
including changing the Dino's y position depending on the gravity,
moving our obstacles towards the player, and handling
collision detection between the Dino and the obstacles.
We can use the setInterval
function to run a function in regular intervals.
- create an
update
function - using
setInterval
, ourupdate
function runs roughly every16.67
milliseconds (60 FPS) - put a
console.log
in ourupdate
function to verify that it is being run every frame
Our Dino player character needs to fall to the bottom
of our game area using gravity.
We can use gravity in combination with velocity to
make our Dino move faster and faster.
Our Dino's y
position has to increase, to move downwards,
but it needs to stop once the Dino reaches the bottom.
We can use our update
function to move the Dino every frame.
- every frame, our Dino's velocity will increase based on the gravity
- use our velocity to move our Dino's
y
position every frame - move our Dino HTML element to the new
y
position by changing the element's inline styling with JavaScript - stop moving our Dino once it reaches the bottom of our game area
When the player presses the space key, the Dino should jump. While jumping, if the player releases the space key, the jump's strength should decrease.
- on key down, our Dino starts moving upwards
- while jumping, on key up, our Dino's upwards velocity is decreased
Obstacles are blocks that spawn on the right side of our game area at random intervals. They move towards the left side, towards our Dino. If they collide with our Dino, it's game over. The Dino must jump over these obstacles. Once an obstacle reaches the left side of the game area, it should despawn.
- spawn a new obstacle on the right side of our game area, by creating a new HTML element for our obstacle
- spawn them in random intervals (ex. randomly between 0.5 and 2 seconds), using
setTimeout
- all obstacles move to the left by some fixed pixel value every frame (ex. 10 pixels every frame)
- if an obstacle reaches the left side of our game area, it should be removed from the game, the obstacle's HTML element should be deleted
When our Dino collides with an obstacle, it's game over and
the game should stop. We can implement a simple AABB collision detection
(see Background Materials) function to check for collision between two elements.
Hint: We can use the element.getBoundingClientRect
function to easily get
an element's top/bottom/left/right position values (see Background Materials)
- create a new function (ex.
doElementsCollide
) which should returntrue
if the two elements passed as arguments are colliding with each other, using the AABB collision detection technique - each frame, check if the Dino is colliding with any obstacle
- if colliding, stop the game
We want to have a score, which is incremented when our Dino jumps over an obstacle. When the game is over, we want to display this score to the player.
- when an obstacle's
x
position has made it passed the Dino'sx
position, we want our score to increment - on game over, we want to show our score in the DOM, as an HTML element
We want to save our score into the browser's localStorage
.
On game over, we should get our stored highscore (if it exists),
and if our new score is greater than the stored highscore, we want
to overwrite our localStorage
's highscore with the new score.
On game over, we want to display the highscore, and we want to tell
the player if they just set a new highscore.
- on game over, compare score to highscore from
localStorage
, and if it's a new highscore we save the new highscore tolocalStorage
- on game over, we display the current highscore, and tell the player if they just set a new highscore