logo
By Lawrence

5 minutes

Rocks You Can Hit

Seventy-four boulders and every one of them is a picture. Fly into the biggest at full throttle and you come out the far side unmarked; empty a burst into it and the tracers keep going. Nothing this lesson touches the scene file. The change is one line in the cabinet and a grasp of where a rock's hitbox comes from. That second half is worth slowing down for, because the field already handed you a trap.

Two shapes for the same rock

A rock exists twice. The renderer takes an icosphere and pushes every vertex outward through a seeded noise function, so you see a lumpy, oblong boulder. Gameplay code can't test a bullet against a thousand pushed-out vertices sixty times a second, so it tests against a box.

The trap is that these are two accounts of one object, written by two different pieces of code, and nothing forces them to agree. Get it wrong and the failures are the baffling kind: shots that vanish into open space, deaths with nothing on screen.

So the box is derived from the mesh's own stretch. The rock spawner you wrote last lesson ends with these three lines:

src/components/AsteroidField/AsteroidField.ts
// Collision bounds from the geometry's own stretch, so the box matches the mesh.
const [hx, hy, hz] = halfExtentsFor(rock.radius, asteroidStretch(rock.meshSeed));
entity.add(new AsteroidComponent({ radius: rock.radius, hx, hy, hz }));

Continue reading

Unlock the Full Course

Every lesson, the runnable examples, and the finished build — yours to keep.

$9one-time

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search