HugoNikanors blogg‽

A blog about nothing, but mostly itself.

Hugo Hornquist 15 Jun 2019

Wolfenometry

As is well known Wolfenstein 3D is a 2D game, which uses simple raycasting to figure out the distance from the player to the wall's in front of her. As a small hobby project I set out to recreate this. Since my levels (like the original) are bound to a strict grid we don't actually have to do a "real" ray-caster. But can instead just calculate the distance to next tile-border the ray will pass through, and immediately jump there.

This should have been easy, but due to a number of bad missteps on my parts (mostly involving trying to decide my move based on if my angle was pointing left-right or up-down) it took way to long to figure out the proper equations.

In the end it was as simple as:

(define (find-next-wall x y a callback)
  (let ((dx-ampl (mod (* -1 (sgn (cos a)) (decimals x)) 1))
        (dy-ampl (mod (* -1 (sgn (sin a)) (decimals y)) 1)))
    ;; Try moving to vertical wall
    (let* ((dx (* 1.01 dx-ampl (sgn (cos a))))
           (dy (* dx (tan a))))
      (if (<= (abs dy) dy-ampl)
          (callback (+ x dx) (+ y dy))
          ;; if that failed, try horizontal wall instead
          (let* ((dy (* 1.01 dy-ampl (sgn (sin a))))
                 (dx (* dy (cot a))))
            (callback (+ x dx) (+ y dy)))))))

Along with a trivial decimal-truncation and array reference to check if a given square contains a wall or not. The end result looks rather ok, except some fish-eye effect and bad color blending.

Full Source

Screenshot

About Contact Legal Q&A