7 Commits

Author SHA1 Message Date
andrea
0b3c7e0f22 add circuit schema png 2026-03-22 10:57:34 +01:00
andrea
f1059588ff add circuit schema 2026-03-22 10:54:33 +01:00
andrea
a2f5049bfe add circuit schema 2026-03-22 10:51:45 +01:00
andrea
f88de159f5 restore default values
Some checks failed
Arduino Pong CI / build (macos-latest) (push) Has been cancelled
Arduino Pong CI / build (ubuntu-latest) (push) Has been cancelled
Arduino Pong CI / build (windows-latest) (push) Has been cancelled
Arduino Pong CD / release (push) Has been cancelled
2026-03-21 13:59:03 +01:00
andrea
fae479ce90 clean code adding a menu class
Some checks failed
Arduino Pong CI / build (macos-latest) (push) Has been cancelled
Arduino Pong CI / build (ubuntu-latest) (push) Has been cancelled
Arduino Pong CI / build (windows-latest) (push) Has been cancelled
2026-03-21 13:52:54 +01:00
andrea
d65e7ef1c8 fix delay on level difficulty choice 2026-03-21 12:20:06 +01:00
andrea
8c402ff13a return to main menu after game finishes
Some checks failed
Arduino Pong CI / build (macos-latest) (push) Has been cancelled
Arduino Pong CI / build (ubuntu-latest) (push) Has been cancelled
Arduino Pong CI / build (windows-latest) (push) Has been cancelled
Arduino Pong CD / release (push) Has been cancelled
2026-03-21 12:16:07 +01:00
6 changed files with 138 additions and 68 deletions

View File

@@ -1,6 +1,7 @@
#include "Arduino_LED_Matrix.h" #include "Arduino_LED_Matrix.h"
#include "src/config.h" #include "src/config.h"
#include "src/menu.h"
#include "src/renderer.h" #include "src/renderer.h"
#include "src/engine.h" #include "src/engine.h"
#include "src/paddle.h" #include "src/paddle.h"
@@ -36,9 +37,6 @@ enum game_statuses : uint8_t {
}; };
game_statuses game_status= MENU; game_statuses game_status= MENU;
enum game_modes : uint8_t {PVP, PVC, CVC};
game_modes game_mode = PVP;
Ball ball(4, 6); Ball ball(4, 6);
@@ -48,12 +46,13 @@ HumanPaddle human_pad1(1, P1_BTN_UP, P1_BTN_BOTTOM);
HumanPaddle human_pad2(4, P2_BTN_UP, P2_BTN_BOTTOM); HumanPaddle human_pad2(4, P2_BTN_UP, P2_BTN_BOTTOM);
BotPaddle bot_pad1(1, 0); BotPaddle bot_pad1(1, 0);
BotPaddle bot_pad2(4, MATRIX_WIDTH-1); BotPaddle bot_pad2(4, MATRIX_WIDTH-1);
Menu menu;
uint8_t current_gmode_idx= 0; // uint8_t current_gmode_idx= 0;
bool update_menu= true; // bool update_menu= true;
bool mode_selected= false; // bool mode_selected= false;
uint8_t current_bot_menu_idx= 0; // uint8_t current_bot_menu_idx= 0;
bool update_menu_bot_skills= true; // bool update_menu_bot_skills= true;
Engine engine(ball, INITIAL_BALL_DELAY); Engine engine(ball, INITIAL_BALL_DELAY);
Renderer renderer(ball, frame, matrix); Renderer renderer(ball, frame, matrix);
@@ -77,79 +76,80 @@ void loop() {
switch (game_status) { switch (game_status) {
case MENU: { case MENU: {
if (digitalRead(P2_BTN_BOTTOM) == LOW && current_gmode_idx < sizeof(frame_gmodes)/sizeof(frame_gmodes[0]) -1) { // switch modes
current_gmode_idx += 1; if (digitalRead(P2_BTN_BOTTOM) == LOW) {
update_menu= true; menu.next_mode();
const byte (*current_gmode)[12]= frame_gmodes[menu.get_mode()];
matrix.loadPixels((uint8_t*)current_gmode, MATRIX_HEIGHT * MATRIX_WIDTH);
delay(300);
} }
else if (digitalRead(P2_BTN_UP) == LOW && current_gmode_idx > 0) { else if (digitalRead(P2_BTN_UP) == LOW) {
update_menu= true; menu.prev_mode();
current_gmode_idx -= 1; const byte (*current_gmode)[12]= frame_gmodes[menu.get_mode()];
game_mode= PVP; matrix.loadPixels((uint8_t*)current_gmode, MATRIX_HEIGHT * MATRIX_WIDTH);
delay(300);
} }
// 1. P vs P // 1. P vs P
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && game_modes(current_gmode_idx) == PVP) { else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && menu.number_of_bots() == 0) {
p1= &human_pad1; p1= &human_pad1;
p2= &human_pad2; p2= &human_pad2;
mode_selected= true;
}
// 2. P vs CPU
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && game_modes(current_gmode_idx) == PVC) {
p1= &human_pad1;
p2= &bot_pad2;
mode_selected= true;
update_menu= false;
game_mode= PVC;
}
// 3. CPU vs CPU
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && game_modes(current_gmode_idx) == CVC) {
p1= &bot_pad1;
p2= &bot_pad2;
mode_selected= true;
update_menu= false;
game_mode= CVC;
}
if (update_menu) {
// show menu on the matrix
const byte (*current_gmode)[12]= frame_gmodes[current_gmode_idx];
matrix.loadPixels((uint8_t*)current_gmode, MATRIX_HEIGHT * MATRIX_WIDTH);
update_menu= false;
delay(300);
}
else if (mode_selected) {
engine.set_players(p1, p2); engine.set_players(p1, p2);
renderer.set_players(p1, p2); renderer.set_players(p1, p2);
if (game_mode == PVC || game_mode == CVC) { game_status= TIMER;
}
// 2. P vs CPU
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && menu.number_of_bots() == 1) {
p1= &human_pad1;
p2= &bot_pad2;
engine.set_players(p1, p2);
renderer.set_players(p1, p2);
game_status= MENU_BOT_SKILLS; game_status= MENU_BOT_SKILLS;
delay(300); // avoid accidental double click for next menu delay(300); // avoid accidental double click for next menu
} }
else game_status= TIMER; // 3. CPU vs CPU
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && menu.number_of_bots() == 2) {
p1= &bot_pad1;
p2= &bot_pad2;
engine.set_players(p1, p2);
renderer.set_players(p1, p2);
game_status= MENU_BOT_SKILLS;
delay(300); // avoid accidental double click for next menu
} }
else {
const byte (*current_gmode)[12]= frame_gmodes[menu.get_mode()];
matrix.loadPixels((uint8_t*)current_gmode, MATRIX_HEIGHT * MATRIX_WIDTH);
}
break; break;
} }
case MENU_BOT_SKILLS: { case MENU_BOT_SKILLS: {
if (digitalRead(P2_BTN_BOTTOM) == LOW && current_bot_menu_idx < sizeof(frame_bot_skills)/sizeof(frame_bot_skills[0]) -1) { // switch difficulty level
current_bot_menu_idx += 1; if (digitalRead(P2_BTN_BOTTOM) == LOW) {
update_menu_bot_skills= true; menu.increase_skills();
const byte (*current_skill_frame)[12]= frame_bot_skills[menu.get_skill()];
matrix.loadPixels((uint8_t*)current_skill_frame, MATRIX_HEIGHT * MATRIX_WIDTH);
delay(300);
} }
else if (digitalRead(P2_BTN_UP) == LOW && current_bot_menu_idx > 0) { else if (digitalRead(P2_BTN_UP) == LOW) {
current_bot_menu_idx -= 1; menu.decrease_skills();
update_menu_bot_skills= true; const byte (*current_skill_frame)[12]= frame_bot_skills[menu.get_skill()];
} matrix.loadPixels((uint8_t*)current_skill_frame, MATRIX_HEIGHT * MATRIX_WIDTH);
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW) { delay(300);
if (!p1 -> is_human()) p1 -> set_skills(current_bot_menu_idx + 1);
if (!p2 -> is_human()) p2 -> set_skills(current_bot_menu_idx + 1);
game_status= TIMER;
update_menu_bot_skills= false;
} }
if (update_menu_bot_skills) { // choose difficulty level
const byte (*current_skill_frame)[12]= frame_bot_skills[current_bot_menu_idx]; else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW) {
if (!p1 -> is_human()) p1 -> set_skills(menu.get_skill() + 1);
if (!p2 -> is_human()) p2 -> set_skills(menu.get_skill() + 1);
game_status= TIMER;
}
else {
const byte (*current_skill_frame)[12]= frame_bot_skills[menu.get_skill()];
matrix.loadPixels((uint8_t*)current_skill_frame, MATRIX_HEIGHT * MATRIX_WIDTH); matrix.loadPixels((uint8_t*)current_skill_frame, MATRIX_HEIGHT * MATRIX_WIDTH);
update_menu= false;
delay(300);
} }
break; break;
} }
@@ -159,7 +159,7 @@ void loop() {
renderer.render_timer(i); renderer.render_timer(i);
delay(1000); delay(1000);
} }
game_status= MENU; game_status= RUN;
// delay the first ball movement // delay the first ball movement
exec_t2= millis() + FIRST_START_BALL_DELAY; exec_t2= millis() + FIRST_START_BALL_DELAY;
break; break;
@@ -206,8 +206,9 @@ void loop() {
// restart game once one button is pressed // restart game once one button is pressed
if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW || if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW ||
digitalRead(P2_BTN_UP) == LOW || digitalRead(P2_BTN_BOTTOM) == LOW) { digitalRead(P2_BTN_UP) == LOW || digitalRead(P2_BTN_BOTTOM) == LOW) {
game_status= TIMER;
engine.reset(); engine.reset();
game_status= MENU;
delay(300);
} }
break; break;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.7 MiB

42
src/menu.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include "menu.h"
void Menu::next_mode() {
if (_game_mode < _game_modes(COUNT_MODES) - 1)
_game_mode= _game_modes(_game_mode+1);
}
void Menu::prev_mode() {
if (_game_mode > 0) {
_game_mode= _game_modes(_game_mode-1);
}
}
uint8_t Menu::get_mode() {
return _game_mode;
}
uint8_t Menu::number_of_bots() {
if (_game_mode == PVC) return 1;
else if (_game_mode == CVC) return 2;
return 0;
}
void Menu::increase_skills() {
if (_bot_skill < _bot_skill_levels(COUNT_SKILLS) - 1)
_bot_skill= _bot_skill_levels(_bot_skill+1);
}
void Menu::decrease_skills() {
if (_bot_skill > 0) {
_bot_skill= _bot_skill_levels(_bot_skill-1);
}
}
uint8_t Menu::get_skill() {
return _bot_skill;
}
void Menu::reset_menu() {
_game_mode= PVP;
_bot_skill= EASY;
}

26
src/menu.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef MENU_H
#define MENU_H
#include <Arduino.h>
#include "font.h"
class Menu {
private:
enum _game_modes : uint8_t {PVP, PVC, CVC, COUNT_MODES};
_game_modes _game_mode = PVP;
enum _bot_skill_levels : uint8_t {EASY, HARD, COUNT_SKILLS};
_bot_skill_levels _bot_skill = EASY;
public:
void next_mode();
void prev_mode();
uint8_t get_mode();
uint8_t number_of_bots();
void increase_skills();
void decrease_skills();
uint8_t get_skill();
void reset_menu();
};
#endif

View File

@@ -121,7 +121,7 @@ uint8_t BotPaddle::get_skills() {
} }
void BotPaddle::set_skills(uint8_t skills) { void BotPaddle::set_skills(uint8_t skills) {
if (skills < 0) _skills= 0; if (skills < 1) _skills= 1;
else if (skills > 1) _skills= 1; else if (skills > 2) _skills= 2;
else _skills= skills; else _skills= skills;
} }