Friday, January 23, 2015

Creating a simple snake game using the HTML5 canvas


Here we are using the new canvas feature in HTML5 to create a simple snake game we used to play in our childhood.



First create a canvas in your HTML page

<canvas id="drawCanvas" width="600" height="600"></canvas>


Then we declare some variables we need in our cording

var drawCanvas = $("#drawCanvas")[0];
            var context = drawCanvas.getContext("2d");
            var width = $("#drawCanvas").width();
            var height = $("#drawCanvas").height();


Then we create a start() method and save some variables and the width of the cell can be saved here.

var cell_width = 15;
            var defaultRun;
            var snake_food;
            var userscore;

the snake is created using an array of cells

var mySnakeArray;

we then create a function to start our game

function start()

the default direction of the snake is set to the right  and another function is used to make the food for the snake

defaultRun = "right";
createFood();

To display the score we use a variable

Userscore=0;

To move our snake we can use a timer that will trigger the paintSnake method every 70ms:

           if (typeof game_loop != "undefined") clearInterval(game_loop);
           game_loop = setInterval(paintSnake, 70);

Then we create the snake using the createsnake() method, here we define the size of the array and we uses an empty array to start with.

function createSnake() {
           var snakeSize = 6;
           mySnakeArray = [];
           for (var m = 0; m<snakeSize-1;m++) {

This line will create a horizontal snake starting from the middle left. You can change its position by giving the value of x or y:

mySnakeArray.push({ x: 0, y: 20 })

Here we are going to create the food for the snake

function createFood() {
                snake_food = {
                    x: Math.round(Math.random() * (width - cell_width) / cell_width),
                    y: Math.round(Math.random() * (height - cell_width) / cell_width),
                };
             }


Next we are creating a paint method that paints the snake

function paintSnake()
First we need to paint our canvas:
context.fillStyle = "#c0f0aa";
context.fillRect(0, 0, width, height);
context.strokeStyle = "0000ff";
context.strokeRect(0, 0, width, height);

Now we need to move our snake. Here, we use two variables that will pop out the last cell and it will place in front of the head cell:
            var pop_x = mySnakeArray[0].x;
            var pop_y = mySnakeArray[0].y;

These are the positions of the head cell. We need to increment it to get the new head position of our snake. Now add some proper direction based moment:

            if (defaultRun == "right") pop_x++;
            else if (defaultRun == "left") pop_x--;
            else if (defaultRun == "down") pop_y++;
            else if (defaultRun == "up") pop_y--;

Its time to add the game so it will restart our game if our snake hits the wall. Also add the body collision code so that if our snake's head bumps into the body then our game will restart:

            if (pop_x == -1 || pop_x == width / cell_width || pop_y == -1 || pop_y == height / cell_width || check_collision(pop_x, pop_y, mySnakeArray)) {

The start() method will restart our game and return helps to organize our code:

                     start();
                     return;
                }

Then we need to make the snake eat his food and this make the snake longer and that’s just by adding a new block to its array

if (pop_x == snake_food.x && pop_y == snake_food.y) {
                 var snake_tail = { x: pop_x, y: pop_y };
                 userscore++;
                 createFood();    //It will create our snakes food.
            }
            else {
                var snake_tail = mySnakeArray.pop();
                snake_tail.x = pop_x; snake_tail.y = pop_y;
            }

mySnakeArray.unshift(snake_tail);

If you remember, we declared our cell width; we now paint a 15px wide cell using "paintCell(k.x, k.y)". After that we will paint the food & score both:

            paintCell(snake_food.x, snake_food.y);               
            var score_text = "Score: " + userscore;
            context.fillText(score_text, width-50, 20);


Now create a generic function that will paint cells:

           function paintCell(x, y) {
                context.fillStyle = "orange";
                context.fillRect(x * cell_width, y * cell_width, cell_width, cell_width);
                context.strokeStyle = "red";
                context.strokeRect(x * cell_width, y * cell_width, cell_width, cell_width);
            }

This is a very important method that will check if the given x/y coordinates exist already in an array of cells or not.
            function check_collision(x, y, array) {
                for (var i = 0; i < array.length; i++) {
                    if (array[i].x == x && array[i].y == y)
                        return true;
                }
                return false;
            }

In this final step we will add the keyboard controls so that we can control our little snake from our keyboard arrow keys.

          $(document).keydown(function (e) {
                var keyInput = e.which;
We will add another clause to prevent reverse gear:
         if (keyInput == "40" && defaultRun != "up") defaultRun = "down";
         else if (keyInput == "39" && defaultRun != "left") defaultRun = "right";
         else if (keyInput == "38" && defaultRun != "down") defaultRun = "up";
         else if (keyInput == "37" && defaultRun != "right") defaultRun = "left";

The full HTML code for this simple game is provided below


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Codemonkeyy Games</title>
    <style type="text/css">
        body {
            margin: 0 auto;
            padding : 0;
        }
    </style>
    <!-- Jquery -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
    <script>
        $(document).ready(function () {
            //Canvas stuff
            var drawCanvas = $("#drawCanvas")[0];
            var context = drawCanvas.getContext("2d");
            var width = $("#drawCanvas").width();
            var height = $("#drawCanvas").height();

            var cell_width = 15;
            var defaultRun;
            var snake_food;
            var userscore;
            var mySnakeArray;
          
           function start() {
                defaultRun = "right";
                createSnake();
                createFood();
                userscore = 0;
              
                if (typeof game_loop != "undefined") clearInterval(game_loop);
                game_loop = setInterval(paintSnake, 70);
            }
            start();

           function createSnake() {
                var snakeSize = 6;
                mySnakeArray = [];
                for (var m = 0; m<snakeSize-1;m++) {
                    mySnakeArray.push({ x: 0, y: 20 });
                }
            }

            function createFood() {
                snake_food = {
                    x: Math.round(Math.random() * (width - cell_width) / cell_width),
                    y: Math.round(Math.random() * (height - cell_width) / cell_width),
                };
             }

            function paintSnake() {
                context.fillStyle = "#c0f0aa";
                context.fillRect(0, 0, width, height);
                context.strokeStyle = "0000ff";
                context.strokeRect(0, 0, width, height);

                var pop_x = mySnakeArray[0].x;
                var pop_y = mySnakeArray[0].y;

                if (defaultRun == "right") pop_x++;
                else if (defaultRun == "left") pop_x--;
                else if (defaultRun == "down") pop_y++;
                else if (defaultRun == "up") pop_y--;
              

                 if (pop_x == -1 || pop_x == width / cell_width || pop_y == -1 || pop_y == height / cell_width || check_collision(pop_x, pop_y, mySnakeArray)) {
                     start();
                     return;
                }

                 if (pop_x == snake_food.x && pop_y == snake_food.y) {
                    var snake_tail = { x: pop_x, y: pop_y };
                    userscore++;
                     createFood();
                }
                else {
                    var snake_tail = mySnakeArray.pop();
                    snake_tail.x = pop_x; snake_tail.y = pop_y;
                }

                mySnakeArray.unshift(snake_tail);

                for (var i = 0; i < mySnakeArray.length; i++) {
                    var k = mySnakeArray[i];
               
                    paintCell(k.x, k.y);
                }

              
                paintCell(snake_food.x, snake_food.y);
              
                var score_text = "Score: " + userscore;
                context.fillText(score_text, width-50, 20);
            }

           function paintCell(x, y) {
                context.fillStyle = "orange";
                context.fillRect(x * cell_width, y * cell_width, cell_width, cell_width);
                context.strokeStyle = "red";
                context.strokeRect(x * cell_width, y * cell_width, cell_width, cell_width);
            }

            function check_collision(x, y, array) {
                for (var i = 0; i < array.length; i++) {
                    if (array[i].x == x && array[i].y == y)
                        return true;
                }
                return false;
            }

          $(document).keydown(function (e) {
                var keyInput = e.which;
                if (keyInput == "40" && defaultRun != "up") defaultRun = "down";
                else if (keyInput == "39" && defaultRun != "left") defaultRun = "right";
                else if (keyInput == "38" && defaultRun != "down") defaultRun = "up";
                else if (keyInput == "37" && defaultRun != "right") defaultRun = "left";
            })
        })
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
             <canvas id="drawCanvas" width="550" height="600"></canvas>
                                      <p>From <a href="http://codemonkeyy.blogspot.com" rel="external">Learn to code @ "CODEMONKEYY"</a>.</p>

        </div>
    </form>
</body>
</html>







No comments:

Post a Comment