{}const=>[]async()letfn</>var
JSWebDevelopment

Write your first game: Snake in JavaScript in 10 minutes 🐍

Want to feel like a game dev? Write a classic Snake with us in pure HTML and JS. It's simple, fun and with memes! Even if you're a beginner, you can do it. And then — only up 🚀

К

Kodik

Author

4 min read

🐍 Snake in pure HTML + JS: step by step and with memes!

Have you ever dreamed of writing your own game? And what about that very classic — Snakes? 😎 Today we will create a real retro game right in the browser step by step. No libraries, no frameworks — just HTML, CSS, and JavaScript.

⚠️ Spoiler: you won't just run the snake, you'll understand how it works.

And if it suddenly seems difficult to you, calm, only calm, we'll explain everything with memes and examples. Let's go! 🚀

Project demo | 📂 Download source code on GitHub

🤖 In the app Code you can learn HTML, CSS and JavaScript, as well as many other courses to start your journey in web development! 🌱


📦 Step 1: HTML — create the basis of the game

HTML is a skeleton. In it we place:

  • canvas — our canvas on which we will draw a snake and food;

  • div with buttons to start and end the game;

  • score counter.

<canvas id="game" width="320" height="320"></canvas>

🎨 Step 2: CSS — a style without which it would be boring

A little magic of styles:

  • black background

  • canvas with frame and rounded edges

  • adaptation for mobile devices (touch-action)

Buttons, headings, start and end screens are also stylized to make the game look nice.


🧠 Step 3: JavaScript is the brain of the whole snake 🧬

Now let's take a closer look at the entire game code.

1. Initialization of elements:

const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

canvas — access to the canvas element. ctx is what we will use to draw.

We also declare variables: cell size, snake direction, points, speed, and game state.

const scale = 20;
const rows = canvas.height / scale;
const columns = canvas.width / scale;
let direction = { x: 1, y: 0 };
let nextDirection = { x: 1, y: 0 };
let speed = 250;
let score = 0;

2. Snake class — the snake itself:

class Snake {
  constructor() {
    this.body = [
      { x: 5, y: 5 },
      { x: 4, y: 5 },
    ];
  }

  update() {
    const head = { ...this.body[0] };
    head.x += direction.x;
    head.y += direction.y;
    this.body.unshift(head);

    if (head.x === fruit.x && head.y === fruit.y) {
      score++;
      if (speed > 80) speed -= 5;
      placeFruit();
    } else {
      this.body.pop();
    }
  }

  draw() {
    this.body.forEach((segment, i) => {
      ctx.fillStyle = i === 0 ? "#58a6ff" : "#3fb950";
      ctx.beginPath();
      ctx.roundRect(
        segment.x * scale + 2,
        segment.y * scale + 2,
        scale - 4,
        scale - 4,
        6
      );
      ctx.fill();
    });
  }

  checkCollision() {
    const [head, ...body] = this.body;
    return (
      head.x < 0 ||
      head.x >= columns ||
      head.y < 0 ||
      head.y >= rows ||
      body.some((s) => s.x === head.x && s.y === head.y)
    );
  }
}

Explanation:

  • update() — move the snake and check if it has eaten the fruit;

  • draw() — draw each segment;

  • checkCollision() — check for collisions with boundaries or itself.

3. Food (fruit):

function placeFruit() {
  fruit = {
    x: Math.floor(Math.random() * columns),
    y: Math.floor(Math.random() * rows),
  };

  if (snake.body.some((s) => s.x === fruit.x && s.y === fruit.y)) {
    placeFruit();
  }
}

Food is placed randomly. If it lands on a snake, we generate it again.

4. Game cycle:

function gameLoop(time = 0) {
  if (!playing) return;
  const delta = time - lastTime;
  if (delta > speed) {
    direction = nextDirection;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    snake.update();
    if (snake.checkCollision()) {
      endGame();
      return;
    }
    drawFruit();
    snake.draw();
    lastTime = time;
  }
  requestAnimationFrame(gameLoop);
}

Each "frame":

  • we clear the canvas

  • move the snake

  • check for death

  • drawing food and a snake

5. Management:

Keyboard:

window.addEventListener("keydown", (e) => {
  if (e.key === "ArrowUp" && direction.y !== 1) nextDirection = { x: 0, y: -1 };
  if (e.key === "ArrowDown" && direction.y !== -1) nextDirection = { x: 0, y: 1 };
  if (e.key === "ArrowLeft" && direction.x !== 1) nextDirection = { x: -1, y: 0 };
  if (e.key === "ArrowRight" && direction.x !== -1) nextDirection = { x: 1, y: 0 };
});

Swipes:

canvas.addEventListener("touchstart", (e) => { ... });
canvas.addEventListener("touchend", (e) => { ... });

💀 End of the game:

function endGame() {
  playing = false;
  canvas.style.display = "none";
  scoreDisplay.style.display = "none";
  gameOverScreen.style.display = "flex";
  finalScore.textContent = `You scored ${score} points`;
}

✅ Conclusion: you have become a snake master 🐍

You didn't just write the code — you understood how the game logic works. This is a huge step!

Want to learn more? Fly into Code - there is a lot of practice, explanations in simple language and fun tasks.

🎯Stop procrastinating

Liked the article?
Time to practice!

In Kodik, you don't just read — you write code immediately. Theory + practice = real skills.

Instant practice
🧠AI explains code
🏆Certificate

No registration • No card