#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>
// Définition des broches
#define TFT_MOSI 10
#define TFT_SCLK 8
#define TFT_CS 20
#define TFT_DC 3
#define TFT_RST 4
// Couleurs (approximations en RGB565)
#define COLOR_RGB565_WHITE ST77XX_WHITE
#define COLOR_RGB565_BLACK ST77XX_BLACK
#define COLOR_RGB565_GREEN ST77XX_GREEN
#define COLOR_RGB565_LGRAY 0xC618 // Gris clair approximatif
#define COLOR_RGB565_PURPLE ST77XX_MAGENTA
#define COLOR_RGB565_YELLOW ST77XX_YELLOW
#define COLOR_RGB565_ORANGE 0xFD20 // Approximatif
#define COLOR_RGB565_RED ST77XX_RED
#define COLOR_RGB565_BLUE ST77XX_BLUE
// Création de l'objet écran (mode SPI)
Adafruit_ST7789 screen = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// Résolution en mode paysage : 320 x 240
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
// Définition des variables du jeu
#define PLAYER_ONE 4
#define PLAYER_TWO 2
int buttonPin = 0;
// Coordonnées des raquettes
int paddlesStartPosition = 80;
int paddleStartRange = 80;
int prevPaddleOne;
int prevPaddleTwo;
int paddleOne;
int paddleTwo;
// Attributs des joueurs
int paddleOneX = 25;
int paddleTwoX = 280;
int paddlesHeight = 40;
int paddlesWidth = 10;
// État global du jeu
bool isGameStart = false;
int targetScore = 10;
int playerOneScore;
int playerTwoScore;
bool playerOneReady = false;
bool playerTwoReady = false;
// Attributs de la balle
int ballSize = 10;
int ballSpeed = 2; // Vitesse initiale réduite
int speedX[] = { -2, -1, 1, 2 };
// Coordonnées de la balle
int ball_x = 160;
int ball_y = 120;
int prevBallX;
int prevBallY;
// Déplacements de la balle
int ball_x_move = 0;
int ball_y_move = 0;
int hitCount = 0;
void setup() {
Serial.begin(9600);
// Initialisation de l'écran (résolution d'origine 240x320, rotation pour obtenir 320x240)
screen.init(240, 320);
screen.setRotation(3);
// Configuration analogique
analogReadResolution(10);
pinMode(buttonPin, INPUT);
screen.fillScreen(COLOR_RGB565_WHITE);
reset();
}
void loop() {
if (isGameStart) {
move();
draw();
state();
delay(20); // Petite pause pour ralentir la boucle de jeu
} else {
movePaddle();
drawPaddle();
startCondition();
}
}
void startCondition() {
if ((paddleOne >= paddlesStartPosition) && (paddleOne + paddlesHeight <= paddlesStartPosition + paddleStartRange)) {
playerOneReady = true;
screen.fillRect(0, paddlesStartPosition, paddlesWidth, paddleStartRange, COLOR_RGB565_GREEN);
} else {
playerOneReady = false;
screen.fillRect(0, paddlesStartPosition, paddlesWidth, paddleStartRange, COLOR_RGB565_LGRAY);
}
if ((paddleTwo >= paddlesStartPosition) && (paddleTwo + paddlesHeight <= paddlesStartPosition + paddleStartRange)) {
screen.fillRect(310, paddlesStartPosition, paddlesWidth, paddleStartRange, COLOR_RGB565_GREEN);
playerTwoReady = true;
} else {
screen.fillRect(310, paddlesStartPosition, paddlesWidth, paddleStartRange, COLOR_RGB565_LGRAY);
playerTwoReady = false;
}
if (playerOneReady && playerTwoReady) {
isGameStart = true;
screen.fillScreen(COLOR_RGB565_WHITE);
}
}
void state() {
if (playerOneScore == targetScore) {
screen.fillScreen(COLOR_RGB565_WHITE);
screen.setTextColor(COLOR_RGB565_BLACK);
screen.setCursor(65, 110);
screen.println("PLAYER 1 WON!!");
delay(2000);
reset();
}
if (playerTwoScore == targetScore) {
screen.fillScreen(COLOR_RGB565_WHITE);
screen.setTextColor(COLOR_RGB565_BLACK);
screen.setCursor(65, 110);
screen.println("PLAYER 2 WON!!");
delay(2000);
reset();
}
}
void reset() {
isGameStart = false;
playerOneScore = 0;
playerTwoScore = 0;
ball_x = 160;
ball_y = 120;
ball_x_move = 0;
ball_y_move = 0;
ballSpeed = 2; // Vitesse initiale réduite
getRandomX();
getRandomY();
screen.fillScreen(COLOR_RGB565_WHITE);
screen.setTextSize(4);
screen.setTextColor(COLOR_RGB565_BLACK);
screen.setCursor(55, 100);
screen.println("PING PONG");
screen.setTextSize(2);
screen.setCursor(70, 150);
screen.println("ALIGN TO START");
screen.fillRect(0, paddlesStartPosition, paddlesWidth, paddleStartRange, COLOR_RGB565_LGRAY);
screen.fillRect(310, paddlesStartPosition, paddlesWidth, paddleStartRange, COLOR_RGB565_LGRAY);
}
void restart() {
delay(1000);
ball_x = 160;
ball_y = 120;
ball_x_move = 0;
ball_y_move = 0;
ballSpeed = 2; // Vitesse initiale réduite
getRandomX();
getRandomY();
}
void movePaddle() {
paddleOne = map(analogRead(PLAYER_ONE), 4, 840, 6, 191);
paddleTwo = map(analogRead(PLAYER_TWO), 4, 840, 6, 191);
}
void move() {
movePaddle();
moveBall();
}
void moveBall() {
if (hitCount >= 5) {
ballSpeed++; // Augmentation de la vitesse après plusieurs coups
ball_x_move = (ball_x_move < 0) ? -ballSpeed : ballSpeed;
hitCount = 0;
}
// Collisions haut et bas
if (ball_y <= 6 || ball_y + ballSize >= 230) {
ball_y_move *= -1;
}
// Mur gauche
if (ball_x <= 10) {
playerTwoScore++;
restart();
}
// Mur droit
if (ball_x >= 306) {
playerOneScore++;
restart();
}
// Collision avec la raquette
if (ballCollision(true) || ballCollision(false)) {
ball_x_move *= -1;
ball_y_move = 0;
hitCount++;
getRandomY();
}
ball_x += ball_x_move;
ball_y += ball_y_move;
}
bool ballCollision(bool left) {
if (left) {
if ((ball_y >= paddleOne || ball_y + ballSize >= paddleOne) && (ball_y <= paddleOne + paddlesHeight)) {
if (ball_x <= paddleOneX + paddlesWidth && ball_x >= paddleOneX) {
return true;
}
}
} else {
if (ball_y <= paddleTwo + paddlesHeight && (ball_y >= paddleTwo || ball_y + ballSize >= paddleTwo)) {
if (ball_x + ballSize >= paddleTwoX && ball_x + ballSize <= paddleTwoX + paddlesWidth) {
return true;
}
}
}
return false;
}
void draw() {
drawCourt();
drawScores();
drawPaddle();
drawBall();
}
void drawScores() {
screen.setTextColor(COLOR_RGB565_BLACK, COLOR_RGB565_WHITE);
screen.setTextSize(2);
screen.setCursor(110, 20);
screen.println(playerOneScore);
screen.setCursor(200, 20);
screen.println(playerTwoScore);
}
void drawCourt() {
// Lignes horizontales
screen.fillRect(10, 6, 300, 4, COLOR_RGB565_BLACK);
screen.fillRect(10, 230, 300, 4, COLOR_RGB565_BLACK);
// Lignes verticales
screen.fillRect(10, 6, 4, 226, COLOR_RGB565_BLACK);
screen.fillRect(306, 6, 4, 226, COLOR_RGB565_BLACK);
// Ligne médiane
screen.fillRect(158, 6, 4, 226, COLOR_RGB565_BLACK);
}
void drawBall() {
eraseBall();
screen.fillRect(ball_x, ball_y, ballSize, ballSize, COLOR_RGB565_BLACK);
prevBallX = ball_x;
prevBallY = ball_y;
}
void drawPaddle() {
erasePaddles();
screen.fillRect(paddleOneX, paddleOne, paddlesWidth, paddlesHeight, COLOR_RGB565_BLACK);
screen.fillRect(paddleTwoX, paddleTwo, paddlesWidth, paddlesHeight, COLOR_RGB565_BLACK);
prevPaddleOne = paddleOne;
prevPaddleTwo = paddleTwo;
}
void getRandomX() {
do {
ball_x_move = (random(0, 2) == 0) ? -ballSpeed : ballSpeed;
} while (ball_x_move == 0);
}
void getRandomY() {
do {
ball_y_move = speedX[random(0, 4)];
Serial.println(ball_y_move);
} while (ball_y_move == 0);
}
void eraseBall() {
if (ball_x - prevBallX > 0) {
screen.fillRect(prevBallX, prevBallY, ball_x - prevBallX, ballSize, COLOR_RGB565_WHITE);
} else {
screen.fillRect(ball_x + ballSize, prevBallY, prevBallX - ball_x, ballSize, COLOR_RGB565_WHITE);
}
if (ball_y - prevBallY > 0) {
screen.fillRect(ball_x, prevBallY, ballSize, ball_y - prevBallY, COLOR_RGB565_WHITE);
} else {
screen.fillRect(ball_x, ball_y + ballSize, ballSize, prevBallY - ball_y, COLOR_RGB565_WHITE);
}
}
void erasePaddles() {
if (paddleOne - prevPaddleOne > 0) {
screen.fillRect(paddleOneX, prevPaddleOne, paddlesWidth, paddleOne - prevPaddleOne, COLOR_RGB565_WHITE);
} else {
screen.fillRect(paddleOneX, paddleOne + paddlesHeight, paddlesWidth, prevPaddleOne - paddleOne, COLOR_RGB565_WHITE);
}
if (paddleTwo - prevPaddleTwo > 0) {
screen.fillRect(paddleTwoX, prevPaddleTwo, paddlesWidth, paddleTwo - prevPaddleTwo, COLOR_RGB565_WHITE);
} else {
screen.fillRect(paddleTwoX, paddleTwo + paddlesHeight, paddlesWidth, prevPaddleTwo - paddleTwo, COLOR_RGB565_WHITE);
}
}
Loading
xiao-esp32-c3
xiao-esp32-c3