diff --git a/src/display/Vector.h b/src/display/Vector.h index 3896d03..2477c04 100644 --- a/src/display/Vector.h +++ b/src/display/Vector.h @@ -51,26 +51,6 @@ public: return {x * i, y * i}; } - Vector bounceInBox(uint8_t width, uint8_t height) const { - double x2 = this->x; - double y2 = this->y; - while (x2 < 0 || x2 >= width) { - if (x2 < 0) { - x2 = -x2; - } else if (x2 >= width) { - x2 = 2 * width - x2; - } - } - while (y2 < 0 || y2 >= height) { - if (y2 < 0) { - y2 = -y2; - } else if (y2 >= height) { - y2 = 2 * height - y2; - } - } - return {x2, y2}; - } - }; #endif diff --git a/src/mode/Pong/Player.h b/src/mode/Pong/Player.h index a0e01f9..768a6f6 100644 --- a/src/mode/Pong/Player.h +++ b/src/mode/Pong/Player.h @@ -7,7 +7,7 @@ class Player { public: - uint8_t position = 0; + uint8_t y = 0; uint8_t size = 2; @@ -17,14 +17,14 @@ public: void randomMove(uint8_t height) { if (moveUp) { - position--; - if (position <= 0 || randomBool(20)) { - moveUp = !moveUp; + y--; + if (y <= 0 || randomBool(20)) { + moveUp = false; } } else { - position++; - if (position + size >= height || randomBool(20)) { - moveUp = !moveUp; + y++; + if (y + size >= height || randomBool(20)) { + moveUp = true; } } } diff --git a/src/mode/Pong/Pong.h b/src/mode/Pong/Pong.h index 00ab919..0a7943b 100644 --- a/src/mode/Pong/Pong.h +++ b/src/mode/Pong/Pong.h @@ -17,7 +17,7 @@ private: Player player1; - Vector position; + Vector ball; Vector velocity; @@ -29,7 +29,7 @@ public: explicit Pong(Display &display) : Mode(display), - position(width / 2.0, height / 2.0), + ball(width / 2.0, height / 2.0), velocity(Vector::polar(random(360), exp10(1))) { timer(0, 100); spawnBall(random(2) == 0 ? -1 : +1); @@ -51,12 +51,12 @@ protected: } break; case PLAY: - position = position.plus(velocity); + ball = ball.plus(velocity); player0.randomMove(height); player1.randomMove(height); + topBottomBounce(); paddleBounce(); checkScoring(); - topBottomBounce(); markDirty(); break; @@ -80,12 +80,12 @@ protected: break; case PLAY: for (int i = 0; i < player0.size; ++i) { - display.set(1, (uint8_t) round(player0.position) + i, GREEN); + display.set(1, (uint8_t) round(player0.y) + i, GREEN); } for (int i = 0; i < player1.size; ++i) { - display.set(width - 2, (uint8_t) round(player1.position) + i, RED); + display.set(width - 2, (uint8_t) round(player1.y) + i, RED); } - display.set((uint8_t) round(position.x), (uint8_t) round(position.y), WHITE); + display.set((uint8_t) round(ball.x), (uint8_t) round(ball.y), WHITE); break; case OVER: if (player0.score > player1.score) { @@ -104,22 +104,32 @@ private: void resetPlayer() { player0.size = 3; player0.score = 0; - player0.position = (height - player0.size) / 2; + player0.y = (height - player0.size) / 2; player1.size = 3; player1.score = 0; - player1.position = (height - player1.size) / 2; + player1.y = (height - player1.size) / 2; } void topBottomBounce() { - position = position.bounceInBox(width, height); + while (ball.y < 0 || ball.y >= height) { + if (ball.y < 0) { + ball.y = -ball.y; + velocity.y = -velocity.y; + } else if (ball.y >= height) { + ball.y = 2 * height - ball.y - 1; + velocity.y = -velocity.y; + } + } } void checkScoring() { - if (position.x < 0) { + if (ball.x < 0) { player1.score++; + Serial.println("Player 1 scored"); spawnBall(+1); - } else if (position.x >= width) { + } else if (ball.x >= width) { player0.score++; + Serial.println("Player 0 scored"); spawnBall(-1); } if (player0.score >= 10 || player1.score >= 10) { @@ -129,18 +139,26 @@ private: } void paddleBounce() { - if (position.x == 1 && player0.position <= position.y && position.y < player0.position + player0.size) { + double paddleHitPosition0 = ball.y - player0.y; + if (ball.x >= 1 && ball.x < 2 && paddleHitPosition0 >= 0 && paddleHitPosition0 < player0.size) { + Serial.printf("Player 0 hit: paddleHitPosition0=%.2f\n", paddleHitPosition0); velocity.x = -velocity.x; - position.x = 3; - } else if (position.x == width - 2 && player1.position <= position.y && position.y < player1.position + player1.size) { + velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition0 - 1)); + ball.x = 3; + return; + } + double paddleHitPosition1 = ball.y - player1.y; + if (ball.x >= width - 2 && ball.x < width - 1 && paddleHitPosition1 >= 0 && paddleHitPosition1 < player1.size) { + Serial.printf("Player 1 hit: paddleHitPosition1=%.2f\n", paddleHitPosition1); velocity.x = -velocity.x; - position.x = width - 4; + velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition1 - 1)); + ball.x = width - 4; } } void spawnBall(int direction) { - position.x = (double) width / 2.0; - position.y = (double) height / 2.0; + ball.x = (double) width / 2.0; + ball.y = (double) height / 2.0; velocity.x = direction; velocity.y = 0; status = SCORE;