diff --git a/raycaster.fnl b/raycaster.fnl index 5d05f16..1f24b28 100644 --- a/raycaster.fnl +++ b/raycaster.fnl @@ -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))) ) }