#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1 // Pin de reset (usualmente no es necesario)
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_ADDRESS 0x3C
// Pines de LED y botones
#define LED_VERDE 0
#define LED_BLANCO 15
#define LED_AZUL 2
#define LED_AMARILLO 19
#define LED_ROJA 23
#define BTN_VERDE 5
#define BTN_BLANCO 16
#define BTN_AZUL 17
#define BTN_AMARILLO 4
#define BTN_ROJO 18
#define SPEAKER_PIN 27
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int score = 0;
int sequence[100]; // Arreglo para almacenar la secuencia de LEDs
int userInput[100]; // Arreglo para almacenar las entradas del usuario
int level = 0; // Nivel actual del juego
int userIndex = 0; // Índice de entrada del usuario
bool gameStarted = false;
bool gameOver = false;
void setup() {
// Inicializar pantalla OLED
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
while (true); // Quedarse aquí si la pantalla OLED falla
}
showStartScreen();
// Inicializar pines de LED y botones
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_BLANCO, OUTPUT);
pinMode(LED_AZUL, OUTPUT);
pinMode(LED_AMARILLO, OUTPUT);
pinMode(LED_ROJA, OUTPUT);
pinMode(BTN_VERDE, INPUT_PULLUP);
pinMode(BTN_BLANCO, INPUT_PULLUP);
pinMode(BTN_AZUL, INPUT_PULLUP);
pinMode(BTN_AMARILLO, INPUT_PULLUP);
pinMode(BTN_ROJO, INPUT_PULLUP);
pinMode(SPEAKER_PIN, OUTPUT);
}
void loop() {
if (!gameStarted && !gameOver) {
// Esperar a que se presione cualquier botón para iniciar el juego
if (buttonPressed()) {
gameStarted = true;
playStartMusic(); // Reproducir música de inicio
delay(300); // Pequeño retraso para evitar que el primer clic cuente como jugada
level = 1;
addNextToSequence(); // Añadir el primer elemento a la secuencia
playSequence();
showClicksRemaining(level); // Mostrar la cantidad de clics que se deben hacer
}
} else if (gameOver) {
// Esperar a que se presione cualquier botón para reiniciar el juego
if (buttonPressed()) {
resetGame();
}
} else {
// Verificar si algún botón es presionado y compararlo con la secuencia
int button = readButton();
if (button != 0) {
playButtonSound(button); // Reproducir sonido al presionar el botón
handleButtonPress(button);
}
}
}
void playStartMusic() {
tone(SPEAKER_PIN, 523, 200); // Nota C5
delay(200);
tone(SPEAKER_PIN, 587, 200); // Nota D5
delay(200);
tone(SPEAKER_PIN, 659, 200); // Nota E5
delay(200);
tone(SPEAKER_PIN, 784, 200); // Nota G5
delay(200);
noTone(SPEAKER_PIN);
}
void playSequence() {
userIndex = 0;
for (int i = 0; i < level; i++) {
lightRandomLED(sequence[i]);
delay(500); // Pausa entre los LEDs
}
}
void addNextToSequence() {
sequence[level - 1] = random(1, 6); // Añadir un nuevo LED aleatorio a la secuencia
}
int readButton() {
// Lee el estado de los botones y devuelve el número correspondiente
if (digitalRead(BTN_VERDE) == LOW) {
delay(100); // Debounce
if (digitalRead(BTN_VERDE) == LOW) {
return 1;
}
}
if (digitalRead(BTN_BLANCO) == LOW) {
delay(100); // Debounce
if (digitalRead(BTN_BLANCO) == LOW) {
return 2;
}
}
if (digitalRead(BTN_AZUL) == LOW) {
delay(100); // Debounce
if (digitalRead(BTN_AZUL) == LOW) {
return 3;
}
}
if (digitalRead(BTN_AMARILLO) == LOW) {
delay(100); // Debounce
if (digitalRead(BTN_AMARILLO) == LOW) {
return 4;
}
}
if (digitalRead(BTN_ROJO) == LOW) {
delay(100); // Debounce
if (digitalRead(BTN_ROJO) == LOW) {
return 5;
}
}
return 0; // No se presionó ningún botón
}
void playButtonSound(int button) {
switch (button) {
case 1:
tone(SPEAKER_PIN, 440, 100); // Nota A4 (La)
break;
case 2:
tone(SPEAKER_PIN, 494, 100); // Nota B4 (Si)
break;
case 3:
tone(SPEAKER_PIN, 523, 100); // Nota C5 (Do)
break;
case 4:
tone(SPEAKER_PIN, 587, 100); // Nota D5 (Re)
break;
case 5:
tone(SPEAKER_PIN, 659, 100); // Nota E5 (Mi)
break;
}
delay(100);
noTone(SPEAKER_PIN);
}
void handleButtonPress(int button) {
userInput[userIndex] = button;
userIndex++;
showClicksRemaining(level - userIndex); // Actualizar y mostrar la cantidad de clics restantes
if (userIndex == level) {
if (checkSequence()) {
level++;
showHappyFace();
delay(1000);
addNextToSequence(); // Añadir un nuevo elemento a la secuencia
playSequence();
showClicksRemaining(level); // Mostrar la nueva cantidad de clics para la siguiente ronda
} else {
endGame();
}
}
}
bool checkSequence() {
for (int i = 0; i < level; i++) {
if (userInput[i] != sequence[i]) {
return false;
}
}
return true;
}
void lightRandomLED(int led) {
// Apagar todos los LEDs antes de encender uno nuevo
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_BLANCO, LOW);
digitalWrite(LED_AZUL, LOW);
digitalWrite(LED_AMARILLO, LOW);
digitalWrite(LED_ROJA, LOW);
switch (led) {
case 1:
digitalWrite(LED_VERDE, HIGH);
tone(SPEAKER_PIN, 261, 200); // Nota C4 (Do)
delay(500); // Mantener encendido el LED por 0.5 segundos
digitalWrite(LED_VERDE, LOW);
break;
case 2:
digitalWrite(LED_BLANCO, HIGH);
tone(SPEAKER_PIN, 329, 200); // Nota E4 (Mi)
delay(500); // Mantener encendido el LED por 0.5 segundos
digitalWrite(LED_BLANCO, LOW);
break;
case 3:
digitalWrite(LED_AZUL, HIGH);
tone(SPEAKER_PIN, 392, 200); // Nota G4 (Sol)
delay(500); // Mantener encendido el LED por 0.5 segundos
digitalWrite(LED_AZUL, LOW);
break;
case 4:
digitalWrite(LED_AMARILLO, HIGH);
tone(SPEAKER_PIN, 523, 200); // Nota C5 (Do alto)
delay(500); // Mantener encendido el LED por 0.5 segundos
digitalWrite(LED_AMARILLO, LOW);
break;
case 5:
digitalWrite(LED_ROJA, HIGH);
tone(SPEAKER_PIN, 659, 200); // Nota E5 (Mi alto)
delay(500); // Mantener encendido el LED por 0.5 segundos
digitalWrite(LED_ROJA, LOW);
break;
}
}
void showClicksRemaining(int clicks) {
display.clearDisplay();
display.setTextSize(1.5);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 5);
display.print(F("Clicks restantes: "));
// Calcular la longitud del texto en píxeles
int16_t textWidth = String(clicks).length() * 18; // Ancho del texto (cada dígito tiene 18 píxeles de ancho)
int16_t posX = (128 - textWidth) / 2; // Centrar el texto (suponiendo una pantalla de 128 píxeles de ancho)
display.setTextSize(4);
display.setCursor(posX, 25); // Ajuste X para centrar, Y se mantiene en 20
display.print(clicks);
display.display();
}
void showHappyFace() {
// Mostrar una cara feliz
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 10);
display.setTextSize(1);
display.setCursor(5, 10);
display.print(F("Muy bien"));
// Dibujar una cara feliz
display.drawCircle(100, 40, 10, SSD1306_WHITE); // Cabeza
display.fillCircle(96, 38, 2, SSD1306_WHITE); // Ojo izquierdo
display.fillCircle(104, 38, 2, SSD1306_WHITE); // Ojo derecho
// Boca (simplificada con una curva)
display.drawLine(95, 43, 97, 45, SSD1306_WHITE); // Línea izquierda
display.drawLine(97, 45, 100, 46, SSD1306_WHITE); // Línea central izquierda
display.drawLine(100, 46, 103, 45, SSD1306_WHITE); // Línea central derecha
display.drawLine(103, 45, 105, 43, SSD1306_WHITE); // Línea derecha
display.display();
// Reproducir música de victoria
tone(SPEAKER_PIN, 523, 200); // Nota C5
delay(200);
tone(SPEAKER_PIN, 659, 200); // Nota E5
delay(200);
tone(SPEAKER_PIN, 784, 200); // Nota G5
delay(200);
noTone(SPEAKER_PIN);
}
void endGame() {
gameOver = true;
// Apagar todos los LEDs
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_BLANCO, LOW);
digitalWrite(LED_AZUL, LOW);
digitalWrite(LED_AMARILLO, LOW);
digitalWrite(LED_ROJA, LOW);
// Mostrar mensaje de Game Over y el puntaje final con una cara triste
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 5);
display.println(F("Game Over!"));
display.setTextSize(1);
display.setCursor(5, 40);
display.print(F("Total: "));
display.setTextSize(2);
display.setCursor(55, 35);
display.print(level - 1);
// Dibujar una cara triste
display.drawCircle(100, 40, 10, SSD1306_WHITE); // Cabeza
display.fillCircle(96, 38, 2, SSD1306_WHITE); // Ojo izquierdo
display.fillCircle(104, 38, 2, SSD1306_WHITE); // Ojo derecho
display.drawLine(95, 44, 105, 44, SSD1306_WHITE); // Boca triste
display.display();
// Reproducir sonido de Game Over
playGameOverTone();
}
void playGameOverTone() {
tone(SPEAKER_PIN, 300, 500);
delay(500);
tone(SPEAKER_PIN, 250, 500);
delay(500);
tone(SPEAKER_PIN, 200, 500);
delay(500);
}
void resetGame() {
gameStarted = false;
gameOver = false;
level = 0;
showStartScreen();
}
void showStartScreen() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20, 10);
display.setTextSize(1);
display.setCursor(5, 10);
display.println(F("Da click en cualquier botón para iniciar"));
display.display();
}
bool buttonPressed() {
if (digitalRead(BTN_VERDE) == LOW || digitalRead(BTN_BLANCO) == LOW || digitalRead(BTN_AZUL) == LOW || digitalRead(BTN_AMARILLO) == LOW || digitalRead(BTN_ROJO) == LOW) {
delay(200); // Debounce
return true;
}
return false;
}