Achieving our goal¶
Eating the apple is the only goal in snake. Each apple the player eats, the larger the snake grows, and the more points he scores. Each time the snake eats the apple, the apple is respawned in another location on the grid. In order to spawn our apple in random locations, let's write a function to generate a random tile.
Creating chaos¶
JavaScript has a built-in Math library with plenty of functions we can use out of the box. Math.random is the first function we will use. It generates a random floating-point (decimal) number that is greater than or equal to 0 and less than 1. We want to generate numbers that corrospond to tile coordinates, which will be whole numbers between 0 and 9 for our 10x10 grid. Math.random() * max
will create x
where 0 <= x < max
. Or, using interval notation, [0,max).
Since we need whole numbers, we must round the result of Math.random() * max
. If we use Math.round, it will be less likely for us to get a number at the bottom and top of the range. For example, to roll a 0, Math.random() * max
would have to return a number lower than .5. To roll a 1, it would have to return a number between .5 and 1.5, which is twice the probability of rolling a 0. To give the entire range the same probability of being chosen, we will use Math.floor. It will round any number less than 1 down to 0. The only catch with using Math.floor
is that we need to provide a max
of 10 to achieve a range of 0-9.
Creating the Apple¶
Since the apple needs to respawn every time it gets eaten by the snake, let's write a function to create the apple. The function should be called immediately, so that upon loading the game, the apple will be waiting for the player.
Looks good! But with our current code, we could throw an apple directly on top of the snake. To avoid that, let's check if the randomly generated apple is on top of the snake, and if it is, we will try to randomly generate the apple again. We will use a do...while
loop to repeat the generation logic if there is a collision. Since there is only one apple, once we detect a collision, we can stop looping through the elements in the player array.
Rendering the apple¶
It's time to draw our objective on the screen! But first, let's break out our tile rendering logic into a function called drawTile
. This will make it easier to draw the apple.
Let's use this new function to draw the background, player, and the apple. Your render function should now look like this:
Great! Now you should see an apple randomly drawn on the screen. But we aren't finished with this apple, yet! The snake will run right through the apple without eating it. To fix this, we need to implement the update logic for our apple.
Eating the apple¶
Start by defining a new varible to store whether or not the apple has been eaten. You can put this near the top of the file with the other variables.
At the bottom of the update
function, we need to write some logic to check whether the player's new head
position collides with the apple. If there is a collision, we will update the eaten
variable, and respawn the apple.
Question
Now that the apple has been eaten, how can we increase the size of the snake by 1 tile?
Solution
To make sure you're all caught up, here is the entire update
function.
Great work!
Now our snake can achieve his only goal in life - eating the apple. Our game has all the basic mechanics of Snake! In the next chapter, we learn how to complete the game loop to allow players to play our game over and over again.