Game Development

Snake Game using Phaser

Drawing the Snake

As we mentioned earlier, the Game state is where the actual game play happens. This is also the place where we will draw the snake. Like we did with the Menu state, we need to register the Game state with the global game object in main.js.
Here is how your code should look like:

main.js


var game;

game = new Phaser.Game(600, 450, Phaser.AUTO, '');
        
game.state.add('Menu', Menu);
        
// Adding the Game state.
game.state.add('Game', Game);
        
game.state.start('Menu');

menu.js

We'll also want to add some code in menu.js to let us start the Game state when it is clicked. For this purpose, we will replace the sprite with a button. Adding a button is basically the same as adding a sprite, you only need to provide a function to be called when it is clicked.
Here is the final menu.js code:


var Menu = {

    preload : function() {
    // Load all the needed resources for the menu.
        game.load.image('menu', './assets/images/menu.png');
    },
        
    create: function () {
        
    // Add menu screen.
    // It will act as a button to start the game.
        this.add.button(0, 0, 'menu', this.startGame, this);
        
    },
        
    startGame: function () {
        
    // Change the state to the actual game.
        this.state.start('Game');
        
    }
        
};

game.js

We can now proceed with coding the Game state and drawing the snake. The structure is similar to the one of the Menu state.


    var snake, apple, squareSize, score, speed,
    updateDelay, direction, new_direction,
    addNew, cursors, scoreTextValue, speedTextValue, 
    textStyle_Key, textStyle_Value;
        
var Game = {
        
    preload : function() {
        // Here we load all the needed resources for the level.
        // In our case, that's just two squares - one for the snake body and one for the apple.
        game.load.image('snake', './assets/images/snake.png');
        game.load.image('apple', './assets/images/apple.png');
    },
        
    create : function() {
        
        // By setting up global variables in the create function, we initialise them on game start.
        // We need them to be globally available so that the update function can alter them.
        
        snake = [];                     // This will work as a stack, containing the parts of our snake
        apple = {};                     // An object for the apple;
        squareSize = 15;                // The length of a side of the squares. Our image is 15x15 pixels.
        score = 0;                      // Game score.
        speed = 0;                      // Game speed.
        updateDelay = 0;                // A variable for control over update rates.
        direction = 'right';            // The direction of our snake.
        new_direction = null;           // A buffer to store the new direction into.
        addNew = false;                 // A variable used when an apple has been eaten.
        
         // Set up a Phaser controller for keyboard input.
        cursors = game.input.keyboard.createCursorKeys();
        
        game.stage.backgroundColor = '#061f27';
        
        // Generate the initial snake stack. Our snake will be 10 elements long.
        // Beginning at X=150 Y=150 and increasing the X on every iteration.
        for(var i = 0; i < 10; i++){
        snake[i] = game.add.sprite(150+i*squareSize, 150, 'snake');  // Parameters are (X coordinate, Y coordinate, image)
        }
        
        // Genereate the first apple.
        this.generateApple();
        
        // Add Text to top of game.
        textStyle_Key = { font: "bold 14px sans-serif", fill: "#46c0f9", align: "center" };
        textStyle_Value = { font: "bold 18px sans-serif", fill: "#fff", align: "center" };
        
         // Score.
        game.add.text(30, 20, "SCORE", textStyle_Key);
        scoreTextValue = game.add.text(90, 18, score.toString(), textStyle_Value);
        // Speed.
        game.add.text(500, 20, "SPEED", textStyle_Key);
        speedTextValue = game.add.text(558, 18, speed.toString(), textStyle_Value);
        
    },
        
    update: function() {
        // The update function is called constantly at a high rate (somewhere around 60fps),
        // updating the game field every time.
        // We are going to leave that one empty for now.
    },
        
    generateApple: function(){
        
        // Chose a random place on the grid.
        // X is between 0 and 585 (39*15)
        // Y is between 0 and 435 (29*15)
        
        var randomX = Math.floor(Math.random() * 40 ) * squareSize,
            randomY = Math.floor(Math.random() * 30 ) * squareSize;
        
        // Add a new apple.
        apple = game.add.sprite(randomX, randomY, 'apple');
    }
        
};