raycaster.fnl: Next big update

- Added mouse look thanks to Love's `translate` function
- Included code for multi-level vertical rendering
- Updated movement to include/default to strafing
- Changed mapped keys to ESDF for ease of play.
  - TODO: implement remapping?
- Included floor/ceiling rendering code, but not yet using it
  - TODO: draw a textured floor
  - TODO: draw a textured skybox
This commit is contained in:
Bill Niblock 2024-10-16 17:24:25 -04:00
parent 532d5e5073
commit e763bae3b2

View file

@ -6,23 +6,26 @@
(var (screen-width screen-height) (love.window.getMode))
; ### Map Information ###
(var map (mapper.generate 15 15))
; (var map [[1 1 1 1 1 1 1 1 1 1 1 ]
; [2 0 0 0 0 0 0 0 0 0 4 ]
; [2 0 0 0 0 0 0 0 0 0 4 ]
; [2 0 0 0 0 0 0 0 0 0 4 ]
; [2 0 0 0 0 0 0 0 0 0 4 ]
; [2 0 0 0 0 0 0 0 0 0 4 ]
; [2 0 0 0 0 0 0 0 3 0 4 ]
; [2 0 0 0 0 0 0 3 3 0 4 ]
; [2 0 0 0 0 0 0 0 0 0 4 ]
; [1 1 1 1 1 1 1 1 1 1 1 ]])
; (var map (mapper.generate 15 15))
(var map [[1 1 2 1 1 1 1 2 1 1 1 ]
[1 0 0 0 0 0 0 0 0 0 1 ]
[1 0 0 0 0 0 0 0 0 0 2 ]
[2 0 0 0 0 0 0 0 0 0 2 ]
[1 0 0 0 0 0 0 0 0 0 1 ]
[1 0 0 0 0 0 0 0 0 0 1 ]
[1 0 0 0 0 0 0 0 3 0 1 ]
[1 0 0 0 0 0 0 3 3 0 1 ]
[1 0 0 0 0 0 0 0 0 0 1 ]
[1 1 1 1 1 1 1 1 1 1 1 ]])
; ### Texture Information ###
(var walls [])
(var wall-textures (love.filesystem.getDirectoryItems "textures/walls"))
(var (tex-height tex-width) (values 64 64))
(var skybox [])
(var skybox-textures (love.filesystem.getDirectoryItems "textures/skybox"))
(each [_ v (ipairs wall-textures)]
(local wall {})
(tset wall :t (love.graphics.newImage (.. "textures/walls/" v)))
@ -30,13 +33,82 @@
(tset wall :h (love.graphics.getHeight (. wall :t)))
(table.insert walls wall))
(each [_ v (ipairs skybox-textures)]
(local skyb {})
(tset skyb :t (love.graphics.newImage (.. "textures/skybox/" v)))
(tset skyb :w (love.graphics.getWidth (. skyb :t)))
(tset skyb :h (love.graphics.getHeight (. skyb :t)))
(table.insert skybox skyb))
; ### "Player" variables ###
(var (posx posy) (values 4.0 4.0)) ; Initial map position
(var (dirx diry) (values -1.0 0.0)) ; Initial direction vector
(var (planex planey) (values 0 0.66)) ; Camera plane
; ### Offset experimentation ###
(var (offst-x offst-y) (values 0 0))
{
:draw (fn love.draw []
; Mouse-Look
(love.graphics.translate offst-x offst-y)
; "Skybox"
; Draw a big thing before everything else
; (love.graphics.draw (. skybox 1 :t) -20 -20)
; CEILING/FLOOR CASTING
(var cf-f-tex-num (. walls 7))
(var cf-c-tex-num (. walls 6))
(var floor-texel (love.graphics.newQuad 0 0 1 1 (. cf-f-tex-num :w) (. cf-f-tex-num :h)))
(for [i (/ screen-height 2) screen-height]
; Set ray-dir for left-most (i = 0) and right-most (i = screen-width) rays
(var (cf-ray-dir-x0 cf-ray-dir-y0) (values (- dirx planex) (- diry planey)))
(var (cf-ray-dir-x1 cf-ray-dir-y1) (values (+ dirx planex) (+ diry planey)))
; Current y position compared to horizon
(var cf-p (math.floor (/ (- i screen-height) 2)))
; Vertical position of the camera
(var cf-pos-z (* 0.5 screen-height))
; Horizontal distance from camera to floor for current row
(var cf-row-distance (/ cf-pos-z cf-p))
; Calculate step vectors
(var cf-floor-step-x (/ (* cf-row-distance (- cf-ray-dir-x1 cf-ray-dir-x0)) screen-width))
(var cf-floor-step-y (/ (* cf-row-distance (- cf-ray-dir-y1 cf-ray-dir-y0)) screen-width))
; Coordinates of left-most column, updated stepping to the right
(var (cf-floor-x cf-floor-y) (values (+ posx (* cf-row-distance cf-ray-dir-x0))
(+ posy (* cf-row-distance cf-ray-dir-y0))))
; Draw floor and ceiling
(for [j 0 screen-width]
; Get cell
(var (cf-cell-x cf-cell-y) (values (math.floor cf-floor-x) (math.floor cf-floor-y)))
; Get texture coordinate from fractional part
; CPP Code: wtf is the & doing there?
; (var (cf-tx cf-ty) (values (math.floor (% (* tex-width (- cf-floor-x cf-cell-x)) tex-width))
; (math.floor (% (* tex-height (- cf-floor-y cf-cell-y)) tex-height))))
(var (cf-tx cf-ty) (values (math.floor (* tex-width (- cf-floor-x cf-cell-x)))
(math.floor (* tex-height (- cf-floor-y cf-cell-y)))))
;; Draw the texture
; (love.graphics.draw (. tex-num :t)
; (love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
; i draw-start 0 1 (/ line-height (. tex-num :h)))
; (love.graphics.draw (. cf-f-tex-num :t)
; floor-texel
; j i 0 1 1)
; Step
(set cf-floor-x (+ cf-floor-x cf-floor-step-x))
(set cf-floor-y (+ cf-floor-y cf-floor-step-y))
)
)
; WALL CASTING
(for [i 0 screen-width]
; Calculate ray position and direction
; Originals, giving a fish-eye lens effect:
@ -112,24 +184,6 @@
(var draw-end (+ (/ line-height 2) (/ screen-height 2)))
(if (>= draw-end screen-height) (set draw-end (- screen-height 1)))
; Draw wall slice
; (var color [1 1 1 1])
; (case (. map mapx mapy)
; 1 (set color [1 1 1 1])
; 2 (set color [1 0 0 1])
; 3 (set color [0 1 0 1])
; 4 (set color [0 0 1 1])
; )
; (when (= side 1)
; (tset color 1 (/ (. color 1) 2))
; (tset color 2 (/ (. color 2) 2))
; (tset color 3 (/ (. color 3) 2)))
; (love.graphics.setColor color)
; (love.graphics.line i draw-start i draw-end)
; (love.graphics.setColor 1 1 1)
; Draw textured wall
;; Choose texture
(var tex-num (. walls (. map mapx mapy)))
@ -143,34 +197,64 @@
(var tex-x (math.floor (* wallx (. tex-num :w))))
(if (and (= side 0) (> ray-dir-x 0)) (set tex-x (- (. tex-num :w) tex-x 1)))
(if (and (= side 1) (< ray-dir-y 0)) (set tex-x (- (. tex-num :w) tex-x 1)))
;; Draw the texture
;; Draw the texture, accounting for "fog"
(var fog-dist (- 1 (/ perp-wall-dist 7)))
(love.graphics.setColor 1 1 1 fog-dist)
(love.graphics.draw (. tex-num :t)
(love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
i draw-start 0 1 (/ line-height (. tex-num :h)))
(when (= (. map mapx mapy) 3)
(for [q 1 3]
(set fog-dist (- fog-dist 0.1))
(love.graphics.setColor 1 1 1 fog-dist)
(love.graphics.draw (. tex-num :t)
(love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
i (- draw-start (* line-height q)) 0 1 (/ line-height (. tex-num :h)))
)
)
)
(overlay.overlay)
(overlay.overlay offst-x offst-y)
)
:update (fn update [dt]
(var mvspeed (* dt 3.0))
(var rtspeed (* dt 1.0))
(when (love.keyboard.isDown "up")
(when (love.keyboard.isDown "e")
(when (= 0 (. map (math.floor (+ (* mvspeed dirx) posx)) (math.floor posy)))
(set posx (+ (* mvspeed dirx) posx)))
(when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed diry) posy))))
(set posy (+ (* mvspeed diry) posy)))
)
(when (love.keyboard.isDown "down")
(when (= 0 (. map (math.floor (+ (* mvspeed dirx) posx)) (math.floor posy)))
(when (love.keyboard.isDown "d")
(when (= 0 (. map (math.floor (- posx (* mvspeed dirx))) (math.floor posy)))
(set posx (- posx (* mvspeed dirx))))
(when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed diry) posy))))
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed diry)))))
(set posy (- posy (* mvspeed diry))))
)
(when (love.keyboard.isDown "right")
(when (love.keyboard.isDown "s")
(var strafe-x (- (* dirx (math.cos (- (/ math.pi 2)))) (* diry (math.sin (- (/ math.pi 2))))))
(var strafe-y (+ (* dirx (math.sin (- (/ math.pi 2)))) (* diry (math.cos (- (/ math.pi 2))))))
(when (= 0 (. map (math.floor (- posx (* mvspeed strafe-x))) (math.floor posy)))
(set posx (- posx (* mvspeed strafe-x))))
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed strafe-y)))))
(set posy (- posy (* mvspeed strafe-y))))
)
(when (love.keyboard.isDown "f")
(var strafe-x (- (* dirx (math.cos (+ (/ math.pi 2)))) (* diry (math.sin (+ (/ math.pi 2))))))
(var strafe-y (+ (* dirx (math.sin (+ (/ math.pi 2)))) (* diry (math.cos (+ (/ math.pi 2))))))
(when (= 0 (. map (math.floor (- posx (* mvspeed strafe-x))) (math.floor posy)))
(set posx (- posx (* mvspeed strafe-x))))
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed strafe-y)))))
(set posy (- posy (* mvspeed strafe-y))))
)
(when (love.keyboard.isDown "r")
(var old-dirx dirx)
(set dirx (- (* dirx (math.cos (- rtspeed))) (* diry (math.sin (- rtspeed)))))
(set diry (+ (* old-dirx (math.sin (- rtspeed))) (* diry (math.cos (- rtspeed)))))
@ -179,7 +263,7 @@
(set planey (+ (* old-planex (math.sin (- rtspeed))) (* planey (math.cos (- rtspeed)))))
)
(when (love.keyboard.isDown "left")
(when (love.keyboard.isDown "w")
(var old-dirx dirx)
(set dirx (- (* dirx (math.cos rtspeed)) (* diry (math.sin rtspeed))))
(set diry (+ (* old-dirx (math.sin rtspeed)) (* diry (math.cos rtspeed))))
@ -189,8 +273,26 @@
)
)
:mousemoved (fn mousemoved [x y dx dy]
(var rtspeed (* dx -0.001))
(var yawspeed (* dy -0.5))
(var old-dirx dirx)
(set dirx (- (* dirx (math.cos rtspeed)) (* diry (math.sin rtspeed))))
(set diry (+ (* old-dirx (math.sin rtspeed)) (* diry (math.cos rtspeed))))
(var old-planex planex)
(set planex (- (* planex (math.cos rtspeed)) (* planey (math.sin rtspeed))))
(set planey (+ (* old-planex (math.sin rtspeed)) (* planey (math.cos rtspeed))))
(set offst-y (+ offst-y yawspeed))
)
:keypressed (fn keypressed [k]
(when (= k "x") (love.event.quit))
(when (= k "u") (set offst-x (+ offst-x 5)))
(when (= k "o") (set offst-x (- offst-x 5)))
(when (= k "y") (set offst-y (- offst-y 5)))
(when (= k "h") (set offst-y (+ offst-y 5)))
)
}