In this part, we are going to finish the game by implementing things like elements rendering, projectors, and game loop. Let’s jump in!
We need to somehow project the game state to the screen. In the example below — the point with coordinates (3, 6) in the game state projected on the screen to point at (180, 360).
To do this, we will write a function that receives container size and size of the game field and returns an object with two projectors — for distances and for vectors.
To render game elements, we need access to the container element we put in the HTML back in the first part.
We can get container by id, and then obtain its width and height. To clear container, we remove its first and only child — canvas.
We will render all game elements on the canvas context, so we need a function to receive it.
We have separate functions to display cells, food, snake, and scores. The main render function receives state object, calculate all parameters needed for other functions, and put everything on the screen.
State of the whole game is an object, and the same way as with game state, we will write a function that generates initial state for the application.
The function takes container size and game initial state to pack everything together. Worth to mention that projectors are also in the application state.
Inside of the game loop, we will call a function listed below to receive a new state.
If the game not stopped we are receiving a new game state and update the best score that saved in the local storage, so that it is not lost when the player closes a browser tab.
Now we are ready to put everything together.
In this function, we have the only let keyword in the entire game. We will update the state by calling a function declared at the start of the body.
The first event listener allows us to have a smooth picture when the screen changes its size. When resize happens, we will clear container, attach new canvas, update state with new projectors, and call tick() extra.
On keydown events, we update the state with new movement value. On keyup event, we clear movement and check if the player wants to stop or resume the game. On the stop, we will save the time of the game stop, and on a resume, we will calculate a new value for the last update.
At the end of the function, we are starting the game loop that consists of updating game state and rerendering.
Now, you can open the file in the browser and enjoy the game! To take most from this series I highly recommend you to make changes in the game to improve your skills. There is a list of possible things I think of that can be done next:
- Make a snake look more realistic by making it rounded and with an actual head.🐍
- Increase the length of the snake only when its tail reaches the point of the eaten food position.
- Sound when snake changes direction or eats the food.
- Make an interesting animation when the snake hits the wall or eats the food.
In this series, we implemented the classic snake game. The commit with changes from this part you can find here. Thanks for staying until the end!
Reach the next level of focus and productivity with increaser.org.