Skip to content

Instantly share code, notes, and snippets.

@Cric75
Last active November 22, 2021 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cric75/03b2c344aae731657c59683fef10b26e to your computer and use it in GitHub Desktop.
Save Cric75/03b2c344aae731657c59683fef10b26e to your computer and use it in GitHub Desktop.
/* Version du jeu incorporant une classe Paddle pour remplacer la fonction raquette
* Ce code s'appuie sur celui de Steph (Dynamic stretching and shrinking of a pong paddle)
*/
#include <Gamebuino-Meta.h>
uint8_t bSpeed = 2;
uint8_t hauteur = 12;
uint8_t modDiff = 26;
// Gestion des états
enum class State : uint8_t {
start,
menu,
play,
game_over
};
// Gestion du niveau de difficulté
enum class Difficulty : uint8_t {
easy,
medium,
hard
};
// Caractéristiques du jeu : état et score des 2 joueurs (droite puis gauche)
struct Game {
State state;
Difficulty difficulty;
uint8_t score1;
uint8_t score2;
void resetScores() {
score1 = score2 = 0;
}
};
Game game;
/*
Caractéristiques d'une raquette
Basée sur le code de Steph
*/
struct Paddle {
static const uint8_t V = 2; // Vitesse
static const uint8_t L = 3; // Largeur
static const uint8_t H = 12; // Hauteur
uint8_t posX;
uint8_t posY;
uint8_t vitesse;
uint8_t hauteur;
uint8_t largeur;
uint8_t gbheight = gb.display.height();
Color color;
Paddle(uint8_t posX, uint8_t posY, Color color) :
posX(posX), posY(posY), color(color), vitesse(V), hauteur(H), largeur(L) {}
// Player Up (BUTTON_UP) or Down (BUTTON_DOWN)
void up() { posY -= V; }
void down() { posY += V; }
// La raquette Joueur ne peut pas sortir de l'écran (hout ou bas)
void updatePlayer() {
if (posY < 1) posY = 2;
else if (posY+hauteur > gbheight) posY = gbheight-hauteur;
}
// La raquette Computer suit le mouvement de la balle
void updateComputer(Ball &b) {
if (b.posY > (posY+hauteur/2) && posY + hauteur < gbheight) {
posY += 2;
}
else if (b.posY < (posY + hauteur/2) && posY > 0) {
posY -= 2;
}
if (posY < 1) posY = 2;
else if (posY+hauteur > gbheight) posY = gbheight-hauteur;
}
void draw() {
// Affichage de la raquette Player / Computer
gb.display.setColor(color);
gb.display.fillRect(posX, posY, largeur, hauteur);
}
void drawscore() {
// Affichage du score, appelé par Player.drawscore
gb.display.setCursor(33, 5);
gb.display.setColor(BLUE);
gb.display.print(game.score1);
gb.display.setColor(WHITE);
gb.display.print(" - ");
gb.display.setColor(PINK);
gb.display.print(game.score2);
}
};
// Caractéristiques de la balle et de la difficulté
//struct s_balle{int posX; int posY; int speedX; int speedY; int taille; int modDiff;};
//s_balle balle={20, 20, bSpeed, -bSpeed, 4, 0};
struct Ball {
uint8_t posX;
uint8_t posY;
uint8_t speedX;
uint8_t speedY;
uint8_t taille;
uint8_t modDiff; // Difficulté du jeu
Ball(uint8_t posX, uint8_t posY, uint8_t speedX, uint8_t speedY, uint8_t taille, uint8_t modDiff) :
posX(posX), posY(posY), speedX(speedX), speedY(speedY), taille(taille), modDiff(modDiff) {}
void update() {
posX += speedX;
posY += speedY;
// La balle rebondit en haut ou en bas de l'écran
if (posY == 0) {
speedY = bSpeed;
}
if (posY > gb.display.height()-taille) {
speedY = -bSpeed;
}
// La balle sort de l'écran à droite : c'est perdu, on remet au centre
if (posX == 0) {
posX = 40;
posY = random(20, gb.display.height() - 20); // Position aléatoire au centre de l'écran;
if (random(0, 2) == 1) { // 50% du temps
speedY = bSpeed;
}
else { // 50% du temps
speedY = -bSpeed;
}
game.score2 +=1;
}
// La balle sort de l'écran à gauche : c'est perdu, on remet au centre
if (posX+taille > gb.display.width()) {
posX = 40;
posY = random(20, gb.display.height() - 20); // Position aléatoire au centre de l'écran;
if (random(0, 2) == 1) { // 50% du temps
speedY = bSpeed;
}
else { // 50% du temps
speedY = -bSpeed;
}
game.score1 +=1;
}
// Gestion de collisions raquette Player
if ((posX == player.posX+player.largeur)
&& (posY+taille >= player.posY)
&& (posY <= player.posY+player.hauteur)) {
// ball.speedX = 1;
speedX = 1;
}
// Gestion de collisions raquette Computer
if ((posX+taille == computer.posX)
&& (posY+taille >= computer.posY)
&& (posY <= computer.posY+computer.hauteur)) {
// ball.speedX = -1;
speedX = -1;
}
}
// La balle rebondit sur les 4 murs
void start() {
posX += speedX;
posY += speedY;
// La balle rebondit en haut ou en bas de l'écran
if (posY == 0) {
speedY = bSpeed;
}
if (posY == gb.display.height()-taille) {
speedY = -bSpeed;
}
// La balle rebondit à droite ou à gauche de l'écran
if (posX == 0) {
speedX = bSpeed;
}
if (posX == gb.display.width()-taille) {
speedX = -bSpeed;
}
}
// Affichage de la balle en mouvement
void draw() {
gb.display.setColor(YELLOW);
gb.display.fillRect(posX, posY, taille, taille);
}
};
/*
Construction de 2 instances de Paddle
Caractéristiques des raquettes de gauche du joueur (player) et de droite de l'IA (computer)
*/
Paddle player(10, 30, LIGHTBLUE);
Paddle computer(gb.display.width()-12, 30, PINK);
/*
* Construction d'1 instance d0e Ball
* Rappel :
* uint8_t posX;
uint8_t posY;
uint8_t speedX;
uint8_t speedY;
uint8_t taille;
uint8_t modDiff;
*/
Ball ball(20, 20, bSpeed, -bSpeed, 4, 0);
/*
Etat du jeu start (écran de démarrage au lancement du jeu)
On fait rebondir une balle sur tout l'écran en arrière plan
*/
void start() {
if (gb.buttons.pressed(BUTTON_A)) game.state = State::menu;
gb.display.print(14, 10, "PONG 1 PLAYER");
if (gb.frameCount % 25 < 13) {
gb.display.print(14, 30, "APPUYER SUR A");
gb.display.print(14, 40, "POUR DEMARRER");
}
ball.start();
ball.draw();
game.resetScores();
}
/*
Etat du jeu menu (choix à partie de 3 niveaux de difficultés)
*/
void menu() {
// uint8_t hauteur;
if (gb.buttons.pressed(BUTTON_UP)) {
switch (game.difficulty) {
case Difficulty::medium: game.difficulty = Difficulty::easy; break;
case Difficulty::hard: game.difficulty = Difficulty::medium;
}
} else if (gb.buttons.pressed(BUTTON_DOWN)) {
switch (game.difficulty) {
case Difficulty::easy: game.difficulty = Difficulty::medium; break;
case Difficulty::medium: game.difficulty = Difficulty::hard;
}
} else if (gb.buttons.pressed(BUTTON_A))
game.state = State::play;
gb.display.print(4, 10, "CHOISIR DIFFICULTE");
gb.display.print(32, 30, "FACILE");
gb.display.print(32, 40, "MOYENNE");
gb.display.print(32, 50, "DIFFICILE");
gb.display.setColor(YELLOW);
gb.display.fillRect(20, 31 + 10*(uint8_t)game.difficulty, 4, 4);
if (game.difficulty == Difficulty::easy) {
bSpeed=2;
modDiff=26; // la balle apparait systématiquement car hors scope du décompte des 25 images dans le gb.Count
}
else if (game.difficulty == Difficulty::medium) {
bSpeed=3;
modDiff=18;
}
else {
bSpeed=3;
modDiff=12;
}
if (game.difficulty == Difficulty::hard) {
hauteur = 6;
}
else {
hauteur = 12;
}
}
// Etat du jeu play (corps du jeu)
void play() {
readButtons();
update();
draw();
}
/*
Etat du jeu gameOver (fin de la partie)
Un appui sur A (BUTTON_A) relance le jeu (état start)
*/
void gameOver() {
gb.display.setCursor(33, 5);
gb.display.setColor(BLUE);
gb.display.print(game.score1);
gb.display.setColor(WHITE);
gb.display.print(" - ");
gb.display.setColor(PINK);
gb.display.print(game.score2);
if (gb.buttons.pressed(BUTTON_A)) game.state = State::start;
if (game.score1 >= 10) {
gb.display.setColor(BLUE);
gb.display.print(12, 20, "LE JOUEUR GAGNE");
if (gb.frameCount % 25 < 13) {
gb.display.setColor(WHITE);
gb.display.print(17, 30, "APPUYER SUR A");
gb.display.print(17, 40, "POUR DEMARRER");
}
} else if (game.score2 >= 10) {
gb.display.setColor(PINK);
gb.display.print(20, 20, "LA GB GAGNE");
if (gb.frameCount % 25 < 13) {
gb.display.setColor(WHITE);
gb.display.print(17, 30, "APPUYER SUR A");
gb.display.print(17, 40, "POUR DEMARRER");
}
}
}
void readButtons() {
if (gb.buttons.repeat(BUTTON_UP, 0)) player.up();
else if (gb.buttons.repeat(BUTTON_DOWN, 0)) player.down();
}
void update() {
player.updatePlayer();
computer.updateComputer(ball);
ball.update();
}
void draw() {
player.draw();
player.drawscore();
computer.draw();
ball.draw();
}
void setup() {
gb.begin();
game.state = State::start;
}
void loop() {
gb.waitForUpdate();
gb.display.clear();
switch (game.state) {
case State::start:
start();
break;
case State::menu:
menu();
break;
case State::play:
play();
break;
case State::game_over:
gameOver();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment