diff --git a/arduino_pong.ino b/arduino_pong.ino index 91b637f..5b2e41f 100644 --- a/arduino_pong.ino +++ b/arduino_pong.ino @@ -33,15 +33,19 @@ enum game_statuses : uint8_t { GAMEOVER, WAIT, }; -game_statuses game_status= TIMER; +game_statuses game_status= MENU; Ball ball(4, 6); -HumanPaddle p1(1, P1_BTN_UP, P1_BTN_BOTTOM); -// HumanPaddle p2(4, P2_BTN_UP, P2_BTN_BOTTOM); -// BotPaddle p1(1, 0, 2); -BotPaddle p2(4, MATRIX_WIDTH-1, 1); -Engine engine(p1, p2, ball, INITIAL_BALL_DELAY); -Renderer renderer(p1, p2, ball, frame, matrix); + +Paddle* p1= nullptr; +Paddle* p2= nullptr; +HumanPaddle human_pad1(1, P1_BTN_UP, P1_BTN_BOTTOM); +HumanPaddle human_pad2(4, P2_BTN_UP, P2_BTN_BOTTOM); +BotPaddle bot_pad1(1, 0, 2); +BotPaddle bot_pad2(4, MATRIX_WIDTH-1, 2); + +Engine engine(ball, INITIAL_BALL_DELAY); +Renderer renderer(ball, frame, matrix); void setup() { Serial.begin(9600); @@ -63,9 +67,31 @@ void loop() { case MENU: // show menu on the matrix + // matrix.renderBitmap(pvp_frame, MATRIX_HEIGHT, MATRIX_WIDTH); // 1. P vs P + if (digitalRead(P1_BTN_UP) == LOW) { + p1= &human_pad1; + p2= &human_pad2; + engine.set_players(p1, p2); + renderer.set_players(p1, p2); + game_status= TIMER; + } // 2. P vs CPU + else if (digitalRead(P1_BTN_BOTTOM) == LOW) { + p1= &human_pad1; + p2= &bot_pad2; + engine.set_players(p1, p2); + renderer.set_players(p1, p2); + game_status= TIMER; + } // 3. CPU vs CPU + else if (digitalRead(P2_BTN_UP) == LOW) { + p1= &bot_pad1; + p2= &bot_pad2; + engine.set_players(p1, p2); + renderer.set_players(p1, p2); + game_status= TIMER; + } // slideshow menu break; @@ -101,7 +127,7 @@ void loop() { renderer.render_score(); engine.restart_ball(); delay(1000); - if (p1.get_score() >= MAX_POINTS || p2.get_score() >= MAX_POINTS) + if (p1 -> get_score() >= MAX_POINTS || p2 -> get_score() >= MAX_POINTS) game_status= GAMEOVER; else { game_status= RUN; diff --git a/src/engine.cpp b/src/engine.cpp index 4d4cef2..77c8a46 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,7 +1,7 @@ #include "engine.h" -bool Engine::_check_pad_ball_collision(Paddle &p) { - uint8_t ppos= p.get_position(); +bool Engine::_check_pad_ball_collision(Paddle *p) { + uint8_t ppos= p -> get_position(); for (int p= ppos; p < ppos + PADDLE_LENGTH; p++) { if (_ball.get_y() == p) { return true; @@ -29,7 +29,7 @@ void Engine::run() { } else if (bx <= 0) { // p2 scores - _p2.increase_score(); + _p2 -> increase_score(); _event= P2SCORE; return; } @@ -43,7 +43,7 @@ void Engine::run() { } else if (bx >= MATRIX_WIDTH-1) { // p1 scores - _p1.increase_score(); + _p1 -> increase_score(); _event= P1SCORE; return; } @@ -60,13 +60,18 @@ void Engine::run() { } } +void Engine::set_players(Paddle *p1, Paddle *p2) { + _p1= p1; + _p2= p2; +} + bool Engine::control_players() { bool need_refresh= false; - if (_p1.is_human()) need_refresh |= _p1.check_pad_movement(); - else need_refresh |= _p1.check_pad_movement(_ball); - if (_p2.is_human()) need_refresh |= _p2.check_pad_movement(); - else need_refresh |= _p2.check_pad_movement(_ball); + if (_p1 -> is_human()) need_refresh |= _p1 -> check_pad_movement(); + else need_refresh |= _p1 -> check_pad_movement(_ball); + if (_p2 -> is_human()) need_refresh |= _p2 -> check_pad_movement(); + else need_refresh |= _p2 -> check_pad_movement(_ball); return need_refresh; } @@ -86,6 +91,6 @@ void Engine::restart_ball() { void Engine::reset() { this -> restart_ball(); - _p1.reset(); - _p2.reset(); + _p1 -> reset(); + _p2 -> reset(); } diff --git a/src/engine.h b/src/engine.h index 5f453c8..bb93562 100644 --- a/src/engine.h +++ b/src/engine.h @@ -11,21 +11,22 @@ enum EngineEvents : uint8_t {NONE, P1SCORE, P2SCORE, P1_COLLISION, P2_COLLISION, class Engine { private: - Paddle& _p1; - Paddle& _p2; + Paddle* _p1; + Paddle* _p2; Ball& _ball; EngineEvents _event= NONE; uint8_t _ball_mv_delay; uint8_t _hits = 0; - bool _check_pad_ball_collision(Paddle &p); + bool _check_pad_ball_collision(Paddle *p); public: // inizialize Engine constructor, linking all args with private args - Engine(Paddle &p_one, Paddle &p_two, Ball &ball, uint8_t ball_mv_delay) - : _p1(p_one), _p2(p_two), _ball(ball), _ball_mv_delay(ball_mv_delay) {} + Engine(Ball &ball, uint8_t ball_mv_delay) + : _ball(ball), _ball_mv_delay(ball_mv_delay) {} void run(); + void set_players(Paddle *p_one, Paddle *p_two); bool control_players(); uint8_t ball_movement_delay(); EngineEvents get_event(); diff --git a/src/font.cpp b/src/font.cpp new file mode 100644 index 0000000..78e26c4 --- /dev/null +++ b/src/font.cpp @@ -0,0 +1,214 @@ +#include "font.h"; + +const uint32_t pone_wins[5][4] = { + { + 0x78, + 0xc4847844, + 0x440e000, + 500 + }, + { + 0x11, + 0x1101501, + 0x501f0000, + 500 + }, + { + 0xe, + 0x400400, + 0x400e0000, + 500 + }, + { + 0x9, + 0xd00b00, + 0x90090000, + 500 + }, + { + 0xf, + 0x800f00, + 0x100f0000, + 500 + } +}; +const uint32_t ptwo_wins[5][4] = { + { + 0x79, + 0xe48279e4, + 0x1041e000, + 500 + }, + { + 0x11, + 0x1101501, + 0x501f0000, + 500 + }, + { + 0xe, + 0x400400, + 0x400e0000, + 500 + }, + { + 0x9, + 0xd00b00, + 0x90090000, + 500 + }, + { + 0xf, + 0x800f00, + 0x100f0000, + 500 + } +}; + +const byte font_pong[10][8][3] = { + // Number 0 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 1, 0, 1 }, + { 1, 0, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 1 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 1, 0 }, + { 0, 1, 0 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 2 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 1, 1, 1 }, + { 1, 0, 0 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 3 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 4 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 0, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 0, 0, 1 }, + { 0, 0, 0 } + }, + // Number 5 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 1, 0, 0 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 6 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 7 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 0, 0, 1 }, + { 0, 0, 1 }, + { 0, 0, 1 }, + { 0, 0, 0 } + }, + // Number 8 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 0 } + }, + // Number 9 + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 0, 1 }, + { 0, 0, 1 }, + { 0, 0, 0 } + }, +}; + +const byte pvp_frame[MATRIX_HEIGHT][MATRIX_WIDTH] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 }, + { 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, + { 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, + { 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +const byte pvc_frame[MATRIX_HEIGHT][MATRIX_WIDTH] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, + { 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + { 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, + { 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +const byte cvc_frame[MATRIX_HEIGHT][MATRIX_WIDTH] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + { 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, + { 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +const byte (*game_modes[3])[12]= {pvp_frame, pvc_frame, cvc_frame}; diff --git a/src/font.h b/src/font.h index 2f5bfcd..8d8b65c 100644 --- a/src/font.h +++ b/src/font.h @@ -2,183 +2,15 @@ #define FONT_H #include +#include "config.h" -const uint32_t pone_wins[][4] = { - { - 0x78, - 0xc4847844, - 0x440e000, - 500 - }, - { - 0x11, - 0x1101501, - 0x501f0000, - 500 - }, - { - 0xe, - 0x400400, - 0x400e0000, - 500 - }, - { - 0x9, - 0xd00b00, - 0x90090000, - 500 - }, - { - 0xf, - 0x800f00, - 0x100f0000, - 500 - } -}; -const uint32_t ptwo_wins[][4] = { - { - 0x79, - 0xe48279e4, - 0x1041e000, - 500 - }, - { - 0x11, - 0x1101501, - 0x501f0000, - 500 - }, - { - 0xe, - 0x400400, - 0x400e0000, - 500 - }, - { - 0x9, - 0xd00b00, - 0x90090000, - 500 - }, - { - 0xf, - 0x800f00, - 0x100f0000, - 500 - } -}; +extern const uint32_t pone_wins[5][4]; +extern const uint32_t ptwo_wins[5][4]; +extern const byte font_pong[10][8][3]; -const byte font_pong[10][8][3] = { - // Number 0 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 1, 0, 1 }, - { 1, 0, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 1 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 0 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 2 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 1, 1, 1 }, - { 1, 0, 0 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 3 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 4 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 0, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 0, 0, 1 }, - { 0, 0, 0 } - }, - // Number 5 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 1, 0, 0 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 6 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 7 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 0, 0, 1 }, - { 0, 0, 1 }, - { 0, 0, 1 }, - { 0, 0, 0 } - }, - // Number 8 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 0 } - }, - // Number 9 - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 0, 0, 1 }, - { 0, 0, 1 }, - { 0, 0, 0 } - }, -}; +extern const byte pvp_frame[MATRIX_HEIGHT][MATRIX_WIDTH]; +extern const byte pvc_frame[MATRIX_HEIGHT][MATRIX_WIDTH]; +extern const byte cvc_frame[MATRIX_HEIGHT][MATRIX_WIDTH]; +extern const byte (*game_modes[3])[MATRIX_WIDTH]; #endif diff --git a/src/renderer.cpp b/src/renderer.cpp index 280ee9c..d5e5c82 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -9,6 +9,11 @@ void Renderer::_clear_matrix() { } } +void Renderer::set_players(Paddle *p1, Paddle *p2) { + _p1= p1; + _p2= p2; +} + void Renderer::render_timer(uint8_t seconds) { this -> _clear_matrix(); @@ -22,8 +27,8 @@ void Renderer::render_timer(uint8_t seconds) { void Renderer::render_matrix() { this -> _clear_matrix(); - uint8_t p1pos= _p1.get_position(); - uint8_t p2pos= _p2.get_position(); + uint8_t p1pos= _p1 -> get_position(); + uint8_t p2pos= _p2 -> get_position(); // players coords for (int i= p1pos; i < p1pos+PADDLE_LENGTH; i++) { _frame[i][0]= 1; @@ -46,12 +51,12 @@ void Renderer::render_score() { for (int h=0; h < 8; h++) { for (int w=0; w < 3; w++) { - _frame[h][w+1]= font_pong[_p1.get_score()][h][w]; + _frame[h][w+1]= font_pong[_p1 -> get_score()][h][w]; } } for (int h=0; h < 8; h++) { for (int w=0; w < 3; w++) { - _frame[h][w+8]= font_pong[_p2.get_score()][h][w]; + _frame[h][w+8]= font_pong[_p2 -> get_score()][h][w]; } } _matrix.renderBitmap(_frame, MATRIX_HEIGHT, MATRIX_WIDTH); @@ -60,7 +65,7 @@ void Renderer::render_score() { void Renderer::render_winner() { this -> _clear_matrix(); // check winner - if (_p1.get_score() > _p2.get_score()) + if (_p1 -> get_score() > _p2 -> get_score()) _matrix.loadSequence(pone_wins); else _matrix.loadSequence(ptwo_wins); diff --git a/src/renderer.h b/src/renderer.h index 02e8a47..61370dc 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -12,8 +12,8 @@ class Renderer { private: // define player coordinates - Paddle& _p1; - Paddle& _p2; + Paddle* _p1; + Paddle* _p2; Ball& _ball; byte (&_frame)[MATRIX_HEIGHT][MATRIX_WIDTH]; ArduinoLEDMatrix& _matrix; @@ -21,9 +21,10 @@ class Renderer { void _clear_matrix(); public: - Renderer (Paddle &p1, Paddle &p2, Ball &ball, byte (&frame)[MATRIX_HEIGHT][MATRIX_WIDTH], ArduinoLEDMatrix &matrix) - : _p1(p1), _p2(p2), _ball(ball), _frame(frame), _matrix(matrix) {} + Renderer (Ball &ball, byte (&frame)[MATRIX_HEIGHT][MATRIX_WIDTH], ArduinoLEDMatrix &matrix) + : _ball(ball), _frame(frame), _matrix(matrix) {} + void set_players(Paddle *p1, Paddle *p2); void render_timer(uint8_t seconds); void render_matrix(); void render_score();