Minijuego con Arduino: «Snake game con una matriz 8×8»

Por fin tenemos el tutorial completo de uno de los mini juegos mas famosos del mundo. Ni mas ni menos que el mítico juego de la serpiente que a medida que se va comiendo manzanas va creciendo. Este juego también es muy conocido por su nombre en ingles «Snake Game». 

Bueno bueno, pero eso no es todo, este juego esta realizado solamente con un modulo de leds 8×8. Si, en efecto, el típico que traen todos los kits de Arduino básicos.

Si te interesa como realizar este proyecto de forma muy fácil y rápida, quédate en esta pagina. 

En esta pagina encontraras el código de programación, el esquema de conexiones y un video explicando el proyecto completo en YouTube.

 

Explicación, Objetivo y Funcionamiento del minijuego

Bueno, creo que esta vez es un mini juego tan famoso, que no hace falta ni explicar su funcionamiento, pero bueno, vamos a hacerlo por si acaso que seguro que hay alguien que seguro que no sabe de que juego estamos hablando.

El funcionamiento de este juego es muy fácil. Consiste en una serpiente que a medida que va comiendo manzanas va aumentando su tamaño. ¿El objetivo? Ser cada vez más y más grande, hasta que llegue un punto que no quepa en la pantalla, que es cuando se considera que oficialmente el juego esta terminado. La gracia esta en que si te chocas con tu propio cuerpo, pierdes y te toca volver a empezar de 0.

¿Parece fácil eh? Pues te reto a que intentes pasártelo, ya que cuanto más grande es la serpiente, más fácil es quedarse encerrado sin salida y acabar chocándote con tu propio cuerpo.

Bueno, ¿Estas listo? VAMOS AL LIO!

 

Materiales

Los materiales para realizar este proyecto son muy sencillos y no debería de ser ningún problema conseguirlos, aun así, para que te sea más fácil, aquí tienes una lista con todos los componentes.

A continuación tienes una lista con los enlaces de compra en diferentes sitios.

 

Si tienes alguna duda sobre los materiales que se utilizan en este proyecto, no dudes en dejar un comentario, te responderemos lo antes posible.

Para conocer más a fondo sobre cada uno de los diferentes materiales, puedes visitar la página «materiales» donde se explica de una forma más extensa el funcionamiento y los posibles usos de cada uno de ellos.

Puedes encontrar más herramientas y materiales que puedas necesitar para tus proyectos AQUÍ.

 

Video explicación del proyecto

Si lo que buscas es ver de una forma mucho más detallada de como realizar este proyecto desde el inicio hasta el final y una explicación del código, a continuación se muestra el video con dicho contenido, mucho mas visual y fácil de comprender. Y recuerda, si te gusta esta clase de contenido, no olvides suscribirte 😉

 

 

Esquema de conexiones Arduino para montar el proyecto

Para que te sea más fácil montar este proyecto, aquí tienes el esquema de conexiones. Todas las conexiones de este esquema corresponden con el código de programación que hay justo abajo, así que asegúrate de que todas están tal y como se muestra en esta imagen. 

 

Código de Arduino para la programación del proyecto

A continuación se muestra el código de programación desarrollado específicamente para este proyecto. Los pines que puedes encontrar en el código son los mismos que encontrarás en el esquema de conexiones previamente mostrado.

Si quieres una explicación más detallada de las diferentes partes del código empleado para programar este proyecto y de su funcionamiento, te recomiendo que te veas el video que te hemos dejado más arriba.

//Canal de YouTube -> RobotUNO
//Juego snake en pantalla led 8x8
#include "LedControl.h"
//pins
const int SW_pin = 2;
const int X_pin = 0;
const int Y_pin = 1;
const int DIN = 12;
const int CS = 11;
const int CLK = 10;
const int BUZZER = 8;
//variables
const int screenWidth = 8;
const int screenHeight = 8;
int snakeX, snakeY, foodX, foodY, score = 0, snakeSize = 1;
char direction;
int tailX[100], tailY[100];
bool isGameOver = false;
LedControl lc = LedControl(DIN, CS, CLK, 1);
void setup() {
  setupPins();
  setupLedBoard();
  setupSnakePosition();
  setupFoodPosition();
}
void setupSnakePosition() {
  snakeX = 4;
  snakeY = 4;
}
void setupFoodPosition() {
  foodX = rand() % screenWidth;
  foodY = rand() % screenHeight;
}
void setupLedBoard() {
  lc.shutdown(0, false);
  lc.setIntensity(0, 1);
  lc.clearDisplay(0);
}
void setupPins() {
  pinMode(SW_pin, INPUT);
  digitalWrite(SW_pin, HIGH);
}
void loop() {
  if (isGameOver) {
    playGameOverSong();
    showGameOverScreen();
  } else {
    startGame();
  }
}
void playGameOverSong() {
  tone(BUZZER, 1000, 1000);
  delay(100);
  tone(BUZZER, 2000, 1000);
  delay(100);
  tone(BUZZER, 3000, 1000);
  delay(100);
  tone(BUZZER, 4000, 1000);
  delay(100);
  tone(BUZZER, 5000, 2000);
}
void playFoodEatenSong() {
  tone(BUZZER, 500, 100);
}
void startGame() {
  manageGameOver();
  setJoystickDirection();
  changeSnakeDirection();
  manageSnakeOutOfBounds();
  manageEatenFood();
  manageSnakeTailCoordinates();
  drawSnake();
  delay(300);
}
void manageGameOver() {
  for (int i = 1; i < snakeSize; i++) {
    if (tailX[i] == snakeX && tailY[i] == snakeY) {
      isGameOver = true;
    }
  }
}
void manageSnakeOutOfBounds() {
  if (snakeX >= screenWidth) {
    snakeX = 0;
  } else if (snakeX < 0) {
    snakeX = screenWidth - 1;
  }
  if (snakeY >= screenHeight) {
    snakeY = 0;
  } else if (snakeY < 0) {
    snakeY = screenHeight - 1;
  }
}
void manageSnakeTailCoordinates() {
  int previousX, previousY, prevX, prevY;
  previousX = tailX[0];
  previousY = tailY[0];
  tailX[0] = snakeX;
  tailY[0] = snakeY;

  for (int i = 1; i < snakeSize; i++) {
    prevX = tailX[i];
    prevY = tailY[i];
    tailX[i] = previousX;
    tailY[i] = previousY;
    previousX = prevX;
    previousY = prevY;
  }
}
void manageEatenFood() {
  if (snakeX == foodX && snakeY == foodY) {
    playFoodEatenSong();
    score++;
    snakeSize++;
    setupFoodPosition();
  }
}
void setJoystickDirection() {
  if (analogRead(X_pin) > 1000) {
    direction = 'u';
  } else if (analogRead(X_pin) < 100) {
    direction = 'd';
  } else if (analogRead(Y_pin) > 1000) {
    direction = 'l';
  } else if (analogRead(Y_pin) < 100) {
    direction = 'r';
  }
}
void changeSnakeDirection() {
  switch (direction) {
    case 'l':
      snakeX--;
      break;
    case 'r':
      snakeX++;
      break;
    case 'u':
      snakeY--;
      break;
    case 'd':
      snakeY++;
      break;
  }
}
void showGameOverScreen() {
  for (int i = 0; i < screenHeight; i++) {
    for (int j = 0; j < screenWidth; j++) {
      showLed(j, i);
      delay(50);
    }
  }
  resetVariables();
}
void resetVariables() {
  setupSnakePosition();
  setupFoodPosition();
  direction = ' ';
  isGameOver = false;
  score = 0;
  snakeSize = 1;
}
void showLed(int row, int column) {
  lc.setLed(0, row, column, true);
}
void hideLed(int row, int column) {
  lc.setLed(0, row, column, false);
}
void drawSnake() {
  for (int i = 0; i < screenHeight; i++) {
    for (int j = 0; j < screenWidth; j++) {
      if (i == snakeY && j == snakeX) {
        showLed(snakeX, snakeY);
      } else if (i == foodY && j == foodX) {
        showLed(foodX, foodY);
      } else {
        bool isShown = false;
        for (int k = 0; k < snakeSize; k++) {
          if (tailX[k] == j && tailY[k] == i) {
            showLed(j, i);
            isShown = true;
          }
        }
        if (!isShown) {
          hideLed(j, i);
        }
      }
    }
  }
}

 

Lo que debes de hacer para utilizar este código es muy sencillo, simplemente tienes que copiarlo y pegarlo en tu compilador de Arduino (por ejemplo, Arduino IDE). Si no lo tienes instalado, haz click aquí para ver un tutorial sobre como instalártelo de forma totalmente gratuita.

 

Si tienes cualquier duda, deja un comentario en esta pagina y te responderemos lo antes posible.

Publicado en Minijuegos.

3 Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *