Code a Snake game with JavaScript | Hunor Borbély | Skillshare

Code a Snake game with JavaScript

Hunor Borbély, Web developer

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
3 Lessons (10m) View My Notes
    • 1. Intro

    • 2. Layout and Game Logic

    • 3. Transitioning Effect with CSS


About This Class

In this mini-course, I’m going to show how to create a Snake game with HTML, CSS, and JavaScript. It's a mini-course because we are not going through every detail. I'm going to give you an overview of how the game is build up, explain some of the tricky parts, and then you can find out the rest in the source code. There's plenty of comment in the source code, so this quick walkthrough should be enough to get you started. So let's get into it!


1. Intro: Hey folks, my name is sooner and in this mini-course, I'm going to explain how to create a snake game with HTML, CSS, and JavaScript. It's a mini-course because I'm not going to explain everything. We're not going through the code line by line and we want cold along. I'm going to give you a quick overview of how the game is built up and explain some of the tricky parts. And then you can look up the rest in the source code. You can find a war game on CodePen. So if you want to try it out and see what we are getting into, check out the link in the description below. You can play the game and there you can see the wall source code. There's plenty of comments in the source code. So this quick introduction should be enough for you to get you started. In this video, I'm going to the main parts, but I won't cover the fading effect this game has unquote bad. We are only going to cover a regular snake game. Then we are going through how the transitioning effect works from one type to another. For this project, I'm not using any libraries, not even SVG or Canvas, just plain HTML, CSS, and JavaScript. Of course, it could have been made in some more advanced tools, especially with Canvas, that animation might be smoother, but it works pretty well this way as well. Also, if you're interested in using Canvas in my next mini-course, I'll explain again that uses canvas. So click Subscribe if you don't want to miss that. 2. Layout and Game Logic: Let's see the layout first. The layout is a 50 times 50 grid, but instead of positioning them individually, we have 225 ties as div elements in the list. Then we make it look like a grid with CSS grid. Because of this, we will need a few calculations later on when the snake is moving and we need to figure out which tile is above or below a tile. But it's not too complicated. Also, this is just an example. I'm not actually having 225 hardcoded ties in HTML. I'm generating them with JavaScript. You can find the source code for that on cold plan. So how do we render the snake and the fruits on the field? With this setup, we can have an array for the snake positions and the value for the apple or the foot position. I'm not sure if snakes actually that polls, but I'm calling it Apple in this code. So that because simply access the tag corresponding for the positions and just change their CSS to set a background color for a snake part, or to change the background and add the border radius for the food diet. And that's it. If you just want to paint a static scene, it's fairly simple. But to be the real game with a lot of moving parts, it's a bit more complicated. Let's see how the war game works. The game has four main parts and functions. There's a main loop that keeps track of time and decides if the snake should take another step forward. There is a step function that retains the layout after the snake took a stab. It will use an exposition utility function that determines to which tied the snake moves next based on the current direction and the user inputs. And finally, in parallel with all this, we also handle user interaction to change this next eruption. Let's start with handling user input, because that's the most simple one, where we register an event listener to the key down event. And then if one of the arrow keys is pressed, that firstly prevent the default action because otherwise the browser might think that we tried to scroll the page, then change the direction. Here we push a new direction into an array. And this is an array because you want to enable quick turns when the players pressing keys faster than the snake moves. Like when the snake moves to the right. And the player wants to have a quick turn back and presses up, down left, right after each other. And the snake haven't even moved appetite yet, but we already know that once the snake moved upwards, it nice to turn left. So we have a stack of future turns here. In this function, we could also make some fine tuning. Like we can ignore full turns. Like for instance, if the snake is going right and we press the left, then we could ignore that. Sin for duplicates. If you press right, but the snake is already going right, then we can ignore that as well. This all depends on how you make the game rules. If you are going to create your own snake game, then you can decide how to implement your version. Now let's get to the main event loop. This is using request animation frame, so it will run 60 times every second. The request animation frame gives a timestamp you can use to calculate the time elapsed since the beginning of the game. This time are of course, will always reset when we start the game. We also keep track here, how many steps did this snake take? And based on the time passed and the snake speed, we can also figure out if it's time for the snake to take a step forward. Then we get to the step function, which is fairly simple at this phase, you just grab the next position from the GetMax collisional function added to the snake positions array and paint the corresponding tile to black. Then also we clear up the tail of the snake, excepted the snake just read the food because then the snake is growing and that they are remains. So how did we get the position? First, we figure out the direction. It's either the next item in the user inputs array or we just go to the same direction the snake is already going. Then we figure out the index of the next time. If the snake moves to the right, then we just add plus one to the current head position. If the snake moves to the left, then is the same thing in the opposite direction, we substract one. If you want to go downwards, this is a bit trickier. We have to add the number of items in a row to the current head position to get the index of the Thai below the head. This is 15 in our case, because the width of the grid is 15. If you go up the same story backwards, we subtract 15 from the current head position. And of course, we also need to do some heat detection in dysfunction to make sure that the snake does not hit the wall or doesn't bind itself. In these cases, we just throw an error with the message. And in the main event loop, you might have noticed there's a try-catch block that will catch this error and show a note to the user. After an error, the game loop stops. So we have to restart it for a new game. You can't see it on this slide. But if you check the actual source code, you're going to see that the game restarts b, the space key. In a happier scenario, we can also run into some food. In this case, we increase our score variable, show it to the player by setting the corresponding HTML elements content. And we generate a new Apple. So that's the base game. It's very simple, but it does the job. But of course, instead of stepping tile by tile, it would be much nicer to have a smooth transitioning from one side to the other. 3. Transitioning Effect with CSS: To achieve this, we can have a modified HTML structure. We are going to have a content div for each tile that's gonna take an absolute position relative to the tile itself. And this is great because now instead of filling the Waldstein, we can just feel part of it and we can set from which direction should the field start. Here you can see an example of the idea. But of course we're not setting these from CSS, but we are setting this dynamically from JavaScript based on the snakes eruption. If the snake is heading to the right, then we start the content from the left as set of V. It appropriate to the progress of transitioning. Like if the snake is halfway between two steps, we can set the width of the content to 50% of the time. If the snake is heading to the left, then the same thing is happening, except the snake moves in from the other direction from the right. If the snake is moving down, then we position the content to the top. And this time instead of setting the content with relative to the tile, we set the content height according to the progress. If the snake is moving up the same thing except we positioned the contents to the bottom. The inner parts of the snake that ties except for the head and the tail, don't need any positioning. We can just set the background color and lab id field of tile. So with this method, we can achieve a similar transitioning, but we're missing one piece from the code IV. The snake keeps moving and starts changing directions. We will need to change the absolute positioning in CSS. And in that case, it's better to reset the value set before. Like when the snake was transitioning horizontally, we changed the width attribute, but then it turns upwards. We better cleared a width attribute and reset it to 100%. To solve this problem, I use a set time function that says the values according to its input, but resets every other CSS attribute that we don't specifically. One less thing to mention, if you check how the actual source code for the game, which you can find, of course, in the links below. Then you will find that I did some optimization regarding which bars the greed or repainted. It doesn't retain the wall grid every time because that will be quite resource heavy. It doesn't even repays the worst snake. When the snake transitions between two ties, the body of the snake stays intact and only the head and the tail are transitioning. That's why you want to find the simplest step function, but you find a step and transitional function along with the transitional function. As the name suggests, the step and transitional function takes care of moving from one type to another and sets up the CSS attributes for the transition function. On the other hand, the transitional function just eases the head and tail in between two steps. The reason for this is that the transitional function is called with every render. So it has to be fast. And the step and transitional function can be a bit slower because that only happens at every step. So those were the main parts of this game. If you want to dig deeper into the code, you can find a wall game with the source code in the description below. So I hope you enjoyed this video. If you liked it, please subscribe. I'm planning to do some of these in a similar fashion. In the next song, we are going to again also with the JavaScript, which we'll use Canvas. So hope to see you there.