14

Wanted a proper Asteroids: momentum-based ship, thrust and rotation, bullets, splitting rocks. The tricky feel bits are the inertia (you drift, you don't stop instantly) and seamless screen wrap so objects half-off one edge appear on the other with no popping.

My first attempt snapped the ship's velocity to zero when I released thrust (no inertia) and objects blinked across the screen edges. I made the prompt demand Newtonian thrust with drag and a toroidal wrap that renders duplicates near the borders so wrapping is visually continuous.

Accepted answer below nailed the rock-splitting mass conservation.

THE PROMPT
Build Asteroids in a single HTML canvas file, vanilla JS, 60fps, vector-line art (no sprites).

Ship physics: rotate with left/right, thrust with up. Thrust adds acceleration along the facing direction; apply linear drag (~0.4/s) so the ship coasts and drifts, NOT instant stop. Cap max speed. Fire with Space (bullet inherits a bit of ship velocity, short lifetime, rate-limited).

Screen wrap (toroidal): every entity (ship, bullets, rocks) that crosses an edge appears on the opposite edge. Render must be seamless: when an object is within its radius of an edge, draw a duplicate on the wrapped side so it's never half-missing. Collision detection must also account for wrap.

Asteroids: large rocks drift with random velocity/spin; shooting one splits it into 2 smaller rocks whose combined momentum roughly conserves the parent's (split the velocity with a small perpendicular kick); smallest size is destroyed outright. Jagged procedurally generated polygon outlines, not circles.

Game feel: thrust flame flickers while accelerating, screen shake on rock destruction (cap 6px), ship explodes into line fragments on death with 1s respawn invulnerability (blink), and a chunky low 'thrum' while thrusting. Framerate-independent with a fixed-timestep accumulator. Comment the wrap-duplicate rendering trick.
1drag-based coasting instead of instant stop is the entire feel of asteroids. the drift is the game.vibecoder 3 months ago
add a comment

1 Answer

8

The wrap-duplicate render trick is the part everyone gets wrong, glad it's explicit here. On the split: conserving momentum exactly makes fragments fly apart too predictably. I keep the parent's momentum as the average but add a symmetric perpendicular impulse so the two children spread in a nice V, and scale the impulse down for smaller rocks so tiny debris doesn't rocket off-screen. Also give children a minimum speed so a near-stationary parent doesn't spawn two rocks that just sit there.

THE PROMPT
On split: childVel = parentVel +/- perpendicular(parentVel_dir) * kick, where kick scales with parent size and clamps to a min/max, so fragments spread in a V and never freeze in place.

Your Answer