diff --git a/arduino_pong.ino b/arduino_pong.ino index d8b0943..09d317a 100644 --- a/arduino_pong.ino +++ b/arduino_pong.ino @@ -23,7 +23,6 @@ ArduinoLEDMatrix matrix; int need_refresh= true; uint8_t hits= 0; -uint8_t ball_delay= INITIAL_BALL_DELAY; long exec_t2= millis(); enum game_statuses : uint8_t { @@ -38,7 +37,7 @@ game_statuses game_status= TIMER; Ball ball(4, 6); Paddle p1(1); Paddle p2(4); -Engine engine(p1, p2, ball); +Engine engine(p1, p2, ball, INITIAL_BALL_DELAY); Renderer renderer(p1, p2, ball, frame, matrix); void setup() { @@ -72,18 +71,10 @@ void loop() { case RUN: need_refresh= check_paddle_movements(p1, p2); - if (exec_t1 - exec_t2 > ball_delay) { + if (exec_t1 - exec_t2 > engine.ball_movement_delay()) { engine.run(); - if (engine.get_event() == P1SCORE || engine.get_event() == P2SCORE) { + if (engine.get_event() == P1SCORE || engine.get_event() == P2SCORE) game_status= SCORE; - } - else if (engine.get_event() == P1_COLLISION || engine.get_event() == P2_COLLISION) { - hits++; - if (hits >= 6 && ball_delay >= 80) { - hits= 0; - ball_delay-= 20; - } - } exec_t2= exec_t1; need_refresh= true; } @@ -95,19 +86,17 @@ void loop() { break; case SCORE: - delay(300); // small delay to let see the last ball position + delay(300); renderer.render_score(); + engine.restart_ball(); delay(1000); - ball.reset_position(); - ball_delay= INITIAL_BALL_DELAY; - 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; // before move again the ball wait a second renderer.render_matrix(); - delay(1000); + exec_t2= millis() + FIRST_START_BALL_DELAY; } break; diff --git a/src/ball.cpp b/src/ball.cpp index 81b61fe..b3e1d91 100644 --- a/src/ball.cpp +++ b/src/ball.cpp @@ -1,6 +1,3 @@ -#include -#include -#include "config.h" #include "ball.h" void Ball::_init_directions(int8_t &_direction) { @@ -30,6 +27,13 @@ void Ball::bounce_on_sides() { _direction_y *= -1; } +int8_t Ball::get_direction_x() { + return _direction_x; +} +int8_t Ball::get_direction_y() { + return _direction_y; +} + void Ball::reset_position () { _x= BALL_RESET_X; _y= BALL_RESET_Y; diff --git a/src/ball.h b/src/ball.h index f358079..6845e5d 100644 --- a/src/ball.h +++ b/src/ball.h @@ -1,7 +1,7 @@ #ifndef BALL_H #define BALL_H -#include +#include #include "config.h" class Ball { @@ -17,6 +17,8 @@ class Ball { void move(); void bounce_on_pad(); void bounce_on_sides(); + int8_t get_direction_x(); + int8_t get_direction_y(); void reset_position (); uint8_t get_x(); uint8_t get_y(); diff --git a/src/engine.cpp b/src/engine.cpp index 97fc261..ccb6890 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -10,48 +10,40 @@ bool Engine::_check_pad_ball_collision(Paddle &p) { return false; } -void Engine::_print_score() { - Serial.print("P1: "); - Serial.print(_p1.get_score()); - Serial.print(" - "); - Serial.print("P2: "); - Serial.print(_p2.get_score()); - Serial.println(); -} - void Engine::run() { + // if (_event == P1SCORE || _event == P2SCORE) this -> _soft_reset(); + _event= NONE; _ball.move(); uint8_t bx= _ball.get_x(); uint8_t by= _ball.get_y(); - + int8_t ball_dir= _ball.get_direction_x(); // pad is 1 pixel far from the edge, so i need to calc this delta - if (bx <= 1) { + // check also if the ball is already moving away, to skip useless checks + if (bx <= 1 && ball_dir < 0) { // score the point only if ball reached the edge - if (this -> _check_pad_ball_collision(_p1) && bx == 1) { + if (this -> _check_pad_ball_collision(_p1) && bx <= 1) { _ball.bounce_on_pad(); _event= P1_COLLISION; + _hits++; } else if (bx <= 0) { // p2 scores _p2.increase_score(); - Serial.println("Player 2 Scores"); - this -> _print_score(); _event= P2SCORE; return; } } - else if (bx >= MATRIX_WIDTH-2) { + else if (bx >= MATRIX_WIDTH-2 && ball_dir > 0) { // score the point only if ball reached the edge - if (this -> _check_pad_ball_collision(_p2) && bx == MATRIX_WIDTH-2) { + if (this -> _check_pad_ball_collision(_p2) && bx >= MATRIX_WIDTH-2) { _ball.bounce_on_pad(); _event= P2_COLLISION; + _hits++; } else if (bx >= MATRIX_WIDTH-1) { // p1 scores _p1.increase_score(); - Serial.println("Player 1 Scores"); - this -> _print_score(); _event= P1SCORE; return; } @@ -61,14 +53,29 @@ void Engine::run() { _ball.bounce_on_sides(); _event= WALL_COLLISION; } + + if (_hits >= 6 && _ball_mv_delay >= 80) { + _hits= 0; + _ball_mv_delay -= 20; + } } +uint8_t Engine::ball_movement_delay() { + return _ball_mv_delay; +} + + EngineEvents Engine::get_event() { return _event; } +void Engine::restart_ball() { + _ball.reset_position(); + _ball_mv_delay= INITIAL_BALL_DELAY; +} + void Engine::reset() { + this -> restart_ball(); _p1.reset(); _p2.reset(); - _ball.reset_position(); } diff --git a/src/engine.h b/src/engine.h index e4c87e9..61051dd 100644 --- a/src/engine.h +++ b/src/engine.h @@ -15,17 +15,20 @@ class Engine { Paddle& _p2; Ball& _ball; EngineEvents _event= NONE; + uint8_t _ball_mv_delay; + uint8_t _hits = 0; bool _check_pad_ball_collision(Paddle &p); - void _print_score(); public: // inizialize Engine constructor, linking all args with private args - Engine(Paddle &p_one, Paddle &p_two, Ball &ball) - : _p1(p_one), _p2(p_two), _ball(ball) {} + 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) {} void run(); + uint8_t ball_movement_delay(); EngineEvents get_event(); + void restart_ball(); void reset(); }; diff --git a/src/renderer.cpp b/src/renderer.cpp index 775d530..280ee9c 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -60,13 +60,9 @@ void Renderer::render_score() { void Renderer::render_winner() { this -> _clear_matrix(); // check winner - if (_p1.get_score() > _p2.get_score()) { - Serial.println("Player 1 wins!!!"); + if (_p1.get_score() > _p2.get_score()) _matrix.loadSequence(pone_wins); - } - else { - Serial.println("Player 2 wins!!!"); + else _matrix.loadSequence(ptwo_wins); - } _matrix.play(true); }