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};
|
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
|
#endif
|
||||||
|
|||||||
@ -7,7 +7,7 @@ class Player {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint8_t position = 0;
|
uint8_t y = 0;
|
||||||
|
|
||||||
uint8_t size = 2;
|
uint8_t size = 2;
|
||||||
|
|
||||||
@ -17,14 +17,14 @@ public:
|
|||||||
|
|
||||||
void randomMove(uint8_t height) {
|
void randomMove(uint8_t height) {
|
||||||
if (moveUp) {
|
if (moveUp) {
|
||||||
position--;
|
y--;
|
||||||
if (position <= 0 || randomBool(20)) {
|
if (y <= 0 || randomBool(20)) {
|
||||||
moveUp = !moveUp;
|
moveUp = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
position++;
|
y++;
|
||||||
if (position + size >= height || randomBool(20)) {
|
if (y + size >= height || randomBool(20)) {
|
||||||
moveUp = !moveUp;
|
moveUp = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ private:
|
|||||||
|
|
||||||
Player player1;
|
Player player1;
|
||||||
|
|
||||||
Vector position;
|
Vector ball;
|
||||||
|
|
||||||
Vector velocity;
|
Vector velocity;
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ public:
|
|||||||
|
|
||||||
explicit Pong(Display &display) :
|
explicit Pong(Display &display) :
|
||||||
Mode(display),
|
Mode(display),
|
||||||
position(width / 2.0, height / 2.0),
|
ball(width / 2.0, height / 2.0),
|
||||||
velocity(Vector::polar(random(360), exp10(1))) {
|
velocity(Vector::polar(random(360), exp10(1))) {
|
||||||
timer(0, 100);
|
timer(0, 100);
|
||||||
spawnBall(random(2) == 0 ? -1 : +1);
|
spawnBall(random(2) == 0 ? -1 : +1);
|
||||||
@ -51,12 +51,12 @@ protected:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PLAY:
|
case PLAY:
|
||||||
position = position.plus(velocity);
|
ball = ball.plus(velocity);
|
||||||
player0.randomMove(height);
|
player0.randomMove(height);
|
||||||
player1.randomMove(height);
|
player1.randomMove(height);
|
||||||
|
topBottomBounce();
|
||||||
paddleBounce();
|
paddleBounce();
|
||||||
checkScoring();
|
checkScoring();
|
||||||
topBottomBounce();
|
|
||||||
markDirty();
|
markDirty();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -80,12 +80,12 @@ protected:
|
|||||||
break;
|
break;
|
||||||
case PLAY:
|
case PLAY:
|
||||||
for (int i = 0; i < player0.size; ++i) {
|
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) {
|
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;
|
break;
|
||||||
case OVER:
|
case OVER:
|
||||||
if (player0.score > player1.score) {
|
if (player0.score > player1.score) {
|
||||||
@ -104,22 +104,32 @@ private:
|
|||||||
void resetPlayer() {
|
void resetPlayer() {
|
||||||
player0.size = 3;
|
player0.size = 3;
|
||||||
player0.score = 0;
|
player0.score = 0;
|
||||||
player0.position = (height - player0.size) / 2;
|
player0.y = (height - player0.size) / 2;
|
||||||
player1.size = 3;
|
player1.size = 3;
|
||||||
player1.score = 0;
|
player1.score = 0;
|
||||||
player1.position = (height - player1.size) / 2;
|
player1.y = (height - player1.size) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void topBottomBounce() {
|
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() {
|
void checkScoring() {
|
||||||
if (position.x < 0) {
|
if (ball.x < 0) {
|
||||||
player1.score++;
|
player1.score++;
|
||||||
|
Serial.println("Player 1 scored");
|
||||||
spawnBall(+1);
|
spawnBall(+1);
|
||||||
} else if (position.x >= width) {
|
} else if (ball.x >= width) {
|
||||||
player0.score++;
|
player0.score++;
|
||||||
|
Serial.println("Player 0 scored");
|
||||||
spawnBall(-1);
|
spawnBall(-1);
|
||||||
}
|
}
|
||||||
if (player0.score >= 10 || player1.score >= 10) {
|
if (player0.score >= 10 || player1.score >= 10) {
|
||||||
@ -129,18 +139,26 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void paddleBounce() {
|
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;
|
velocity.x = -velocity.x;
|
||||||
position.x = 3;
|
velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition0 - 1));
|
||||||
} else if (position.x == width - 2 && player1.position <= position.y && position.y < player1.position + player1.size) {
|
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;
|
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) {
|
void spawnBall(int direction) {
|
||||||
position.x = (double) width / 2.0;
|
ball.x = (double) width / 2.0;
|
||||||
position.y = (double) height / 2.0;
|
ball.y = (double) height / 2.0;
|
||||||
velocity.x = direction;
|
velocity.x = direction;
|
||||||
velocity.y = 0;
|
velocity.y = 0;
|
||||||
status = SCORE;
|
status = SCORE;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user