¡Finalmente tenemos el tutorial completo para crear uno de los juegos más icónicos de todos los tiempos! Ni más ni menos que el clásico Snake Game, donde controlás una serpiente que crece a medida que come manzanas. Este juego es famoso mundialmente, ¡y ahora lo podés hacer vos mismo usando un módulo LED 8×8!
¿De qué trata el juego?
El Snake Game es muy conocido, pero para quienes recién lo descubren, su funcionamiento es simple: controlás una serpiente que, al comer manzanas, aumenta su tamaño. El objetivo es lograr que crezca lo máximo posible sin chocar con tu propio cuerpo. Si eso pasa, ¡perdés y tenés que empezar de nuevo!
Aunque parece fácil, cuanto más grande se hace la serpiente, más difícil es evitar las colisiones. ¡Te desafiamos a completarlo sin quedar atrapado!
Materiales necesarios
Los componentes para este proyecto son muy accesibles. Acá te dejamos una lista de lo que vas a necesitar:
- Kit de iniciación Arduino
- Placa Arduino Uno
- Joystick
- Matriz LED 8×8
- Cables macho-hembra
- Buzzer
Conexiones del proyecto
A continuación, vas a encontrar el esquema de conexiones para armar el Snake Game con Arduino. Asegurate de seguirlo tal como se indica para que el código funcione correctamente. ¡Recordá conectar cada componente en su lugar!
Código de programación
Debajo de las conexiones, vas a encontrar el código que tenés que cargar en tu Arduino para que el juego funcione correctamente. ¡Solo copiá, pegá y disfrutá de tu propio Snake Game!
// Juego snake en pantalla led 8×8
#include “LedControl.h”
// Pins
const int SW_pin = 2;
const int X_pin = A0; // Pines analógicos A0 y A1
const int Y_pin = A1;
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 = ‘r’; // Inicializar dirección en ‘r’ para evitar que la serpiente no se mueva
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 = random(screenWidth); // Usar random() en lugar de rand()
foodY = random(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 < 100; i++) { // Limitar el tamaño del array a 100
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 = ‘r’; // Restablecer dirección a ‘r’
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);
}
}
}
}
}
Con este proyecto, no solo te vas a divertir jugando, sino que también vas a aprender más sobre Arduino y cómo usar sus componentes. ¡Animate y compartilo con nosotros cuando lo tengas listo!
Encontrá en nuestra web todo lo que buscás para tus proyectos, desde componentes hasta kits completos. ¡Conseguí lo necesario para transformar tus ideas en realidad!
No te pierdas nuestras próximas notas, donde vamos a presentar otros proyectos Arduino innovadores. ¡Seguí nuestras publicaciones y descubrí nuevas ideas cada semana!
Hasta la próxima.
