Public Access
Pong: a paddle steered by tilting
The player's move goes from -1 to 1 instead of three steps, and two rules make it from the device's tilt: where the paddle is asked to be (it rolls to the low side, about 15 degrees for the whole height) and how to get there without overshooting. Host-tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
This commit is contained in:
+14
-3
@@ -11,6 +11,17 @@ constexpr float kSteepest = 0.87f; // 50 degrees, in radians: off the very end
|
||||
float clampPaddle(float y) { return std::clamp(y, Pong::kPaddleH / 2, Pong::kHeight - Pong::kPaddleH / 2); }
|
||||
} // namespace
|
||||
|
||||
float tiltTarget(float pitch, float level) {
|
||||
constexpr float kFullTilt = 0.26f; // 15 degrees either way covers the whole field
|
||||
float travel = Pong::kHeight / 2 - Pong::kPaddleH / 2;
|
||||
return Pong::kHeight / 2 + std::clamp((pitch - level) / kFullTilt, -1.0f, 1.0f) * travel;
|
||||
}
|
||||
|
||||
float moveToward(float paddleY, float targetY) {
|
||||
constexpr float kSlowWithin = 10; // pixels: closer than that, it eases in
|
||||
return std::clamp((targetY - paddleY) / kSlowWithin, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void Pong::start() {
|
||||
playerScore_ = deviceScore_ = rally_ = longest_ = 0;
|
||||
player_ = device_ = kHeight / 2;
|
||||
@@ -39,7 +50,7 @@ void Pong::bounceOff(float paddleY, bool toRight) {
|
||||
vy_ = std::sin(where * kSteepest) * speed_;
|
||||
}
|
||||
|
||||
uint8_t Pong::step(float seconds, int move) {
|
||||
uint8_t Pong::step(float seconds, float move) {
|
||||
uint8_t events = 0;
|
||||
seconds = std::min(seconds, 0.25f); // a held-up loop is not a quarter of the field
|
||||
while (seconds > 0 && phase_ != Phase::Over) {
|
||||
@@ -50,8 +61,8 @@ uint8_t Pong::step(float seconds, int move) {
|
||||
return events;
|
||||
}
|
||||
|
||||
uint8_t Pong::tick(float dt, int move) {
|
||||
player_ = clampPaddle(player_ + (move < 0 ? -1 : move > 0 ? 1 : 0) * kPlayerSpeed * dt);
|
||||
uint8_t Pong::tick(float dt, float move) {
|
||||
player_ = clampPaddle(player_ + std::clamp(move, -1.0f, 1.0f) * kPlayerSpeed * dt);
|
||||
// The device watches the ball once it comes its way, and waits in the middle otherwise.
|
||||
float target = vx_ > 0 && phase_ == Phase::Play ? y_ : kHeight / 2;
|
||||
float reach = kDeviceSpeed * dt;
|
||||
|
||||
+13
-4
@@ -9,6 +9,15 @@ namespace roro::games {
|
||||
// Pong against the device (issue #101): the player's paddle on the left, the device's on the
|
||||
// right, first to 7. The ball goes faster with each return, and the device's paddle only moves so
|
||||
// fast: a steep, fast ball gets past it. Lengths are pixels of the 240 x 122 field, times seconds.
|
||||
// Where the paddle is asked to be when the device is tilted (issue #101's follow-up): its top
|
||||
// lowered, the paddle goes up, as a ball rolls to the low side (it felt the right way round on the
|
||||
// device); held as it was when the game began, the middle. `pitch` and
|
||||
// `level` are "up" along the device's top-bottom axis, -1 to 1, as the accelerometer gives it.
|
||||
float tiltTarget(float pitch, float level);
|
||||
// The move that brings the paddle at `paddleY` to `targetY` with no overshoot: full speed far away,
|
||||
// slower close by.
|
||||
float moveToward(float paddleY, float targetY);
|
||||
|
||||
class Pong {
|
||||
public:
|
||||
static constexpr float kWidth = 240, kHeight = 122;
|
||||
@@ -23,9 +32,9 @@ class Pong {
|
||||
|
||||
explicit Pong(uint32_t seed) : rng_(seed) { start(); }
|
||||
void start();
|
||||
// `seconds` later, with the player's paddle asked up (-1), down (1) or left alone (0).
|
||||
// What happened, as Events.
|
||||
uint8_t step(float seconds, int move);
|
||||
// `seconds` later, with the player's paddle asked up (-1), down (1) or left alone (0), or
|
||||
// anything between for a slower move. What happened, as Events.
|
||||
uint8_t step(float seconds, float move);
|
||||
|
||||
Phase phase() const { return phase_; }
|
||||
float ballX() const { return x_; }
|
||||
@@ -40,7 +49,7 @@ class Pong {
|
||||
int longestRally() const { return longest_; } // in this game
|
||||
|
||||
private:
|
||||
uint8_t tick(float dt, int move);
|
||||
uint8_t tick(float dt, float move);
|
||||
void serve(bool toPlayer);
|
||||
bool meets(float paddleY) const;
|
||||
void bounceOff(float paddleY, bool toRight);
|
||||
|
||||
Reference in New Issue
Block a user