Asteroids Arcade: Physics and Collision Detection in JS
In 1979, Atari’s Asteroids took the world by storm with its unique vector graphics and wrap-around screen physics. It stripped game design down to its rawest form: inertia, rotation, and precision shooting. Today, rebuilding this classic using JavaScript and the HTML5 Canvas API is a masterclass in handling Euclidean geometry and vector-based physics. In this guide, we’ll explore how to handle deep-space momentum and the math required to keep track of a chaotic field of space rocks.
THRUSTERS ENGAGED
1. Vector Physics: Frictionless Momentum
Unlike a platformer where you stop when you release a key, Asteroids uses Newtonian physics. Once your ship starts moving, it stays moving until an opposite force is applied.
- Rotation: We track the ship’s
anglein radians. When the player presses ‘Left’ or ‘Right’, we simply increment or decrement this value. - Thrust: When ‘Up’ is pressed, we calculate the $x$ and $y$ components of the force using trigonometry:
$dx += \cos(angle) \times thrust$
$dy += \sin(angle) \times thrust$ - Screen Wrapping: To create the “infinite space” feel, if an object’s $x$ coordinate goes below $0$, we set it to
canvas.width, and vice versa.
2. Circular Collision Detection: The Distance Formula
In Asteroids, using rectangular hitboxes (AABB) feels clunky because the objects rotate. Instead, we use Circular Collision Detection. Since asteroids and the ship are roughly circular, we check the distance between their centers.
The Math Behind the Hit
We use the Pythagorean theorem ($a^2 + b^2 = c^2$) to find the distance between two points $(x1, y1)$ and $(x2, y2)$. If the distance is less than the sum of their radii, a collision has occurred.
let dist = Math.sqrt((x1-x2)**2 + (y1-y2)**2);
if (dist < (radius1 + radius2)) { /* BOOM! */ }
3. Managing the Asteroid "Splitting" Logic
A key gameplay element is that large asteroids break into smaller ones. In our JavaScript logic, we handle this using a Recursive Array Structure:
- When a bullet hits a "Large" asteroid, it is removed from the active array.
- Two new "Medium" asteroid objects are pushed into the array at the same coordinates, but with randomized velocities.
- This process repeats until the "Small" asteroids are destroyed, at which point they are simply removed.
4. Drawing Vectors with Canvas Paths
The original Asteroids used vector hardware, which drew lines instead of pixels. We mimic this in the Canvas API by using stroke() instead of fill(). By keeping our shapes as a series of relative coordinates, we can rotate and scale them easily using ctx.rotate() and ctx.translate() without losing sharpness.
5. Performance Optimization: Object Pooling
In a high-intensity game of Asteroids, you might have dozens of rocks and bullets on screen. To prevent "Garbage Collection" stutters, expert developers use Object Pooling. Instead of creating and deleting objects constantly, we keep a fixed-size array and "activate" or "deactivate" objects as needed, keeping the memory usage flat and the frame rate at a buttery-smooth 60FPS.
Conclusion: The Beauty of Minimalist Design
Building an Asteroids clone is a reminder that compelling gameplay often comes from consistent, predictable physics. By mastering vectors, rotation, and circular collisions in JavaScript, you gain the tools to build almost any 2D experience. The black void of space is your canvas—now go out there and clear that asteroid field!
Tags: #JavaScript #GamePhysics #Asteroids #RetroDev #HTML5Canvas