Creare “Snake” il gioco con JavaScript

Amante dei giochi classici? Ricorderai sicuramente “Snake“, uno dei giochi per cellulari più famosi della storia, presente in particolare nei dispositivi Nokia.
Chiunque abbia posseduto uno di questi cellulari, avrà sicuramente passato fantastici e impegnativi momenti nel tentativo di far diventare il più lungo possibile il serpentello digitale, cercando di battere il suo stesso record.

snake su nokia

Nostalgia a parte, in questo articolo voglio proporre una versione realizzata con linguaggio JavaScript del videogioco “snake”, giocabile con qualsiasi dispositivo con un semplice browser web.

Snake programmato con JavaScript

Di seguito ti mostrerò il codice completo JavaScript per programmare un mini videogioco Snake-style, cioè di un “serpentello” che da la caccia al cibo per crescere, che in caso di contatto con i bordi dello schermo/canvas, finirà game over.

snake game javascript image

Il serpente è manovrabile dal giocatore con i quattro tasti freccia della tastiera (su, giù, destra, sinistra).

Per usare il codice, copia e incolla il contenuto in un semplice file in formato .html, racchiudendolo nei tag <script> e </script>.

Qui il codice:

// Creazione del canvas
var canvas = document.createElement("canvas");
canvas.style.backgroundColor = "#03326B";
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);

//dimesione canvas
var canvasSize = 400;
canvas.width = canvasSize;
canvas.height = canvasSize;


  // scritta iniziale 
  ctx.fillStyle = "lightgreen";
  ctx.font = "40px monospace";
  ctx.fillText("PLAY SNAKE", canvasSize/2 - 100, canvasSize/2 - 20);
  
// Variabili di gioco
//		dimensione punto griglia
var gridSize = 10;
var gameSpeed = 100 //millisecondi : NON MINORE DI 20!!
var gridWidth = canvas.width / gridSize;
var gridHeight = canvas.height / gridSize;
var snake = [
  { x: 2, y: 0 },
  { x: 1, y: 0 },
  { x: 0, y: 0 }
];
var direction = "right";
var food = createFood();
var score = 0;
var gameLoop;

// Posizione cibo casuale
function createFood() {
  return {
    x: Math.floor(Math.random() * gridWidth),
    y: Math.floor(Math.random() * gridHeight)
  };
}
// update gioco
function update() {
  var head = { x: snake[0].x, y: snake[0].y };
  direction = newDirection;
  // Posizione direzione
  if (direction === "up") head.y--;
  else if (direction === "down") head.y++;
  else if (direction === "left") head.x--;
  else if (direction === "right") head.x++;

  // Collisione canvas
  if (head.x < 0 || head.x >= gridWidth || head.y < 0 || head.y >= gridHeight) {
    // Fine del gioco
    clearInterval(gameLoop);
    drawGameOver();
    resetGame() 
    return;
  }

  // Collisione corpo
  for (var i = 1; i < snake.length; i++) {
    if (snake[i].x === head.x && snake[i].y === head.y) {
      // Fine del gioco
      clearInterval(gameLoop);
      drawGameOver();
      resetGame() 
      return;
    }
  }

  // Posizione della testa
  snake.unshift(head);

  // Conta del cibo
  if (head.x === food.x && head.y === food.y) {
    // Genera nuovo cibo e aumenta la lunghezza dello snake
    food = createFood();
    score++; // Incrementa il punteggio
  } else {
    // Rimuove la coda dello snake
    snake.pop();
  }

  // Sfondo
  ctx.fillStyle = "#00295B";
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  // Cibo
  ctx.fillStyle = "#f00";
  ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);

  // Snake
  ctx.fillStyle = "#0f0";
  snake.forEach(function(segment) {
    ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
  });

  // Punteggio
  ctx.fillStyle = "#fff";
  ctx.font = "20px monospace";
  ctx.fillText("Score: " + score, 10, 30);
}

// pulsanti direzione
var newDirection = direction;

function handleInput(event) {
  if (event.keyCode === 38 && direction !== "down") {
    newDirection = "up";
  } else if (event.keyCode === 40 && direction !== "up") {
    newDirection = "down";
  } else if (event.keyCode === 37 && direction !== "right") {
    newDirection = "left";
  } else if (event.keyCode === 39 && direction !== "left") {
    newDirection = "right";
  }
}

document.addEventListener("keydown", handleInput);

// Avvia il gioco
function startGame() {
  if (!gameLoop) {
    gameLoop = setInterval(update, gameSpeed);
    document.getElementById("playButton").style.display = "none"; // Nasconde il pulsante "PLAY" una volta avviato il gioco
  }
}
// "Game Over"
function drawGameOver() {
  ctx.fillStyle = "#fff";
  ctx.font = "25px monospace";
  ctx.fillText("Game Over", 10, 60);
}

// Reset gioco
function resetGame() {
  snake = [
    { x: 2, y: 0 },
    { x: 1, y: 0 },
    { x: 0, y: 0 }
  ];
  direction = "right";
  food = createFood();
  score = 0;
  gameLoop = null;
  document.getElementById("playButton").style.display = "block"; 
}

// Play Button
var playButton = document.createElement("button");
playButton.textContent = "PLAY NOW";
playButton.id = "playButton";
playButton.addEventListener("click", startGame);
document.body.appendChild(playButton);

Ricorda di inserire questo codice tra il tag <script> e </script>.

A questo punto ti basta aprire il file con un browser web qualsiasi, come Chrome, Edge etc..

Gioca ora online!

Qui in basso puoi provare il gioco online, ospitato su Codewith.it. Clicca sul link per vedere e modificare il codice sorgente.

Spiegazione del codice JavaScript

Questa sezione è dedicata ai più curiosi, che vogliono avere maggiori informazioni sul funzionamento del codice descritto.

Partiamo dicendo che il gioco è “auto installante“, cioè ti basta inserirlo in un documento in formato HTML e il browser in automatico creerà l’istanza di gioco, cioè il canvas in cui verranno “disegnati” gli elementi di gioco: il serpente e il cibo.

All’inizio del codice JS sono presenti tutte le variabili di configurazione, se sai cosa fare, puoi modificarle a tuo piacimento.

Il funzionamento reale è il seguente: Al momento della creazione e cliccando sul tasto “Play“, il canvas verrà aggiornato in un lasso di tempo prestabilito (100 millisecondi), dichiarato nell’ultima riga del codice JS (N.B. cambiando questo valore si potrà aumentare e diminuire la velocità di gioco, cambiando dunque la difficoltà).

Ad ogni refresh verranno aggiornate le variabili di direzione del serpente, che cambieranno di volta in volta al premere dei pulsanti “arrows” della tastiera.

Alla collisione con gli elementi “cibo”, il serpente crescerà di un’unità.

Superate le posizioni limite, ovvero ai bordi del canvas, il gioco terminerà con Game over.

Ognuno di questi eventi è descritto in apposite funzioni JavaScript, facilmente rilevabili dal codice.

Iscriviti alla nostra Newsletter qui e seguici su Facebook per aggiornamenti!


Articoli recenti:

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

CAPTCHA