-
-
Save Cric75/03b2c344aae731657c59683fef10b26e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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