Juego Arcade Whac-A-Mole DIY (Edición Botones) – Proyecto Arduino
Componentes y Suministros
| Componente | Cantidad | Notas |
|---|---|---|
| Arduino Mega 2560 | 1 | |
| Display 7 segmentos 4 dígitos 1.4" I2C (Adafruit) | 2 | Elige el color que quieras |
| Botón arcade grande con LED 60mm (Adafruit) | 5 | Elige 5 colores diferentes |
| Placa Audio FX 16MB (Adafruit) | 1 | |
| Amplificador 2.5W (Adafruit) | 2 | |
| Altavoz 3W, 4 ohm | 2 | |
| Botón on/off con LED (Adafruit) | 1 | |
| Potenciómetro 10k (Adafruit) | 2 | |
| Perilla para potenciómetro (Adafruit) | 2 | |
| Cable | 1 | |
| Tornillos avellanados M3 + tuercas | 1 | |
| Tornillos avellanados M4 + tuercas | 1 | |
| Todas las piezas impresas en 3D | 1 | |
| Todas las piezas de MDF cortadas por láser | 1 | |
| Shield Arduino Mega personalizado | 1 | |
| Headers apilables Arduino Mega (para espaciado) | 1 | |
| Convertidor DC step-down 5V 3A (Adafruit) | 1 | |
| Fuente 12V | 1 | |
| Bus hembra PSU | 1 | |
| USB-B panel mount | 1 |
Herramientas y Máquinas Necesarias
- Impresora 3D (genérica)
- Destornillador
- Soldador (genérico)
Aplicaciones y Servicios Online
- Arduino IDE
- Servicio de corte láser MDF
Sobre el Proyecto
Este es un juego Whac-A-Mole personalizado. Por ahora está programado con un juego básico, pero es posible crear actualizaciones en el futuro.
Características Principales
- 5 botones para el juego. Cada botón tiene su propio LED brillante. Los LEDs son controlados por PWM (usados en la secuencia de game-over).
- 10 niveles seleccionables. Nivel 1 (fácil) hasta 10 (insano). Durante el juego debes pulsar el botón correcto dentro de un tiempo determinado. Esta duración es variable dentro de cada nivel (a veces debes pulsar más rápido que en otros pasos).
- Selección de botón (pseudo)aleatoria durante el juego. El siguiente paso (botón a pulsar) es siempre un botón diferente.
- 2 displays LED de dígitos. Uno para puntuación actual/cuenta atrás/selección de nivel y otro para mostrar la puntuación máxima.
- Control de volumen digital
- Almacenamiento de puntuación máxima
- Efectos de sonido. Durante varios estados del juego se reproducen bucles de sonido a través de los altavoces integrados.
- Recinto cortado por láser
- Muchas piezas impresas en 3D
- Shield Arduino Mega personalizado
Recinto
Primero, empieza montando el recinto.


Monta los soportes de montaje impresos en 3D en la tapa superior.

Si lo deseas, pinta el recinto.
Luego, monta los soportes de los displays LED. No olvides colocar los tornillos debajo de los soportes, de lo contrario las barras verticales no se pueden fijar.

Monta el shield Arduino. Usé un set extra de headers apilables, para tener más espacio entre el shield y el Arduino.

Monta el panel de control trasero.

Monta la tapa superior (botones y paneles LED).




El panel de control trasero incluye dos controles de potenciómetro: uno para control de volumen, otro para selección de nivel.


Conclusiones
¡Terminado!
En el panel LED izquierdo ves el nivel seleccionado. Puedes elegir nivel 1 (fácil) hasta 10 (insano). En el panel derecho ves la puntuación máxima para el nivel correspondiente. Durante una partida activa el panel izquierdo muestra la puntuación actual. Ahora pulsa el botón verde para iniciar el juego. Tras una cuenta atrás el juego comenzará.

Código
- Whac_A_Mole_v1.0.0
Whac_A_Mole_v1.0.0Arduino
Código Arduino, escrito en Visual Studio
/* Whac_A_Mole_v1.0.0 By WT040 */
#include "Wire.h"
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_7segment matrix1 = Adafruit_7segment();
Adafruit_7segment matrix2 = Adafruit_7segment();
#define debounceTime 10
// controles potenciómetro
#define potmeterVolume 0
#define potmeterGameLevel 1
// pin alimentación amplificador
#define ampPower 32
// botones
#define btn1Pin 22
#define btn2Pin 24
#define btn3Pin 26
#define btn4Pin 28
#define btn5Pin 30
byte btnArray[] = { btn1Pin, btn2Pin, btn3Pin, btn4Pin, btn5Pin };
#define btn1 0
#define btn2 1
#define btn3 2
#define btn4 3
#define btn5 4
// LEDs botones
#define btnLed1Pin 9
#define btnLed2Pin 10
#define btnLed3Pin 11
#define btnLed4Pin 12
#define btnLed5Pin 13
byte btnLedArray[] = { btnLed1Pin, btnLed2Pin, btnLed3Pin, btnLed4Pin, btnLed5Pin };
#define btnLed1 0
#define btnLed2 1
#define btnLed3 2
#define btnLed4 3
#define btnLed5 4
// pines digitales audio fx
#define fx0TriggerPin 29
#define fx1TriggerPin 31
#define fx2TriggerPin 33
#define fx3TriggerPin 35
#define fx4TriggerPin 37
#define fx5TriggerPin 39
#define fx6TriggerPin 41
#define fx7TriggerPin 43
#define fx8TriggerPin 45
#define fx9TriggerPin 47
#define fx10TriggerPin 49
#define fxVolUpPin 51
#define fxVolDnPin 53
byte fxTriggerArray[] = { fx0TriggerPin, fx1TriggerPin, fx2TriggerPin, fx3TriggerPin, fx4TriggerPin, fx5TriggerPin, fx6TriggerPin, fx7TriggerPin, fx8TriggerPin, fx9TriggerPin, fx10TriggerPin };
byte fxVolumeArray[] = { fxVolUpPin, fxVolDnPin };
#define fx0Trigger 0
#define fx1Trigger 1
#define fx2Trigger 2
#define fx3Trigger 3
#define fx4Trigger 4
#define fx5Trigger 5
#define fx6Trigger 6
#define fx7Trigger 7
#define fx8Trigger 8
#define fx9Trigger 9
#define fx10Trigger 10
#define fxVolUp 0
#define fxVolDn 1
signed int currentPlayingSound = -1;
byte btnPressed[5], ledState[5];
// parpadeo LED
unsigned long previousMillisLedBlink = 0;
#define intervalLedBlink 750
// secuencia inicio juego
unsigned long previousMillisGameStarting = 0;
#define intervalCountDown 1000
byte gameStartCountDown;
// pasos juego
unsigned long previousMillisGameStep = 0;
int gameStepLength = 0;
int gameStepBtn = 0;
int valPotmeterVolume = 0;
int volume = 0;
int actualVolume = 35;
int valPotmeterGameLevel = 0;
int gameLevel;
int currentScore;
int highScore;
int highScoreAddr = 1;
byte activeBtn;
bool debug;
byte wackAMoleState;
bool SystemInitialized = false;
#define stateUnknown 0
#define waitForStart 1
#define starting 2
#define running 3
#define gameOver 4
#define stopped 5
void setup() {
Serial.begin(9600);
// init pin amp power
pinMode(ampPower, OUTPUT);
digitalWrite(ampPower, LOW);
// init pines botones
for (int Pin = 0; Pin < 5; Pin++) {
pinMode(btnArray[Pin], INPUT);
}
// init pines LEDs botones
for (int Pin = 0; Pin < 5; Pin++) {
pinMode(btnLedArray[Pin], OUTPUT);
}
// init pines fx botones
for (int Pin = 0; Pin < 11; Pin++) {
pinMode(fxTriggerArray[Pin], OUTPUT);
digitalWrite(fxTriggerArray[Pin], HIGH);
}
// init pines volumen fx
for (int Pin = 0; Pin < 2; Pin++) {
pinMode(fxVolumeArray[Pin], OUTPUT);
digitalWrite(fxVolumeArray[Pin], HIGH);
}
matrix1.begin(0x70);
matrix2.begin(0x71);
while (!eeprom_is_ready());
cli();
highScore = eeprom_read_word((uint16_t*)(gameLevel * 2));
sei();
matrix1.print(0);
matrix1.writeDisplay();
matrix2.print(0);
matrix2.writeDisplay();
initializeSystem();
}
void loop() {
checkButtonInputs();
readVolumePotmeter();
if (wackAMoleState == waitForStart) {
playSound(fx0Trigger);
if (btnPressed[btn4]) {
wackAMoleState = starting;
}
readGameLevelPotmeter();
ledBlinkStart();
}
if (wackAMoleState == starting) {
startGame();
}
if (wackAMoleState == running) {
playSound(fx1Trigger);
checkNextGameStep();
}
}
// ... (resto de funciones: checkNextGameStep, ledBlinkStart, startGame, initializeSystem, checkButtonInputs, initVolume, readVolumePotmeter, readGameLevelPotmeter, playSound, enableAmpPower)
Piezas Personalizadas y Recintos
- Piezas MDF corte láser 6mm - OC9CvHjuTzsYL9POZCJt.dxf
- Piezas MDF corte láser 9mm - 1irkeqvO4ABzhKqhmyG7.dxf
- Piezas Plexiglass corte láser 3mm - j4Tnmni6dQ0KXJtiHcy1.dxf
- Shield Arduino Mega Personalizado - 5yiRX1RdQuPX0gNXjYkm.zip
- Soporte amplificador impreso 3D, imprimir 2x
- Soporte Arduino Mega impreso 3D
- Soporte panel conexión trasera impreso 3D
- Panel conexión trasera impreso 3D
- Clip cable impreso 3D, imprimir tantos como quieras
- Soporte display LED impreso 3D, imprimir 2x
- Bloqueo soporte display LED impreso 3D, imprimir 4x
- Marco superior display LED impreso 3D, imprimir 2x
- Soporte tapa superior trasero impreso 3D
- Soporte tapa superior frontal impreso 3D, imprimir 2x
- Soporte tapa superior lateral impreso 3D, imprimir 2x
Esquemáticos

Proceso de manufactura
- El Botón: De Sujetador Ancestral a Innovación Moderna
- Botón IoT AWS Controlado por Movimiento con Raspberry Pi, Sensor PIR y MQTT
- UnifiedWater v1 – Kit completo de sensor de calidad de agua con Arduino
- Sistema de votación portátil con conectividad GSM
- Jukebox Moderna: Reproductor Musical Raspberry Pi + Arduino con LEDs Reactivos
- Cómo elegir el fabricante de prototipos PCB adecuado: Guía completa
- Selección de la Velocidad Óptima de Aserrado para Sierras de Cinta: Guía Práctica
- Elegir la Bomba Sumergible Adecuada: Consejos de Expertos y Características Clave
- Principales Razones para Elegir Centros de Torneado Vertical para Mecanizado de Precisión
- Cómo Elegir los Mandos de Instrumentos Adecuados para su Equipo
- Cómo elegir los tornillos de cabeza allen con cabeza abotonada: guía práctica