▦ MATRIX THINKING

GAME LAB 04 · RAYCASTING / MODULE 22

One matrix.
Two ways to see a world.

Walk through the book’s maze. On the map, rays stop at walls. In the camera view, those same hits become vertical strips.

01 / THE MATRIX & RAYS

0 · wall1 · passage● observer— selected ray

Click a passage cell to place the observer there. The maze is the book’s original data, including passages at its boundary.

02 / THE SAME HITS, PROJECTED

Click a strip to inspect its ray. Yellow marks the selected strip; its height uses forward depth, not oblique ray length.

Ready. Press Enter to explore.

W/S · forward / backward · A/D · strafe
←/→ · turn · Enter · explore / resume · P · pause
Hold the on-screen buttons on a touchscreen.

03 / FOLLOW ONE RAY

depth = distance × cos(relative_angle)
height = CELL_SIZE × projection_distance / depth

The floor uses camera coordinates:
side = dy × cos(a) − dx × sin(a)
depth = dy × sin(a) + dx × cos(a)

04 / THE FIRST WALL SAMPLE

The final passage samples and the first wall sample of the selected ray. Values are [row, column], as in the book.

SampleDistance[row, col]maze

Inspect the arrays behind the image

Each row below describes one ray. In the book these values are stored in coordinated one-dimensional arrays. Selecting a row highlights the same ray in both pictures.

RayHit [row, col]DistanceDepthHeight

FROM THE BOOK

Find a wall.
Build a view.

This JavaScript adaptation uses Module 22’s original 16 × 32 maze and starting cell (8, 16). It follows the same sample-based ray search, directions through strip centres, forward-depth correction, distance shading, and projected floor grid. Movement checks short steps on each axis before entering a passage.

Read the original Python project ↗

Try a prediction

Pause and change the field of view. The maze and observer position stay unchanged; the ray directions, wall heights and image change. Reduce the ray count to see the image’s vertical strips.

Rays that leave the maze without finding a wall have no wall strip. The browser shows their status explicitly. All distances use the book’s world units: each cell is 30 units wide.

JavaScript runs in the browser; Python and NumPy are not executed. The learning interface adds ray selection and passage-cell positioning. There are no added enemies or victory rules.