Game — ESP32-C3 simulation

An interactive ESP32-C3 circuit simulation you can run free in your browser on Velxio, by edelarosagon.

Components

Sketch code

// ============================================================
//  A R K A N O I D   R E T R O   -  ESP32-C3 + ILI9341 + Touch
// ============================================================
//  Pantalla: ILI9341 320x240 por SPI de hardware (FSPI)
//  Touch:    XPT2046 resistivo, compartiendo el mismo bus SPI
//
//  IMPORTANTE - CONFLICTO DE PINES:
//  En tus dos sketches anteriores, TFT_CS y T_CS eran el mismo
//  pin (7). Ambos chips pueden compartir SCK/MISO/MOSI, pero
//  cada uno necesita su propio CS. Aqui el touch usa el pin 2.
//  Si ese pin esta ocupado en tu placa, cambia TOUCH_CS abajo.
// ============================================================

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>

// ---------- Pines TFT ----------
#define TFT_SCK   4
#define TFT_MISO  5
#define TFT_MOSI  6
#define TFT_CS    7
#define TFT_DC    3
#define TFT_RST  10

// ---------- Pin Touch (CS propio, resto del bus compartido) ----------
#define TOUCH_CS  2

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen ts(TOUCH_CS);

// ---------- Calibracion del touch ----------
// Toca las 4 esquinas viendo el Monitor Serial y ajusta estos 4 numeros.
// Si el eje sale invertido o cruzado, cambia los flags SWAP/INVERT.
const int TS_MIN_X = 200,  TS_MAX_X = 3900;
const int TS_MIN_Y = 200,  TS_MAX_Y = 3900;
const bool TS_SWAP_XY   = true;   // pantalla en landscape suele necesitar swap
const bool TS_INVERT_X  = false;
const bool TS_INVERT_Y  = false;

// ---------- Paleta retro ----------
#define COL_BG        ILI9341_BLACK
#define COL_PADDLE    0x07FF   // cian neon
#define COL_BALL      0xFFE0   // amarillo
#define COL_TEXT      0x07FF
#define COL_LIVES     0xF800   // rojo
#define COL_WIN       0x07E0   // verde

const uint16_t rowColors[5] = {
  0xF800, // rojo
  0xFD20, // naranja
  0xFFE0, // amarillo
  0x07E0, // verde
  0x07FF  // cian
};

// ---------- Geometria del campo ----------
const int SCREEN_W = 320;
const int SCREEN_H = 240;

const int PADDLE_W = 50;
const int PADDLE_H = 8;
const int PADDLE_Y = SCREEN_H - 20;

const int BALL_R = 4;

const int BRICK_ROWS = 5;
const int BRICK_COLS = 10;
const int BRICK_W = 30;
const int BRICK_H = 12;
const int BRICK_GAP = 2;
const int BRICK_TOP = 30;
const int BRICK_LEFT = (SCREEN_W - (BRICK_COLS * (BRICK_W + BRICK_GAP))) / 2;

bool brickAlive[BRICK_ROWS][BRICK_COLS];

// ---------- Estado del juego ----------
enum GameState { START_SCREEN, PLAYING, LEVEL_CLEAR, GAME_OVER };
GameState state = START_SCREEN;

int paddleX, paddleXOld;
float ballX, ballY, ballDX, ballDY;
int ballXOld, ballYOld;

int score = 0;
int lives = 3;
int level = 1;
int bricksLeft = 0;

unsigned long lastFrame = 0;
const int FRAME_MS = 16; // ~60 fps logico

// ============================================================
//  SETUP
// ============================================================
void setup() {
  Serial.begin(115200);

  SPI.begin(TFT_SC

More projects by edelarosagon