Side ProjectJavaScriptp5.jsTwo Player

Building Ping Pong from scratch, in JavaScript.

No game engine. Just p5.js, a canvas, and two paddles. Pong looks deceptively simple until you build it. Getting the physics, collision response, and game feel right was the most honest test of real-time JavaScript I could have set myself.

JavaScript · p5.js
p5.js from scratch
2 · Keyboard & Mouse
Live & Playable
Try it yourself →

No install. No download.
Player 1: ↑/↓ keys · Player 2: mouse or trackpad.

Skills Demonstrated
JavaScriptp5.jsGame Loop ArchitectureBall Physics & ReflectionAABB Collision DetectionDelta Time MovementKeyboard & Mouse InputScore & Game StateSpeed Scaling
What This Demonstrates

Three things that required real thinking.

01

Physics from first principles

No physics library. Just vectors, velocity, and reflection math. Getting the ball to bounce off a moving paddle at the right angle required understanding the geometry directly.

02

Two players, two different inputs

One player uses the keyboard, the other uses the mouse or trackpad. Handling two completely different input types simultaneously and mapping them to the same paddle logic needed deliberate design.

03

Feel over correctness

A physically correct Pong still feels wrong if ball speed doesn't ramp up. Tuning acceleration, max speed, and serve direction was a lesson in game feel, not just code.

A Glimpse Into My Code

Written from scratch. No shortcuts.

Snapshots rather than full source. Enough to show how I think and structure code, without handing it over to copy. Every line was reasoned through, not lifted from a tutorial.

ball.js · collision & physics
Ball collision and physics code
sketch.js · score & game state
Score and game state code

Full source is intentionally kept private. If you'd like to walk through the logic together, reach out.

Reflection

What building it taught me.

Biggest insight

Simple games hide hard problems

Pong looks like four lines of code. It isn't. Getting the bounce angle, the serve pause, and the speed curve all feeling right took far longer than the initial working prototype. Polish is most of the work.

Hardest part

Collision that doesn't tunnel

A fast ball can skip through a paddle in a single frame. Solving it meant checking the ball's predicted path, not just its current position. A real lesson in thinking one step ahead.

What surprised me

Game feel is a separate problem from game logic

The game worked long before it felt good. Small things like serve delay, speed ramping, and bounce angle made a bigger difference to the experience than any piece of core logic.

What's next

Online multiplayer via WebSockets

Same-keyboard play has limits. Taking this online, with real-time game state synced over a network, is the natural next step and the right reason to finally learn WebSockets.

apoorvagoyal1020@gmail.com
Open to Product Design, UX Design and Design/Creative Technology roles
Made withlove and codeby Apoorva Goyal
apoorvagoyal1020@gmail.com
Open to Product Design, UX Design and Design/Creative Technology roles
Made withlove and codeby Apoorva Goyal
apoorvagoyal1020@gmail.com
Open to Product Design, UX Design and Design/Creative Technology roles
Made withlove and codeby Apoorva Goyal
apoorvagoyal1020@gmail.com
Open to Product Design, UX Design and Design/Creative Technology roles
Made withlove and codeby Apoorva Goyal