30 July 2020

Creating a snake game in Javascript - part 2

Welcome back to the second part of how to create a snake game in Javascript tutorial. On the first part of the tutorial, I explained the component that we need to make a snake game. While, in this part, you'll be learning how to take those components together to make a simple snake game. You can get the code on GitHub here. If you want to test play the game, you can do it by clicking this link (Github Page).

Index for this tutorial:




On the last part, I explained what's the component needed to make a snake game. I also explained the function of the two important class; snake and food. If you still remember the things that we need for our game, if not refer to this text below:

So to make a snake game, we'll need quite a few components for it to work. The very first thing is for the game to load up when the web page is loaded. That's where we'll use the window.onload and load the game from there. Just in case you don't know what window.onload is the event fired when the window is loaded. Then, after the game is loaded, we'll need to draw out all of our objects onto the screen.

Another important component in this game is the game loop, where we repeatedly call a function on a specific time interval. By doing this, our game will have movement and changes on the game's object (the snake and food position, for instance). Another thing that our game will need is to be able to check if the snake has eaten food in each game cycle because we need to be able to increase the length of the snake after it eats food. 

Finally, since the keyboard controls this game, we will need a way to detect key pressed by the user using the event listeners.

Global variable declaration


Before we get into the start-up function, we'll need to initialise the needed variables as described in the comments of the code. 

Global variable initialisation



Startup function for the game


Run a function when the window is loaded.


Next, we need to load up the game when the browser web page is loaded. We can do this by calling a function to draw out the objects when the web page is loaded. Then, how would we call the function when the browser loaded you ask? Well, we can use window.onload to detect the event fired when the web page is loaded. After the handler detects the event, we can then call the function initiate().

initiate() function to initialise initial value into global variable

This function lets us initialise some of the value of our variable. We'll be using the rows and columns variable to limit the location that the Food object can spawn on later. Since in our game, one box has the height and width of 20px, by dividing the canvas height and width with the box variable (contains the value of 20). Then, assigning the food and snake variable with their object (Snake and Food) respectively. When creating a new object for the snake, we need to give it an initial position to be spawned. In my case, I gave it the position of x = 5 * 20 and y = 5 * 20. 

After we create the object and since we have the draw() method in both object, we can call the draw() method of food and snake to draw out the two object into the canvas. After all of that, we need to set-up our game's cycle loop where we call a function repeatedly for a time interval of 100 milliseconds.


Getting key pressed by the user


Event listener for detecting key down in our game


Now, the game can draw its initial objects stats and starting its game loop. But the snake won't move if you press any key on your keyboard. Well, that's because we haven't added an event listener to our game to detect it. Well, thank you, Mr Obvious. So, we'll be using "keydown" as our event trigger as if we instead use the "keyup", the event will not be triggered on time if the user keeps pressing the key for a more extended period. Then by using a parameter to receive the event data that's triggered, we can get the keycode pressed by the user using event.keyCode.


Updating the game using the game loop


After we can detect the key pressed by the player, we can now work on our update() function which is called repeatedly throughout the game.

The update function which is called repeatedly throughout the game

When we want to update anything in canvas, we need to clear the shape drawn onto the canvas. Then we will call the snake's update() function to update the coordinate of its head and tail nodes. Then change the direction of the snake, just in case the player pressed other keys before the next cycle starts. After we've updated the coordinates to a new one, we need to check whether the snake's head is currently at the food node position. If yes, then increase the snake size as specified in the eat() function and assign a new Food object into the "food" variable as well as call the food's draw() method. If the snake's head is not on the food node position, then just proceed drawing out the food. 

Another feature in our game is that when the snake position exceeds the boundaries, it'll be transported to the opposite side. Let's say it surpassed the height of the canvas where the snake's y position is the same as the canvas height, the snake's head will be transported to the opposite side of its location, which means the coordinate of y=0. Then, in case the player snake's head position surpasses the canvas's width ( snake's head's x is equal or greater than canvas width), the snake's head will be repositioned to the left-hand side of the canvas (snake's head's x = 0)

When the snake almost exceeded the left boundary

The head will be shifted to the beginning of the right boundary


Then after the position is processed, we can draw out the snake using the draw() method inside the snake class. Then after a certain time interval (in our case 100 milliseconds), the function will be called again. Since our game doesn't have a game over function, the game will just keep running forever.


Improvement that you could add into the game


The game could be improved in many ways. One example of it is to make a game menu for the player where they could navigate to other things before playing the game instead of the game auto-start each time the web page reloaded. Another suggestion is to make a high score system for the player so that he/she could always compare his/her best score with the current one. Then, you could also make the game to be able to end the game or restart the game when the player loses. To make the game even more fun to play, you could add sound effect when the snake eats food as well as background music.

If you want to add some harder feature, you could add a pause system where the user could pause whenever he/she want. Another thing is that you could add a setting section that could let the player change the key they want to use when controlling the snake and controlling the volumes of the sound effects and background music. Finally, you could also make the game to support mobile user. You could design your own controller button and assign the button with the appropriate function call to control the snake, as well as navigating through the game. 

I've done my full version of the snake game with all the feature I mentioned. You could find the source code here at GitHub. Feel free to download and play with it. It's always fun to play with codes as we can learn a lot by playing with it.

The completed version of my snake game


That's all for this tutorial. I hope you now know the components that we need to create a snake game, as well as how its system work. If you still don't understand how some of the code work, I recommend you to read back the first part so you won't feel confused with some of the functions. Like always if you found this tutorial helpful and interesting, please share it with people that might need it or those that are interested in it. If you have any suggestion, critics or question, feel free to leave a comment in the comment section below. Stay tuned for more new tutorials every week from my blog.

No comments:

Post a Comment