Add a pong animation
The video frame plays the paddle: it slides along the bottom of the screen and nowhere else, a square ball runs the diagonals off the walls, and every ball that gets past the frame puts one on a seven-segment counter in the top right. The frame is solid on all four sides, not just its face, so a ball that comes at its flank or up under it is turned away too. Which side a hit came in on is read from where the ball was before the step, with a shallowest-penetration fallback for the frame sliding into the ball rather than the other way round — without that the ball tunnels in and rattles inside the frame. The face keeps the original's angle rule, where the hit position sets the departure angle, so rallies develop instead of the ball retracing one line; the other three sides are plain reflections. The paddle steers by predictLanding, which unfolds the wall reflections analytically instead of simulating them. A paddle that outruns the ball never loses, so PONG_MISS_CHANCE of the time it aims a width wide and lets one through — otherwise the counter would sit on 00 all night. The digits are SVG polygons built from a segment map, so the era-correct display costs no font file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H9v2Xoa6eoeGYpK6gp95k9
This commit is contained in:
@@ -60,12 +60,41 @@ export const WASH_STRENGTH = 0.55;
|
||||
// has the screen to itself, so it does not have to leave room for a second one.
|
||||
export const WASH_FRAME_SCALE = 0.6;
|
||||
|
||||
// Pong: the frame is the paddle, so it gets its own size — narrow enough that
|
||||
// it can miss, wide enough that the video in it is still worth watching.
|
||||
export const PONG_FRAME_SCALE = 0.3;
|
||||
|
||||
// How fast the ball travels, and how fast the paddle may slide, in pixels per
|
||||
// second. The paddle has to outrun the ball to defend a wide screen, but not by
|
||||
// so much that it teleports under every shot.
|
||||
export const PONG_BALL_SPEED = 420;
|
||||
export const PONG_PADDLE_SPEED = 760;
|
||||
|
||||
// The ball is a square this fraction of the screen's short side.
|
||||
export const PONG_BALL_SIZE = 0.028;
|
||||
|
||||
// Gap between the paddle and the bottom edge, as a fraction of the short side.
|
||||
export const PONG_PADDLE_MARGIN = 0.04;
|
||||
|
||||
// Steepest angle off the paddle, in degrees from straight up. Hitting the ball
|
||||
// with the edge of the paddle sends it out this far.
|
||||
export const PONG_MAX_ANGLE = 60;
|
||||
|
||||
// How often the paddle deliberately comes up short, so the counter in the
|
||||
// corner actually moves. Without this a paddle that outruns the ball never
|
||||
// loses a rally.
|
||||
export const PONG_MISS_CHANCE = 0.25;
|
||||
|
||||
// Seconds the ball waits out of play after it gets past the paddle.
|
||||
export const PONG_SERVE_SECONDS = 1.1;
|
||||
|
||||
// The frame animations, keyed by the id sent over the socket. The names must
|
||||
// match the registry in public/player/motion.js, which supplies the code.
|
||||
export const ANIMATIONS = {
|
||||
bounce: { label: 'Bounce' },
|
||||
corners: { label: 'Corners' },
|
||||
drag: { label: 'Drag & resize' },
|
||||
pong: { label: 'Pong' },
|
||||
trail: { label: 'Comet trail' },
|
||||
wash: { label: 'Colour wash' },
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user