Bringing Snake Back to Life with Vanilla JavaScript

Bringing Snake Back to Life with Vanilla JavaScript

Play and reminisce here:

https://main.dnfus08ne926n.amplifyapp.com/

I’ve always had a soft spot for the classic Nokia Snake game. I remember how much I enjoyed it back in the day—such a simple concept, yet it was so addictively fun. In a world now saturated with frameworks, tools, and endless libraries, I thought, why not take it back to basics and recreate the game in vanilla JavaScript? No fancy frameworks, no shortcuts—just pure, old-school coding, like the game itself.

Why Snake?

Snake represents a nostalgic era of gaming for me and many others. It’s one of the first mobile games that sparked joy for millions, and it’s the epitome of "less is more." The concept is simple: you control a snake that grows each time it eats food, and the challenge intensifies as the snake grows longer and the space becomes tighter. I wanted to recapture that simplicity in my code, with no added complexity that a framework might introduce.

Going Back to Basics: Vanilla JavaScript

The goal was straightforward: use nothing but vanilla JavaScript, HTML, and CSS. That means no React, no Vue, no libraries like jQuery—just good old-fashioned DOM manipulation. This approach forces you to think more deeply about how to structure your code, how to efficiently manipulate the DOM, and how to handle game logic without relying on third-party tools.

Breaking Down the Code

The code structure mirrors the simplicity of the original game but is packed with all the essential logic. Everything from handling snake movement, food generation, collision detection, and keeping track of the score is handled with clean, pure JavaScript.

Snake Movement and Food Generation

The movement of the snake is the core of the game. Using keyboard events to control the direction of the snake, each tick of the game updates the snake’s position. This is all managed in the move function:

function move() {
  const head = { ...snake[0] }; // Copy the snake's head
  switch (direction) {
    case "up":
      head.y--;
      break;
    case "down":
      head.y++;
      break;
    case "left":
      head.x--;
      break;
    case "right":
      head.x++;
      break;
  }

  // Add the new head position at the front of the snake array
  snake.unshift(head); 

  // If the snake's head reaches the food, regenerate food at a new position
  if (head.y === food.y && head.x === food.x) {
    food = generateRandomFoodPosition();
    increaseSpeed();
  } else {
    // If not, remove the last part of the snake to maintain the length
    snake.pop(); 
  }
}        

Here, the game uses the switch statement to handle directional movement, and every movement updates the position of the snake’s head. It’s a simple but effective method to control the flow of the game.

Collision Detection and Game Reset

Snake isn’t much of a challenge if there are no consequences, so collision detection is crucial. If the snake’s head touches the walls or its own body, the game resets:

function checkCollision() {
  const head = snake[0]; // The snake's head
  // Check if the snake's head has collided with the boundaries
  if (head.x < 1 || head.x > gridSize || head.y < 1 || head.y > gridSize) {
    resetGame();
  }

  // Check if the snake has collided with itself
  for (let i = 1; i < snake.length; i++) {
    if (head.x === snake[i].x && head.y === snake[i].y) {
      resetGame();
    }
  }
}        

This function checks whether the snake’s head is out of bounds or if it runs into itself. If a collision is detected, the game resets, and the player gets another chance to start over.

Increasing Difficulty

A simple but fun way to increase the challenge is by speeding up the game each time the snake eats food. In the increaseSpeed function, the interval between each movement becomes shorter, giving the game a natural difficulty curve:

function increaseSpeed() {
  if (gameSpeedDelay > 150) {
    gameSpeedDelay -= 5;
  } else if (gameSpeedDelay > 100) {
    gameSpeedDelay -= 3;
  } else if (gameSpeedDelay > 50) {
    gameSpeedDelay -= 2;
  } else if (gameSpeedDelay > 25) {
    gameSpeedDelay -= 1;
  }
}        

By gradually increasing the speed, the game becomes more intense over time, just like in the original Snake.

Reset and Score Handling

The game resets when the snake collides, and the score is tracked to keep the player motivated:

function resetGame() {
  updateHighScore(); // Check if a new high score has been achieved
  stopGame(); // Stop the game
  snake = [{ x: 10, y: 10 }]; // Reset snake's position
  food = generateRandomFoodPosition(); // Generate new food position
  direction = "right"; // Reset direction
  gameSpeedDelay = 200; // Reset speed
  updateScore(); // Update the score display
}        

This function handles the game reset and makes sure the high score is updated if needed.

No Fancy Frameworks

One of the most satisfying aspects of this project was working without any frameworks. Writing in pure JavaScript made me appreciate the fundamental workings of DOM manipulation and game loops. Instead of letting a framework dictate how to structure my project, I could make it as lean as possible. The result is a game that runs smoothly and is easy to maintain.

Why Vanilla JavaScript?

In the current state of web development, it's easy to get caught up in using frameworks and libraries that sometimes add unnecessary complexity. This project reminded me how fun and rewarding it can be to code directly in JavaScript and manage everything myself—from event handling to DOM updates. It’s a great way to sharpen your core programming skills and understand the magic behind the scenes of more complex applications.

Conclusion

Recreating Snake with just vanilla JavaScript has been a nostalgic yet insightful journey. I was able to revive a game that I’ve loved for years while stripping back the complexity that modern frameworks often add to projects. It’s a fun challenge that any developer should try—especially if, like me, you have a soft spot for the classics.

Feel free to check out the code, take it for a spin, and maybe even challenge yourself to extend it with features like walls, bonuses, or multiplayer modes—just be sure to keep it simple, like the original.

要查看或添加评论,请登录

Alec Dannmayr的更多文章

社区洞察

其他会员也浏览了