I thought it would be pretty fun to do a Wolf3D-style raycasting
thing, and it ended up with no fps. Click and
drag the mouse on the viewport to move, or click on the map to edit
it.
On one hand this does sort of work. You can draw mazes on the left
and walk around them on the right. But it has Problems:
Even though it's only casting 256 rays and drawing a 256×256
canvas, it still uses my entire dual-core CPU to get 30–50 fps. I
don't understand what it's spending the CPU time on actually because
reducing the fps and number of rays and increasing the raymarching
step size doesn't help until you reach really extreme levels of
degradation.
Distances are badly quantized because it's just using an
iteration count of the raymarching as the distance. I cranked down
the step size to make this tolerable. This is a dumb way to raycast
on a pixel grid like this; Bresenham's line-drawing method would be
much better.
Because the raymarching is imprecise it can peek through corners.
Because it's generating the rays with polar coordinates you get a
fisheye effect.
There are no textures.
You can't even tell which side of a square pillar you're looking
at, usually.
You have to actually click on the viewport to rotate; it can't
capture your mouse. And it doesn't support WASD or go fullscreen.
HTML5 can do fullscreen and keys but I'm not sure if it can do mouse
pointer hiding/grabbing/warping so as to do unlimited-scope
mouselook.
The ceiling and floor are featureless, but adding a pointcloud
there would have been really easy.
Although it's 136 lines of code, most of that is really the UI
interaction. The actual raycasting code is only 35 lines, and even
that has some debugging and profiling cruft in it. It took me about
3½ hours to write the whole thing, though, again, a lot of that was UI
tweaking.
In retrospect it would have been better to implement 2-D vector
operations including addition, subtraction, scalar multiplication,
elementwise division, angle generation ({x: Math.cos(θ), y:
Math.sin(θ)}), canvas size, and clamping to within bounds.