Epsilon

Designing Snake in HTML5:Basic Design

Posted on November 3, 2012

As a first set of posts, I thought I would share my development process in creating a snake game with html5, and Coffeescript. For those that do not know, the basic snake game where you control a snake that is trying to eat food pellets, while trying to avoid hitting walls, as well as yourself.

Snake Game

Snake Game

This post will show my basic design for such a game, such as the structures that I will be using as well as the game’s flow. I will do this and try to keep terminology relevant to Coffeescript, as well as object-oriented programming.

To begin, I will describe the basic structure of Snake. In Snake, there are a few things that need to be kept track of.

Keeping Track of the Canvas

The first big thing is the canvas element, and the basic game window that I draw Snake in. To draw the game well I need access to the width, height, and context of the canvas element. Also, because I am designing this game in terms of a grid, I need to keep track of how many rows and columns there are. Finally, since there is the possibility that I will use HTML to keep track of the score, I also want to keep track of what div tag I am working in.

For this I will create a Window class, that when the game is initialized will give these relevant parts of the canvas element to this object. So the code that I use in coffeescript would be

Window =
    COLS:   40
    ROWS:   40
    WIDTH:  400
    HEIGHT: 400
    FPS:    60

    div:     {}
    context: {}
    screen:  {}

So as you can see, I create a Window object, with parameters for width and height, which for snake I define to be 400 each. I also have parameters for number of columns and rows, both of which for now are set to 40. Finally, there is both a context and a div parameter, both of which are currently undefined. I clearly show them here so I know that later I will be able to this Window object definition to know what the Window object contains.

Snake

I will also need to keep track of the snake. In particular there are a few things I need to keep track of many things:

So, there are lots of things to keep track of. Here is the basic object I use to keep track of this.

Snake =
    reset: false
    cells: []
    direction: Direction.RIGHT
    move_interval: 100
    last_move: 0
    eaten: 0
    growth: 0
    bitmap: undefined

So in the code, the cells parameter keeps reference of every snake body part. The rest are pretty self explanatory, but there is also one other oddball, the direction parameter. To keep track of all possible ways the snake can move, I give certain values to mean certain directions, and then also give them names so I can use the names instead of values. This is all just to help me read the code later. The code for this Direction object is this:

Direction =
    RIGHT :0
    LEFT  :1
    UP    :2
    DOWN  :3

    opposite : (dir) ->
        if dir == Direction.RIGHT
            return Direction.LEFT
        else if dir == Direction.LEFT
            return Direction.RIGHT
        else if dir == Direction.UP
            return Direction.DOWN
        else if dir == Direction.DOWN
            return Direction.UP

So it is an object, with left, right, up, and down parameters that have all been given unique values. I also place a method here to determine the opposite direction of a given direction.

Food

Finally there is the food pellet to keep track of. Compared to the snake, this has much less to keep track of. I only need to keep track of the position of the food pellet, and the image to use for a given food pellet. So the code for the food pellet is this:

food =
    cell: []
    bitmap: undefined

Why Objects Instead of Classes?

So with that each of the major things in Snake are given substance. There is something a little interesting about the way I designed this though. That is, thus far I have only been defining objects for each of these. Why would I do this? Well, the way I see it is that there is only ever one of these things that is being used at a time. That is, there is only one snake, one food pellet, and one window being drawn or used at a time. If I were to write this game in Java, I would have to design a class for each of these. In fact, in Java this would be an example of a design pattern called the singleton. The singleton pattern is where there is only ever one object instantiated for a class at a given time. For both Javascript and Coffeescript however, I can skip the step of creating a class, and move straight to defining an object for this. Later on, you will see that when a game in Snake is over I will have some way of resetting everything. For now though this is sufficient.

Checkout this github project to see code for this project.

comments powered by Disqus