Andreas Ludvigsson

Bridging Code and Commerce

Creating a Classic Snake Game with JavaScript

In this tutorial, we’ll walk through the process of building a classic Snake game using JavaScript and HTML5 Canvas. By the end, you’ll have a fully functional game that you can play in your web browser.

Step 1: Setting Up the HTML

First, let’s create a basic HTML structure with a canvas element:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Snake Game</title>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <script src="snake-game.js"></script>
</body>
</html>

Step 2: Setting Up the Canvas

In our JavaScript file (snake-game.js), we’ll start by setting up the canvas:

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

Step 3: Defining Game Variables

Next, let’s define our game variables:

let snake = [{x: 10, y: 10}];
let food = {x: 15, y: 15};
let dx = 0;
let dy = 0;
const gridSize = 20;
const tileCount = 20;

Step 4: Creating the Game Loop

The game loop is the heart of our game. It will continuously update and redraw the game state:

function gameLoop() {
    setTimeout(function() {
        clearCanvas();
        moveSnake();
        drawFood();
        drawSnake();
        checkCollision();
        gameLoop();
    }, 100);
}

Step 5: Implementing Game Functions

Now, let’s implement the functions we called in our game loop:

function clearCanvas() {
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function moveSnake() {
    const head = {x: snake[0].x + dx, y: snake[0].y + dy};
    snake.unshift(head);
    if (head.x === food.x && head.y === food.y) {
        generateFood();
    } else {
        snake.pop();
    }
}

function drawSnake() {
    ctx.fillStyle = 'green';
    snake.forEach(segment => {
        ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
    });
}

function drawFood() {
    ctx.fillStyle = 'red';
    ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);
}

function generateFood() {
    food.x = Math.floor(Math.random() * tileCount);
    food.y = Math.floor(Math.random() * tileCount);
}

function checkCollision() {
    const head = snake[0];
    if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
        resetGame();
    }
    for (let i = 1; i < snake.length; i++) {
        if (head.x === snake[i].x && head.y === snake[i].y) {
            resetGame();
        }
    }
}

function resetGame() {
    snake = [{x: 10, y: 10}];
    food = {x: 15, y: 15};
    dx = 0;
    dy = 0;
}

Step 6: Handling User Input

To control the snake, we’ll add an event listener for keyboard input:

document.addEventListener('keydown', function(e) {
    switch(e.key) {
        case 'ArrowUp':
            if (dy === 0) { dx = 0; dy = -1; }
            break;
        case 'ArrowDown':
            if (dy === 0) { dx = 0; dy = 1; }
            break;
        case 'ArrowLeft':
            if (dx === 0) { dx = -1; dy = 0; }
            break;
        case 'ArrowRight':
            if (dx === 0) { dx = 1; dy = 0; }
            break;
    }
});

Step 7: Starting the Game

Finally, let’s start the game by calling our game loop:

gameLoop();

And that’s it! You now have a fully functional Snake game. The snake will grow each time it eats the food, and the game will reset if the snake hits the wall or itself.

Feel free to expand on this basic version by adding a score, increasing difficulty, or adding visual enhancements. Happy coding!

Leave a Reply

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