Making Snake

I’ve been working on some fun little p5.js sketches recently and wanted somewhere to host them. And so this: InsomniacPhysicist’s code-y compSci-y sister site. Everything’s still under construction, and I’m mostly just using this post to figure out how it’s all going to work. If you want to entertain yourself in the meantime, you can play some snake or minesweeper.

I want my sketch.js to look something like this

We’re going to need a snake class to achieve this

Nailed it. Snake is played on a grid (which I’d like to be visible), so a reasonable place to start is to define the grid size and draw the background. We add this.gridSize = 20; to the constructor, and call this.drawBoard(); in show()

Next, our snake is going to need some food. I’m going to use a P5 vector to store its position, write a function to randomize its position on the board (for when it gets eaten), and add a couple of lines to draw() to place it as a white rectangle. Click the bar to see the full code.

So now we’re here.

This looks good, but we still don’t have a snake! We need a vector for the head, an array for the tail, and an integer length. We also need a vector for its current velocity. Then, we need a function to give all that good stuff some reasonable initial values:

For movement this was the simplest solution I could come up with for having the tail “follow” the head:

  1. Destroy last tail segment
  2. Add the head to the front of the tail
  3. Move the head one square in the direction of its velocity

Next we need a way to control the snake. I decided to use a switch, like this:

However, this implementation has an issue: if we’re going left and hit RIGHT_ARROW, our snake is going to turn 180 degrees and die. Adding an if statement to check for this partially solves the problem, but if the user inputs two commands during a single frame, they can still turn the snake 180 degrees. The way I chose to fix this was an “acceleration” vector; essentially storing the user’s command and then using it to update the velocity once per frame (an equivalent method would have been some sort of “allowInput” flag, that gets set to false when the velocity is changed).
So, the keyPressed switch now looks like this

And the update function pushes the “acceleration” to the snake’s velocity once per frame

Woohoo! Moving, controllable snake. Now we need collision.


Leave a Reply

Your email address will not be published. Required fields are marked *