Game Development

Snake Game using Phaser

Collision Detection

A game in which the snake is roaming freely in the playing field is not much fun. We need to detect when the snake comes in contact with a wall, an apple or itself. This is called collision detection.

This is usually done by using a physics engine, of which the Phaser framework supports a few. But they are too complex for a simple game like this. We will instead do our own collision detection by comparing coordinates.

In the update function, after the code for moving the snake, we call a number of methods. They will compare coordinates to tell us if a collision has occurred.


        update: function() {

            // Snake movement
            // ...
            // End of snake movement
    
            // Increase length of snake if an apple had been eaten.
            // Create a block in the back of the snake with the old position of the previous last block
            // (it has moved now along with the rest of the snake).
    
            if(addNew){
                snake.unshift(game.add.sprite(oldLastCellx, oldLastCelly, 'snake'));
                addNew = false;
            }
    
            // Check for apple collision.
            this.appleCollision();
    
            // Check for collision with self. Parameter is the head of the snake.
            this.selfCollision(firstCell);
    
            // Check with collision with wall. Parameter is the head of the snake.
            this.wallCollision(firstCell);
        }
    
    },
    
    appleCollision: function() {
    
        // Check if any part of the snake is overlapping the apple.
        // This is needed if the apple spawns inside of the snake.
        for(var i = 0; i < snake.length; i++){
            if(snake[i].x == apple.x && snake[i].y == apple.y){
    
                // Next time the snake moves, a new block will be added to its length.
                addNew = true;
    
                // Destroy the old apple.
                apple.destroy();
    
                // Make a new one.
                this.generateApple();
    
                // Increase score.
                score++;
    
                // Refresh scoreboard.
                scoreTextValue.text = score.toString();
    
            }
        }
    
    },
    
    selfCollision: function(head) {
    
        // Check if the head of the snake overlaps with any part of the snake.
        for(var i = 0; i < snake.length - 1; i++){
            if(head.x == snake[i].x && head.y == snake[i].y){
    
                // If so, go to game over screen.
                game.state.start('Game_Over');
            }
        }
    
    },
    
    wallCollision: function(head) {
    
        // Check if the head of the snake is in the boundaries of the game field.
    
        if(head.x >= 600 || head.x < 0 || head.y >= 450 || head.y < 0){
    
            // If it's not in, we've hit a wall. Go to game over screen.
            game.state.start('Game_Over');
        }
    
    }

When the snake collides with the apple we increase the score and the length of the snake. But when a collision with the wall or the snake body occurs, we should end the game. To do this, we need to make the Game_Over state. Again, we need to register it with main.js. Add this line near the bottom of that file:

main.js


    game.state.add('Game_Over', Game_Over);

And the state itself:

game_over.js


        var Game_Over = {

            preload : function() {
                // Load the needed image for this game screen.
                game.load.image('gameover', './assets/images/gameover.png');
            },
        
            create : function() {
        
                // Create button to start game like in Menu.
                this.add.button(0, 0, 'gameover', this.startGame, this);
        
                // Add text with information about the score from last game.
                game.add.text(235, 350, "LAST SCORE", { font: "bold 16px sans-serif", fill: "#46c0f9", align: "center"});
                game.add.text(350, 348, score.toString(), { font: "bold 20px sans-serif", fill: "#fff", align: "center" });
        
            },
        
            startGame: function () {
        
                // Change the state back to Game.
                this.state.start('Game');
        
            }
        
        };

That's it our Snake Game is Ready!!