Pong: paddle can change angle + top/bottom bounce
This commit is contained in:
parent
89ed7b1c21
commit
7539dbb7b0
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user