Begin work on floor casting
This commit is contained in:
parent
790b2a58bf
commit
f12058bb6f
2 changed files with 172 additions and 112 deletions
BIN
assets/textures/floors/1.png
Normal file
BIN
assets/textures/floors/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
284
mode-play.fnl
284
mode-play.fnl
|
@ -16,6 +16,10 @@
|
|||
(var wall-textures (love.filesystem.getDirectoryItems "assets/textures/walls"))
|
||||
(var (tex-height tex-width) (values 64 64))
|
||||
|
||||
(var floors [])
|
||||
(var floor-textures (love.filesystem.getDirectoryItems "assets/textures/floors"))
|
||||
(var (tex-height tex-width) (values 64 64))
|
||||
|
||||
(var skybox [])
|
||||
(var skybox-textures (love.filesystem.getDirectoryItems "assets/textures/skybox"))
|
||||
|
||||
|
@ -26,6 +30,13 @@
|
|||
(tset wall :h (love.graphics.getHeight (. wall :t)))
|
||||
(table.insert walls wall))
|
||||
|
||||
(each [_ v (ipairs floor-textures)]
|
||||
(local floor {})
|
||||
(tset floor :t (love.graphics.newImage (.. "assets/textures/floors/" v)))
|
||||
(tset floor :w (love.graphics.getWidth (. floor :t)))
|
||||
(tset floor :h (love.graphics.getHeight (. floor :t)))
|
||||
(table.insert floors floor))
|
||||
|
||||
(each [_ v (ipairs skybox-textures)]
|
||||
(local skyb {})
|
||||
(tset skyb :t (love.graphics.newImage (.. "assets/textures/skybox/" v)))
|
||||
|
@ -41,6 +52,164 @@
|
|||
; ### Offset experimentation ###
|
||||
(var (offst-x offst-y) (values 0 0))
|
||||
|
||||
(fn floor-casting [wall-dists]
|
||||
(for [y (math.floor (/ screen-height 2)) (- screen-height 1)]
|
||||
|
||||
; Distance to floor row
|
||||
(var floor-dist (/ screen-height (- (* 2 y) screen-height)))
|
||||
|
||||
; Calculate step distances for row
|
||||
(var (step-x step-y) (values (/ (* floor-dist planex) screen-width)
|
||||
(/ (* floor-dist planey) screen-width)))
|
||||
|
||||
; Starting position for leftmost pixel of this row
|
||||
(var (floor-x floor-y) (values
|
||||
(+ posx (* dirx floor-dist) (* step-x (/ screen-width -2)))
|
||||
(+ posy (* diry floor-dist) (* step-y (/ screen-width -2)))))
|
||||
|
||||
; Draw each pixel across this row
|
||||
(for [x 0 screen-width]
|
||||
; Only draw if actually visible
|
||||
(when (< floor-dist (. wall-dists x))
|
||||
|
||||
; Get pixel of texture to draw
|
||||
; (set tex-x (- (. tex-num :w) tex-x 1))
|
||||
(var (tex-x tex-y) (values
|
||||
(math.floor (- floor-x (* (. floors 1 :w) (math.floor floor-x))))
|
||||
(math.floor (- floor-y (* (. floors 1 :h) (math.floor floor-y))))))
|
||||
|
||||
; Set lighting/fog
|
||||
; (var fog-dist (- 1 (/ (. wall-dists x) 10)))
|
||||
; (var light-dist (- 0.8 (/ (. wall-dists x) 5)))
|
||||
; (love.graphics.setColor light-dist light-dist light-dist fog-dist)
|
||||
|
||||
; Draw texture-pixel to world coordinate
|
||||
(var tex-num (. floors 1))
|
||||
(love.graphics.draw (. tex-num :t)
|
||||
(love.graphics.newQuad tex-x tex-y 1 1 (. tex-num :w) (. tex-num :h))
|
||||
x y))
|
||||
|
||||
; Step forward a pixel
|
||||
(set (floor-x floor-y) (values
|
||||
(+ floor-x step-x) (+ floor-y step-y)))))
|
||||
)
|
||||
|
||||
(fn sky-casting [])
|
||||
|
||||
(fn wall-casting []
|
||||
(var wall-dist [])
|
||||
; WALL CASTING
|
||||
(for [i 0 screen-width]
|
||||
; Calculate ray position and direction
|
||||
; Originals, giving a fish-eye lens effect:
|
||||
; (var camerax (/ (* 2 i) (- screen-width 1)))
|
||||
; (var (ray-dir-x ray-dir-y) (values (+ dirx (* planex camerax)) (+ diry (* planey camerax))))
|
||||
(var camerax (- (/ (* 2 i) (- screen-width 1)) 1.0))
|
||||
(var (ray-dir-x ray-dir-y) (values (+ dirx (* planex camerax)) (+ diry (* planey camerax))))
|
||||
|
||||
; Which map square we're in
|
||||
(var (mapx mapy) (values (math.floor posx) (math.floor posy)))
|
||||
|
||||
; Length of ray from current position to next x or y side
|
||||
(var (side-dist-x side-dist-y) (values 0 0))
|
||||
|
||||
; Length of ray from one x or y side to the next x or y side
|
||||
; (var (delta-dist-x delta-dist-y) (values
|
||||
; (math.sqrt (+ 1 (/ (* ray-dir-y ray-dir-y) (* ray-dir-x ray-dir-x))))
|
||||
; (math.sqrt (+ 1 (/ (* ray-dir-x ray-dir-x) (* ray-dir-y ray-dir-y))))))
|
||||
; (var (delta-dist-x delta-dist-y) (values
|
||||
; (math.sqrt (+ 1 (* (/ ray-dir-y ray-dir-x) (/ ray-dir-y ray-dir-x))))
|
||||
; (math.sqrt (+ 1 (* (/ ray-dir-x ray-dir-y) (/ ray-dir-x ray-dir-y))))))
|
||||
(var (delta-dist-x delta-dist-y) (values (math.abs (/ 1 ray-dir-x)) (math.abs (/ 1 ray-dir-y))))
|
||||
|
||||
(var perp-wall-dist 0)
|
||||
|
||||
; Direction to step in, x or y
|
||||
(var (stepx stepy) (values 0 0))
|
||||
|
||||
; Side the ray hits, x (0) or y (1)
|
||||
(var side 0)
|
||||
|
||||
; Calculate step and initial side-dist-*
|
||||
(if (< ray-dir-x 0)
|
||||
(do
|
||||
(set stepx -1)
|
||||
(set side-dist-x (* (- posx mapx) delta-dist-x)))
|
||||
(do
|
||||
(set stepx 1)
|
||||
(set side-dist-x (* (- (+ mapx 1.0) posx) delta-dist-x))))
|
||||
(if (< ray-dir-y 0)
|
||||
(do
|
||||
(set stepy -1)
|
||||
(set side-dist-y (* (- posy mapy) delta-dist-y)))
|
||||
(do
|
||||
(set stepy 1)
|
||||
(set side-dist-y (* (- (+ mapy 1.0) posy) delta-dist-y))))
|
||||
|
||||
; Perform DDA (Digital Differential Analysis)
|
||||
(var hit false)
|
||||
(while (not hit)
|
||||
(if (< side-dist-x side-dist-y)
|
||||
(do
|
||||
(set side-dist-x (+ side-dist-x delta-dist-x))
|
||||
(set mapx (+ mapx stepx))
|
||||
(set side 0))
|
||||
(do
|
||||
(set side-dist-y (+ side-dist-y delta-dist-y))
|
||||
(set mapy (+ mapy stepy))
|
||||
(set side 1)))
|
||||
(if (> (. map mapx mapy) 0) (set hit true)))
|
||||
|
||||
; Calculate distance of perpendicular ray, to avoid fisheye effect
|
||||
(if (= side 0)
|
||||
(set perp-wall-dist (- side-dist-x delta-dist-x))
|
||||
(set perp-wall-dist (- side-dist-y delta-dist-y)))
|
||||
|
||||
; Calculate height of line to draw on screen
|
||||
(var line-height (/ screen-height perp-wall-dist))
|
||||
|
||||
; Calculate lowest and highest pixel to fill in current stripe
|
||||
(var draw-start (+ (/ (- line-height) 2) (/ screen-height 2)))
|
||||
(if (< draw-start 0) (set draw-start 0))
|
||||
(var draw-end (+ (/ line-height 2) (/ screen-height 2)))
|
||||
(if (>= draw-end screen-height) (set draw-end (- screen-height 1)))
|
||||
|
||||
; Draw textured wall
|
||||
;; Choose texture
|
||||
; (var tex-num (. walls (. map mapx mapy)))
|
||||
(var tex-num (. walls (math.floor (/ (. map mapx mapy) 10))))
|
||||
;; Calculate exactly where the wall was hit
|
||||
(var wallx 0)
|
||||
(if (= side 0)
|
||||
(set wallx (+ posy (* perp-wall-dist ray-dir-y)))
|
||||
(set wallx (+ posx (* perp-wall-dist ray-dir-x))))
|
||||
(set wallx (- wallx (math.floor wallx)))
|
||||
;; Find the x-coordinate on the texture
|
||||
(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, accounting for "fog"
|
||||
(var fog-dist (- 1 (/ perp-wall-dist 10)))
|
||||
(var light-dist (- 0.8 (/ perp-wall-dist 5)))
|
||||
; (love.graphics.setColor light-dist light-dist light-dist 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 0 (% (. map mapx mapy) 10)]
|
||||
(set fog-dist (- fog-dist 0.1))
|
||||
(set light-dist (- light-dist 0.1))
|
||||
(love.graphics.setColor light-dist light-dist light-dist 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)))
|
||||
)
|
||||
(tset wall-dist i perp-wall-dist)
|
||||
; )
|
||||
)
|
||||
wall-dist
|
||||
)
|
||||
|
||||
{
|
||||
:draw (fn love.draw []
|
||||
(state.setDirX dirx)
|
||||
|
@ -48,118 +217,9 @@
|
|||
; 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)
|
||||
|
||||
; WALL CASTING
|
||||
(for [i 0 screen-width]
|
||||
; Calculate ray position and direction
|
||||
; Originals, giving a fish-eye lens effect:
|
||||
; (var camerax (/ (* 2 i) (- screen-width 1)))
|
||||
; (var (ray-dir-x ray-dir-y) (values (+ dirx (* planex camerax)) (+ diry (* planey camerax))))
|
||||
(var camerax (- (/ (* 2 i) (- screen-width 1)) 1.0))
|
||||
(var (ray-dir-x ray-dir-y) (values (+ dirx (* planex camerax)) (+ diry (* planey camerax))))
|
||||
|
||||
; Which map square we're in
|
||||
(var (mapx mapy) (values (math.floor posx) (math.floor posy)))
|
||||
|
||||
; Length of ray from current position to next x or y side
|
||||
(var (side-dist-x side-dist-y) (values 0 0))
|
||||
|
||||
; Length of ray from one x or y side to the next x or y side
|
||||
; (var (delta-dist-x delta-dist-y) (values
|
||||
; (math.sqrt (+ 1 (/ (* ray-dir-y ray-dir-y) (* ray-dir-x ray-dir-x))))
|
||||
; (math.sqrt (+ 1 (/ (* ray-dir-x ray-dir-x) (* ray-dir-y ray-dir-y))))))
|
||||
; (var (delta-dist-x delta-dist-y) (values
|
||||
; (math.sqrt (+ 1 (* (/ ray-dir-y ray-dir-x) (/ ray-dir-y ray-dir-x))))
|
||||
; (math.sqrt (+ 1 (* (/ ray-dir-x ray-dir-y) (/ ray-dir-x ray-dir-y))))))
|
||||
(var (delta-dist-x delta-dist-y) (values (math.abs (/ 1 ray-dir-x)) (math.abs (/ 1 ray-dir-y))))
|
||||
|
||||
(var perp-wall-dist 0)
|
||||
|
||||
; Direction to step in, x or y
|
||||
(var (stepx stepy) (values 0 0))
|
||||
|
||||
; Side the ray hits, x (0) or y (1)
|
||||
(var side 0)
|
||||
|
||||
; Calculate step and initial side-dist-*
|
||||
(if (< ray-dir-x 0)
|
||||
(do
|
||||
(set stepx -1)
|
||||
(set side-dist-x (* (- posx mapx) delta-dist-x)))
|
||||
(do
|
||||
(set stepx 1)
|
||||
(set side-dist-x (* (- (+ mapx 1.0) posx) delta-dist-x))))
|
||||
(if (< ray-dir-y 0)
|
||||
(do
|
||||
(set stepy -1)
|
||||
(set side-dist-y (* (- posy mapy) delta-dist-y)))
|
||||
(do
|
||||
(set stepy 1)
|
||||
(set side-dist-y (* (- (+ mapy 1.0) posy) delta-dist-y))))
|
||||
|
||||
; Perform DDA (Digital Differential Analysis)
|
||||
(var hit false)
|
||||
(while (not hit)
|
||||
(if (< side-dist-x side-dist-y)
|
||||
(do
|
||||
(set side-dist-x (+ side-dist-x delta-dist-x))
|
||||
(set mapx (+ mapx stepx))
|
||||
(set side 0))
|
||||
(do
|
||||
(set side-dist-y (+ side-dist-y delta-dist-y))
|
||||
(set mapy (+ mapy stepy))
|
||||
(set side 1)))
|
||||
(if (> (. map mapx mapy) 0) (set hit true)))
|
||||
|
||||
; Calculate distance of perpendicular ray, to avoid fisheye effect
|
||||
(if (= side 0)
|
||||
(set perp-wall-dist (- side-dist-x delta-dist-x))
|
||||
(set perp-wall-dist (- side-dist-y delta-dist-y)))
|
||||
|
||||
; Calculate height of line to draw on screen
|
||||
(var line-height (/ screen-height perp-wall-dist))
|
||||
|
||||
; Calculate lowest and highest pixel to fill in current stripe
|
||||
(var draw-start (+ (/ (- line-height) 2) (/ screen-height 2)))
|
||||
(if (< draw-start 0) (set draw-start 0))
|
||||
(var draw-end (+ (/ line-height 2) (/ screen-height 2)))
|
||||
(if (>= draw-end screen-height) (set draw-end (- screen-height 1)))
|
||||
|
||||
; Draw textured wall
|
||||
;; Choose texture
|
||||
; (var tex-num (. walls (. map mapx mapy)))
|
||||
(var tex-num (. walls (math.floor (/ (. map mapx mapy) 10))))
|
||||
;; Calculate exactly where the wall was hit
|
||||
(var wallx 0)
|
||||
(if (= side 0)
|
||||
(set wallx (+ posy (* perp-wall-dist ray-dir-y)))
|
||||
(set wallx (+ posx (* perp-wall-dist ray-dir-x))))
|
||||
(set wallx (- wallx (math.floor wallx)))
|
||||
;; Find the x-coordinate on the texture
|
||||
(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, accounting for "fog"
|
||||
(var fog-dist (- 1 (/ perp-wall-dist 10)))
|
||||
(var light-dist (- 0.8 (/ perp-wall-dist 5)))
|
||||
(love.graphics.setColor light-dist light-dist light-dist 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 0 (% (. map mapx mapy) 10)]
|
||||
(set fog-dist (- fog-dist 0.1))
|
||||
(set light-dist (- light-dist 0.1))
|
||||
(love.graphics.setColor light-dist light-dist light-dist 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)))
|
||||
)
|
||||
; )
|
||||
)
|
||||
; (sky-casting)
|
||||
(var wall-dists (wall-casting))
|
||||
(floor-casting wall-dists)
|
||||
(overlay.overlay offst-x offst-y)
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue