It’s time to complete our small snake game (long timeout between posts due to work). Last time we made the snake move on the board and added keyboard controls. Now all that remains is picking up the apples and collision detection with the tail.
First step is placing the apples on the board.
This is something we will do many times, so we introduce a new function
that handles this.
Apples should be assigned to a random position, so we pick a random cell on the
board, using the
Math.floor functions in combination to pick
an integer (non-decimal) number for the X and Y positions. We then update the
board at this position with the property
apple set to the value
Ta place an apple on the board when the game starts, update the
Before the final
} brace, insert a call to the
We also need to update the loop in this function to clear all apples on the board.
The end of the
startGame function will thus look like this, with a call to the
new function and an updated loop:
We also need to check in the render loop for the
apple value (the same place we check
the board for the
snake value) and set a different CSS class if there is an
apple on that spot. In other words, we update the
gameLoop function with the following
else if statement.
And finally, add a matching CSS class, to style the apple red on the board:
Once these changes have been made, the red apple should appear on the board. You can also look at the source of the below sample.
The final piece of the puzzle, will be to pick up the apples and tail collisions.
To check if the snake collided with an apple, we will update the game loop with another if statement. Add this after checking if we collided with any walls (as before):
We check if an apple is present on the cell we are moving to, if that is the case we increase the length of the snake, remove the apple and place a new apple on the board. This makes the game playable:
Collisions with the tail
If you play the game above long enough, you’ll notice you don’t die if you go through your own tail. This is the final thing we need to add to our game.
This requires a very similar check to the one we had for apples, but we instead check if the snake property is set. If it is, we just restart the game. The following if statement goes before the one we added before to pick up apples:
After revelling in your success, we can note there are still bugs to be fixed:
- Apples can be placed ontop of the snake, making them invisible! In
placeApplewe should prevent this by always finding a free position on the board.
- You can walk backwards and collide with yourself. We should check in
enterKeythat we don’t reverse the direction of the snake.
After fixing the bugs, try to extend the game. Here are some ideas on what can be done:
- Replace the snake and Apple with cooler graphics, try using
- Golden apples that give three times the length extension, but disappear if you don’t pick it up fast enough.
- A score display to show the user how many apples they picked up.
- Continuing on score, a high score table. And maybe store it in
localStorageso it persists?
- Only start the game after the user gives some input after dying.
- Mobile support is atrocious, try to make it playable on an iPhone!
- Maybe don’t using
1000 / snakeLengthfor timeout, as the game quickly becomes impossible due to the speed. Try some other formula that is more fair.
Enjoy, and if you make any improvements, please let me know!