#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
// Definición de pines
#define SDA D4
#define SCL D5
#define potX D1
#define potY D2
#define startButton D0
// Características de la pantalla
#define height 64
#define width 128
#define rst -1
Adafruit_SSD1306 display(width, height, &Wire, rst);
// ====== ESTADOS DEL JUEGO ======
enum GameState {
WAIT_START,
PLAYING,
GAME_OVER
};
GameState gameState = WAIT_START;
volatile bool startRequested = false;
// ====== VARIABLES DEL JUEGO ======
int posX = 64 - 4, posY = 30;
int palX = 64 - 12, palY = 64 - 1;
int vel = 4;
int velX = 5, velY = -2;
int centro[2] = {2048, 2048};
// ====== INTERRUPCIÓN ======
void IRAM_ATTR handleStart() {
startRequested = true;
}
// ====== SETUP ======
void setup() {
Serial.begin(115200);
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("Oled Display NOT Found...");
for (;;);
}
pinMode(startButton, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(startButton), handleStart, FALLING);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(15, 10);
display.println("PONG BALL");
display.display();
delay(2000);
}
// ====== LOOP PRINCIPAL ======
void loop() {
switch (gameState) {
case WAIT_START:
mostrarPantallaInicio();
if (startRequested) {
startRequested = false;
resetGame();
gameState = PLAYING;
}
break;
case PLAYING:
play();
break;
case GAME_OVER:
mostrarGameOver();
if (startRequested) {
startRequested = false;
resetGame();
gameState = PLAYING;
}
break;
}
}
// ====== PANTALLAS ======
void mostrarPantallaInicio() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20, 15);
display.println("READY?");
display.setTextSize(1);
display.setCursor(20, 40);
display.println("Press Button");
display.display();
}
void mostrarGameOver() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(30, 20);
display.println("GAME");
display.setCursor(30, 40);
display.println("OVER");
display.display();
}
// ====== RESET ======
void resetGame() {
posX = 64 - 4;
posY = 30;
palX = 64 - 12;
velX = 5;
velY = -2;
}
// ====== JUEGO ======
void play() {
int lectura = analogRead(potX);
if (lectura - centro[0] > 100) palX -= vel;
if (lectura - centro[0] < -100) palX += vel;
moverBola();
display.clearDisplay();
pintarPaleta();
pintarBola(posX, posY);
display.display();
delay(40);
}
// ====== FÍSICA ======
void moverBola() {
posX += velX;
posY += velY;
// Rebote lateral
if (posX >= width - 4) {
posX = width - 4;
velX = -velX;
}
if (posX <= 1) {
posX = 1;
velX = -velX;
}
// Rebote superior
if (posY <= 1) {
posY = 1;
velY = -velY;
}
// Colisión inferior
if (posY >= height - 6) {
posY = height - 6;
if (posX + 4 >= palX && posX <= palX + 24) {
velY = -velY; // rebote
} else {
gameState = GAME_OVER;
}
}
}
// ====== DIBUJO ======
void pintarBola(int x, int y) {
display.fillRect(x, y, 4, 4, WHITE);
}
void pintarPaleta() {
if (palX > 103) palX = 103;
if (palX < 1) palX = 1;
display.fillRect(palX, palY, 24, 2, WHITE);
}
Loading
xiao-esp32-c3
xiao-esp32-c3