#include <LiquidCrystal.h>
// Definición de pines
const int potPin = A0; // Potenciómetro para desplazar
const int buttonPin1 = A1; // Botón para saltar
const int buttonPin2 = A2; // Botón para aplastar
const int buzzerPin = 8; // Pin del buzzer
// Inicialización del LCD
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
// Definición de caracteres personalizados para Mario, la tortuga y el caparazón
byte mario[8] = { B01110, B11111, B01110, B01110, B11111, B11111, B01010, B11011 };
byte tortuga[8] = { B00000, B00000, B00000, B00000, B10110, B11111, B01111, B01001 };
byte caparazon[8] = { B00000, B00000, B00000, B00000, B00000, B01110, B11111, B11111 };
// Variables para el juego
int marioPos = 0; // Posición inicial de Mario en la pantalla
int tortugaPos = 15; // Posición inicial de la tortuga en la pantalla
bool marioJumped = false; // Variable para indicar si Mario ha saltado
bool tortugaAlive = true; // Variable para indicar si la tortuga está viva o convertida en caparazón
int nivel = 1; // Nivel actual del juego
int numTortugasVivas[] = {1, 2, 3}; // Número de tortugas vivas por nivel
unsigned long lastMarioUpdateTime = 0; // Tiempo de la última actualización de Mario
unsigned long lastTurtleUpdateTime = 0;// Tiempo de la última actualización de la tortuga
unsigned long marioUpdateInterval = 100; // Intervalo de actualización de Mario en milisegundos
unsigned long turtleUpdateInterval = 1000; // Intervalo de actualización de la tortuga en milisegundos
// Variables para debounce del botón de salto
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // Ajusta este valor según sea necesario
// Funciones para el juego
void setup() {
// Configuración de pines como entrada con resistencia pull-up interna
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
// Crear caracteres personalizados para Mario, tortuga y caparazon
lcd.createChar(0, mario);
lcd.createChar(1, tortuga);
lcd.createChar(2, caparazon);
// Inicializar la pantalla LCD
lcd.begin(16, 2);
}
void loop() {
unsigned long currentMillis = millis(); // Declarar la variable currentMillis
// Actualizar la posición de Mario
updateMario(currentMillis);
// Verificar el estado del botón de salto con debounce
checkJumpButton();
// Realizar la acción del salto si Mario no ha saltado ya
performJump();
// Si Mario ha saltado y está cayendo
handleMarioFall();
// Verificar si Mario colisiona con la tortuga
checkCollision();
// Actualizar la posición de la tortuga
updateTurtle(currentMillis);
delay(100); // Pausa para controlar la velocidad de actualización del juego
}
void resetGame() {
lcd.clear();
marioPos = 0;
tortugaPos = 15;
marioJumped = false;
tortugaAlive = true;
}
void moveTurtle() {
if (tortugaPos < 8) {
tortugaPos--; // Mover la tortuga hacia la izquierda
if (tortugaPos < 0) {
tortugaAlive = true; // Si la tortuga sale de la pantalla, revivirla
}
} else {
tortugaPos++; // Mover la tortuga hacia la derecha
if (tortugaPos > 15) {
tortugaAlive = true; // Si la tortuga sale de la pantalla, revivirla
}
}
}
void updateMario(unsigned long currentMillis) {
if (currentMillis - lastMarioUpdateTime >= marioUpdateInterval) {
lastMarioUpdateTime = currentMillis;
int potValue = analogRead(potPin);
potValue = 1023 - potValue;
marioPos = map(potValue, 0, 1023, 0, 15);
lcd.clear();
lcd.setCursor(marioPos, 1);
lcd.write((uint8_t)0);
lcd.setCursor(tortugaPos, 1);
lcd.write((uint8_t)1);
// Restablecer marioJumped a false si Mario está en la posición inicial y no está saltando
if (marioPos == 0 && marioJumped) {
marioJumped = false;
}
}
}
void updateTurtle(unsigned long currentMillis) {
if (currentMillis - lastTurtleUpdateTime >= turtleUpdateInterval) {
lastTurtleUpdateTime = currentMillis;
if (tortugaAlive) {
tortugaPos--;
if (tortugaPos < 0) {
tortugaPos = 15;
}
} else {
moveTurtle();
// Ajustar la velocidad de actualización para el caparazón
if (!tortugaAlive) {
turtleUpdateInterval = 200; // Por ejemplo, actualizar más rápido cuando es un caparazón
// Verificar si el caparazón alcanza las posiciones de las orillas
if (tortugaPos == 0 || tortugaPos == 15) {
lcd.clear(); // Limpiar la pantalla antes de mostrar el mensaje
lcd.setCursor(4, 0);
lcd.print("YOU WIN");
playVictorySound(); // Llama a la función para reproducir la música de victoria
delay(2000);
resetGame
}
} else {
turtleUpdateInterval = 1000; // Volver a la velocidad normal cuando es una tortuga viva
}
}
}
}
void checkJumpButton() {
int buttonState = digitalRead(buttonPin1);
static int lastButtonState = HIGH;
static unsigned long lastPressTime = 0;
if (buttonState != lastButtonState && millis() - lastPressTime > debounceDelay) {
lastPressTime = millis();
lastButtonState = buttonState;
if (buttonState == LOW && !marioJumped) {
marioJumped = true;
tone(buzzerPin, 440, 20);
delay(10);
}
}
}
void playVictorySound() {
tone(buzzerPin, 659, 200); // Do
delay(250);
tone(buzzerPin, 784, 200); // Sol
delay(250);
tone(buzzerPin, 987, 400); // Si
delay(500);
}
void playGameOverSound() {
tone(buzzerPin, 494, 100); // Primer tono
delay(150);
tone(buzzerPin, 698, 250); // Segundo tono
delay(150);
tone(buzzerPin, 698, 100); // Tercer tono
delay(150);
tone(buzzerPin, 698, 100); // Cuarto tono
delay(150);
tone(buzzerPin, 698, 100); // Cuarto tono
delay(150);
tone(buzzerPin, 659, 100); // Quinto tono
delay(150);
tone(buzzerPin, 587, 100); // Sexto tono
delay(150);
tone(buzzerPin, 523, 200); // Séptimo tono
delay(250);
}
void checkCollision() {
// Verificar si Mario y la tortuga están en la misma posición
if (marioPos == tortugaPos && !marioJumped) {
// Si la tortuga está viva, reiniciar el juego
if (tortugaAlive) {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("YOU LOST");
playGameOverSound();
delay(2000); // Esperar 2 segundos antes de reiniciar
// Restablecer todas las variables del juego
resetGame();
}
}
}
void performJump() {
if (marioJumped) {
lcd.setCursor(marioPos, 1);
lcd.print(" ");
lcd.setCursor(marioPos, 0);
lcd.write((uint8_t)0);
delay(700);
}
}
void handleMarioFall() {
if (marioJumped) {
if (marioPos == tortugaPos) {
lcd.setCursor(tortugaPos, 1);
lcd.write((uint8_t)2);
// Aplastar la tortuga y convertirla en un caparazón
tortugaAlive = false;
} else {
lcd.setCursor(marioPos, 0);
lcd.print(" ");
lcd.setCursor(marioPos, 1);
lcd.write((uint8_t)0);
marioPos++;
}
if (marioPos > 1) {
marioJumped = false;
marioPos = 0;
}
delay(100);
} else if (!tortugaAlive) {
lcd.setCursor(tortugaPos, 1);
lcd.write((uint8_t)2);
lcd.setCursor(4, 0);
lcd.print("YOU WIN");
playVictorySound(); // Llama a la función para reproducir la música de victoria
}
}