Use state more, start on menus

This commit is contained in:
Bill Niblock 2024-11-02 17:09:38 -04:00
parent e63a0039b6
commit fd96d53a34
7 changed files with 315 additions and 217 deletions

View file

@ -1,9 +1,11 @@
(local state (require :state))
; Cell Stuff ; Cell Stuff
; The "cell-num" is the number of cells across; it is then squared to make the ; The "cell-num" is the number of cells across; it is then squared to make the
; grid. Each cell has a "cell-size" of walls ("wall-width") and hallways ; grid. Each cell has a "cell-size" of walls ("wall-width") and hallways
; ("hall-width"). ; ("hall-width").
(var cell-num 20) (var map-meta (state.getMap))
(var (hall-width wall-width) (values 2 4)) (var cell-num (. map-meta :n))
(var (hall-width wall-width) (values (. map-meta :h) (. map-meta :w)))
(var cell-size (+ hall-width wall-width)) (var cell-size (+ hall-width wall-width))
; (fn wall-seg [] (+ 10 (math.random 1 3))) ; (fn wall-seg [] (+ 10 (math.random 1 3)))
(fn wall-seg [] (math.random 11 13)) (fn wall-seg [] (math.random 11 13))

View file

@ -1,114 +1,65 @@
(local overlay (require :overlay))
(local state (require :state))
(local mapper (require :mapper))
(love.graphics.setNewFont 10)
(local pi math.pi)
(var map (mapper.generate 10 10))
; This sets the wall texture data
(var walls [])
(var wall-textures (love.filesystem.getDirectoryItems "textures/walls"))
(each [_ v (ipairs wall-textures)]
(local wall {})
(tset wall :t (love.graphics.newImage (.. "textures/walls/" v)))
(tset wall :w (love.graphics.getWidth (. wall :t)))
(tset wall :h (love.graphics.getHeight (. wall :t)))
(table.insert walls wall))
; Map size
(var map-height (length map))
(var map-width (length (. map 1)))
; Player position and direction
(var player (state.getPlayer))
; Screen size
(var (screen-width screen-height) (love.window.getMode)) (var (screen-width screen-height) (love.window.getMode))
; (var screen-width 1280) (var (mx my) (values (/ screen-width 2) (/ screen-height 2)))
; (var screen-height 720) (love.mouse.setGrabbed false)
(var texel-width 64) (love.mouse.setRelativeMode false)
(var texel-height 64)
; Ray-casting function (love.graphics.setNewFont 30)
(fn cast-ray [ray-angle]
(local dx (math.cos ray-angle))
(local dy (math.sin ray-angle))
(var rays [])
(var (distance tex done hit-pos) (values 0 1 false {}))
(while (not done)
(var ray-x (+ player.x (* dx distance)))
(var ray-y (+ player.y (* dy distance)))
(set rays [ray-x ray-y])
; Check if ray hits a wall (>= 1) on the map
(if (or (>= (math.floor ray-x) map-width)
(>= (math.floor ray-y) map-height)
(<= ray-x 0)
(<= ray-y 0)
(>= (. map (math.floor ray-y) (math.floor ray-x)) 1))
(do
(set done true)
(set tex (. map (math.floor ray-y) (math.floor ray-x)))
(set hit-pos {:x (- ray-x (math.floor ray-x)) :y (- ray-y (math.floor ray-y))}))
; Increment distance
(set distance (+ distance 0.01))))
(values distance hit-pos tex rays))
; Function to handle player movement (var footer-font (love.graphics.newFont 19))
(fn move-player [move-speed] (local (major minor revision) (love.getVersion))
(let [new-x (+ player.x (* (math.cos player.d) move-speed))
new-y (+ player.y (* (math.sin player.d) move-speed))]
; Check for collisions with walls
(when (= (. map (math.floor new-y) (math.floor new-x)) 0)
(state.modO -1) (state.setX new-x) (state.setY new-y))))
; Draw function for rendering (fn helmet-hud []
{:draw (fn love.draw [] (love.graphics.setColor 0 1 0 0.25)
(love.graphics.clear) (love.graphics.line 0 0
(+ (/ screen-width 6) 0) 35
; For each vertical slice of the screen (+ (/ screen-width 3) 0) 30
(var (last-x last-y) (values 0 0)) (- screen-width (/ screen-width 3)) 30
(for [i 0 (- screen-width 1)] (- screen-width (/ screen-width 6)) 35
; Calculate angle of ray relative to player direction screen-width 0))
(local ray-angle (+ player.d (- (* (/ i screen-width) player.f) (/ player.f 2))))
; Cast the ray to find distance to the nearest wall
(local (distance hit-pos tex rays) (values (cast-ray ray-angle)))
; Calculate height of the wall slice
(local wall-height (math.floor (/ screen-height distance)))
(local start-y (/ (- screen-height wall-height) 2))
(local end-y (/ (+ screen-height wall-height) 2))
; Draw a textured wall (var menu-font (love.graphics.newFont 20))
(local wall-texture (. walls tex)) (fn menu-button [x y t]
(var texture-x 0) (love.graphics.polygon "line" x y
(if (> (/ (- (. rays 1) last-x) (- (. rays 2) last-y)) (/ (- (. rays 2) last-y) (- (. rays 1) last-x))) (+ x 100) y
(set texture-x (math.floor (* (. hit-pos :y) (. wall-texture :w)))) (+ x 120) (+ y 20)
(set texture-x (math.floor (* (. hit-pos :x) (. wall-texture :w))))) (+ x 100) (+ y 40)
(love.graphics.draw (. wall-texture :t) x (+ y 40)
(love.graphics.newQuad texture-x 0 1 (. wall-texture :h) (. wall-texture :w) (. wall-texture :h)) (- x 20) (+ y 20))
i start-y 0 1 (/ wall-height (. wall-texture :h))) (love.graphics.printf t x (+ y 11) (+ x 100))
(when (= 0 (% i 200)) )
(love.graphics.print (.. "r: " ray-angle) i 10)
(love.graphics.print (.. "h-x: " (. rays 1)) i 20)
(love.graphics.print (.. "h-y: " (. rays 2)) i 30)
)
(set (last-x last-y) (values (. rays 1) (. rays 2)))
)
(overlay.overlay) {
(set player (state.getPlayer)) :draw
) (fn draw []
(helmet-hud)
(menu-button (- (/ screen-width 2) 50) 100 (.. mx ", " my))
; (love.graphics.setNewFont 50)
; (love.graphics.setColor 0.75 0.75 0.75)
; (love.graphics.printf "L4-N-DER Training Simulator" 0
; (- (/ screen-height 2) 100) screen-width :center)
; (love.graphics.setNewFont 20)
; (love.graphics.setColor 0.55 0.55 0.05)
; (love.graphics.printf "OFFICIAL LANDER EYES ONLY" 0
; (- (/ screen-height 2) 20) screen-width :center)
; (love.graphics.setColor 0.75 0.75 0.75)
; (love.graphics.printf "Press D To Deploy" 0
; (+ (/ screen-height 2) 20) screen-width :center)
; (love.graphics.printf "Press Q To Quit" 0
; (+ (/ screen-height 2) 40) screen-width :center)
(love.graphics.printf
(: "Made with Love [%s.%s.%s] and Fennel"
:format major minor revision) footer-font 20 (- screen-height 30) screen-width :left)
(love.graphics.printf "A game by Bill Niblock" footer-font -20 (- screen-height 30) screen-width :right)
)
:keypressed (fn keypressed [key set-mode] :keypressed
(when (= key "j") (state.setD (- player.d (/ pi 2)))) (fn keypressed [key set-mode]
(when (= key "l") (state.setD (+ player.d (/ pi 2)))) (when (= key "d")
(when (= key "i") (move-player 1)) (set-mode :mode-play))
(when (= key "k") (move-player -1)) (when (= key "q")
(when (= key "x") (love.event.quit)))} (love.event.quit)))
:mousemoved
(fn mousemoved [x y]
(set (mx my) (values x y)))
}

View file

@ -2,26 +2,14 @@
(local mapper (require :mapper)) (local mapper (require :mapper))
(local overlay (require :overlay)) (local overlay (require :overlay))
(local pi math.pi) (local pi math.pi)
(var count-down true)
; ### Screen Size ### ; ### Screen Size ###
(var (screen-width screen-height) (love.window.getMode)) (var (screen-width screen-height) (love.window.getMode))
(love.mouse.setGrabbed true)
(love.mouse.setRelativeMode true)
; ### Map Information ### ; ### Map Information ###
(var (map spawn) (mapper.generate)) (var (map spawn) (mapper.generate))
; (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 1 1 1 1 1 0 0 0 0 1 ]
; [1 0 0 0 0 0 0 1 1 1 1 ]
; [1 0 1 1 1 1 1 1 1 1 1 ]
; [1 0 1 1 1 1 0 0 0 0 1 ]
; [1 0 1 1 1 1 1 1 1 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 ### ; ### Texture Information ###
(var walls []) (var walls [])
@ -55,6 +43,8 @@
{ {
:draw (fn love.draw [] :draw (fn love.draw []
(state.setDirX dirx)
(state.setDirY diry)
; Mouse-Look ; Mouse-Look
(love.graphics.translate offst-x offst-y) (love.graphics.translate offst-x offst-y)
@ -63,56 +53,57 @@
; (love.graphics.draw (. skybox 1 :t) -20 -20) ; (love.graphics.draw (. skybox 1 :t) -20 -20)
; CEILING/FLOOR CASTING ; CEILING/FLOOR CASTING
; (var cf-f-tex-num (. walls 7)) (var cf-f-tex-num (. walls 2))
; (var cf-c-tex-num (. walls 6)) (var cf-c-tex-num (. walls 2))
; (var floor-texel (love.graphics.newQuad 0 0 1 1 (. cf-f-tex-num :w) (. cf-f-tex-num :h))) ; (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] (for [i (/ screen-height 2) screen-height]
; ; Set ray-dir for left-most (i = 0) and right-most (i = screen-width) rays ; 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-x0 cf-ray-dir-y0) (values (- dirx planex) (- diry planey)))
; (var (cf-ray-dir-x1 cf-ray-dir-y1) (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 ; Current y position compared to horizon
; (var cf-p (math.floor (/ (- i screen-height) 2))) (var cf-p (math.floor (/ (- i screen-height) 2)))
; ; Vertical position of the camera ; Vertical position of the camera
; (var cf-pos-z (* 0.5 screen-height)) (var cf-pos-z (* 0.5 screen-height))
; ; Horizontal distance from camera to floor for current row ; Horizontal distance from camera to floor for current row
; (var cf-row-distance (/ cf-pos-z cf-p)) (var cf-row-distance (/ cf-pos-z cf-p))
; ; Calculate step vectors ; 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-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)) (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 ; 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)) (var (cf-floor-x cf-floor-y) (values (+ posx (* cf-row-distance cf-ray-dir-x0))
; (+ posy (* cf-row-distance cf-ray-dir-y0)))) (+ posy (* cf-row-distance cf-ray-dir-y0))))
; ; Draw floor and ceiling ; Draw floor and ceiling
; (for [j 0 screen-width] (for [j 0 screen-width]
; ; Get cell ; Get cell
; (var (cf-cell-x cf-cell-y) (values (math.floor cf-floor-x) (math.floor cf-floor-y))) (var (cf-cell-x cf-cell-y) (values (math.floor cf-floor-x) (math.floor cf-floor-y)))
; ; Get texture coordinate from fractional part ; Get texture coordinate from fractional part
; ; CPP Code: wtf is the & doing there? ; 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)) ; (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)))) ; (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))) (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))))) (math.floor (* tex-height (- cf-floor-y cf-cell-y)))))
; ;; Draw the texture ;; Draw the texture
; ; (love.graphics.draw (. tex-num :t) ; (var tex-num cf-f-tex-num)
; ; (love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h)) ; (love.graphics.draw (. tex-num :t)
; ; i draw-start 0 1 (/ line-height (. tex-num :h))) ; (love.graphics.newQuad cf-tx 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
; ; (love.graphics.draw (. cf-f-tex-num :t) ; i cf-ty 0 1 (/ line-height (. tex-num :h)))
; ; floor-texel ; (love.graphics.draw (. cf-f-tex-num :t)
; ; j i 0 1 1) ; floor-texel
; j i 0 1 1)
; ; Step ; Step
; (set cf-floor-x (+ cf-floor-x cf-floor-step-x)) (set cf-floor-x (+ cf-floor-x cf-floor-step-x))
; (set cf-floor-y (+ cf-floor-y cf-floor-step-y)) (set cf-floor-y (+ cf-floor-y cf-floor-step-y))
; ) )
; ) )
; WALL CASTING ; WALL CASTING
(for [i 0 screen-width] (for [i 0 screen-width]
; Calculate ray position and direction ; Calculate ray position and direction
@ -204,15 +195,17 @@
(if (and (= side 0) (> ray-dir-x 0)) (set tex-x (- (. tex-num :w) tex-x 1))) (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))) (if (and (= side 1) (< ray-dir-y 0)) (set tex-x (- (. tex-num :w) tex-x 1)))
;; Draw the texture, accounting for "fog" ;; Draw the texture, accounting for "fog"
(var fog-dist (- 1 (/ perp-wall-dist 7))) (var fog-dist (- 1 (/ perp-wall-dist 10)))
(love.graphics.setColor 1 1 1 fog-dist) (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.draw (. tex-num :t)
; (love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h)) ; (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))) ; i draw-start 0 1 (/ line-height (. tex-num :h)))
; (when (= (. map mapx mapy) 3) ; (when (= (. map mapx mapy) 3)
(for [q 0 (% (. map mapx mapy) 10)] (for [q 0 (% (. map mapx mapy) 10)]
(set fog-dist (- fog-dist 0.1)) (set fog-dist (- fog-dist 0.1))
(love.graphics.setColor 1 1 1 fog-dist) (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.draw (. tex-num :t)
(love.graphics.newQuad tex-x 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h)) (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))) i (- draw-start (* line-height q)) 0 1 (/ line-height (. tex-num :h)))
@ -228,52 +221,40 @@
(when (love.keyboard.isDown "e") (when (love.keyboard.isDown "e")
(when (= 0 (. map (math.floor (+ (* mvspeed dirx) posx)) (math.floor posy))) (when (= 0 (. map (math.floor (+ (* mvspeed dirx) posx)) (math.floor posy)))
(set posx (+ (* mvspeed dirx) posx))) (set posx (+ (* mvspeed dirx) posx))
(state.modDis mvspeed))
(when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed diry) posy)))) (when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed diry) posy))))
(set posy (+ (* mvspeed diry) posy))) (set posy (+ (* mvspeed diry) posy))
(state.modDis mvspeed))
) )
(when (love.keyboard.isDown "d") (when (love.keyboard.isDown "d")
(when (= 0 (. map (math.floor (- posx (* mvspeed dirx))) (math.floor posy))) (when (= 0 (. map (math.floor (- posx (* mvspeed dirx))) (math.floor posy)))
(set posx (- posx (* mvspeed dirx)))) (set posx (- posx (* mvspeed dirx)))
(state.modDis mvspeed))
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed diry))))) (when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed diry)))))
(set posy (- posy (* mvspeed diry)))) (set posy (- posy (* mvspeed diry)))
(state.modDis mvspeed))
) )
(when (love.keyboard.isDown "f") (when (love.keyboard.isDown "f")
(when (= 0 (. map (math.floor (+ (* mvspeed planex) posx)) (math.floor posy))) (when (= 0 (. map (math.floor (+ (* mvspeed planex) posx)) (math.floor posy)))
(set posx (+ (* mvspeed planex) posx))) (set posx (+ (* mvspeed planex) posx))
(state.modDis mvspeed))
(when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed planey) posy)))) (when (= 0 (. map (math.floor posx) (math.floor (+ (* mvspeed planey) posy))))
(set posy (+ (* mvspeed planey) posy))) (set posy (+ (* mvspeed planey) posy))
(state.modDis mvspeed))
) )
(when (love.keyboard.isDown "s") (when (love.keyboard.isDown "s")
(when (= 0 (. map (math.floor (- posx (* mvspeed planex))) (math.floor posy))) (when (= 0 (. map (math.floor (- posx (* mvspeed planex))) (math.floor posy)))
(set posx (- posx (* mvspeed planex)))) (set posx (- posx (* mvspeed planex)))
(state.modDis mvspeed))
(when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed planey))))) (when (= 0 (. map (math.floor posx) (math.floor (- posy (* mvspeed planey)))))
(set posy (- posy (* mvspeed planey)))) (set posy (- posy (* mvspeed planey)))
(state.modDis mvspeed))
) )
; (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") (when (love.keyboard.isDown "r")
(var old-dirx dirx) (var old-dirx dirx)
(set dirx (- (* dirx (math.cos (- rtspeed))) (* diry (math.sin (- rtspeed))))) (set dirx (- (* dirx (math.cos (- rtspeed))) (* diry (math.sin (- rtspeed)))))
@ -291,6 +272,12 @@
(set planex (- (* planex (math.cos rtspeed)) (* planey (math.sin rtspeed)))) (set planex (- (* planex (math.cos rtspeed)) (* planey (math.sin rtspeed))))
(set planey (+ (* old-planex (math.sin rtspeed)) (* planey (math.cos rtspeed)))) (set planey (+ (* old-planex (math.sin rtspeed)) (* planey (math.cos rtspeed))))
) )
(if (= 0 (% (+ 1 (math.floor (state.getDis))) 10))
(when count-down
(set count-down false)
(state.modO -1))
(set count-down true))
) )
:mousemoved (fn mousemoved [x y dx dy] :mousemoved (fn mousemoved [x y dx dy]
@ -308,6 +295,7 @@
) )
:keypressed (fn keypressed [k] :keypressed (fn keypressed [k]
(when (= k "o") (state.modO -1))
(when (= k "x") (love.event.quit)) (when (= k "x") (love.event.quit))
) )
} }

View file

@ -186,3 +186,91 @@ Remaining tasks:
2. Draw floors 2. Draw floors
3. Draw sky-boxen 3. Draw sky-boxen
4. Add monster mechanics 4. Add monster mechanics
---
Thinking about a HUD. On the top can be a compass, and then on the bottom can be
a few additional things.
For the compass, I know the direction of the player. I've implemented the state
function again, and am writing that data to it and reading from it for the
overlay. When the `player.getX` is greater than 0, I'm "facing" north; when less
than 0, facing south. For the `player.getY`, greater than 0 is west; less than
is east. It's easy to just print the value, but it'd be really cool to instead
print one of those compass bars. Theoretically it's printing out the elements of
a list at set screen intervals. The list may look like:
```lisp
(var compass-bar [":" "|" "N" "|" ":" "|" "E" "|" ":" "|" "S" "|" ":" "|" "W" "|"])
```
Then it would print 5 elements, starting at x, going to x + 5, wrapping around.
`x` would be determined based on the two values of `player.getX` and
`player.getY`.
This will ensure we loop properly through the indexes, assuming `x` is always
larger than the array length.
```lisp
(fn fi [x] (set r x) (while (> r 5) (set r (- r 5))) r)
```
Beyond this, it may be good to pair this with logic that allows adding or
subtracting from the index and not escaping the list. This would basically check
if the new index will be either less-than 0 or greater than the list length, and
adjust accordingly.
Could be something like:
```
(if x > 0) // northern half
index is set to north
(adjust index by ratio of y to (-1 .. 1))
(else) // southern half
index is set to south
(adjust index by ratio y to (-1 .. 1))
```
The adjustment algorithm is the same, and it's either added or subtracted from
the index, based on which hemisphere, probably?
This value `(math.floor (+ 10 (* 10 (player.getDirX))))` yields 0-19 in both an
east and west facing arc. If I use east and west as a switch, then when I'm
facing east I can move the compass bar list in one direction, and the other when
facing west.
In order to do this I need a proper circular-list approach.
```lisp
(var compass [<elements>])
(fn circular-compass [c n]
(if (< (+ c n) 1) (length compass)
(> (length compass) (+ c n)) 0
(+ c n))
```
---
Compass bar "works", at least well enough for now. Time to move to some menus. I
think a cool aesthetic would be the start menu being like the inside of the
escape pod you start outside of. The background would be a texture of some kind
of metallic wall, and there could be a flashing light effect. The menu items
would be the configuration for the maze: size, number of survivors, etc.. There
would be a button to start, and then a button to quit. If I have time, there can
be a button to remap keys, and maybe turn sound on and off.
Focusing on the menu buttons themselves, each one has a shape and text.
Additionally, each one should have a hover effect. Each menu can have a
left-action, right-action, and select-action.
```lisp
(var menu-font (love.graphics.newFont 20))
(fn menu-button [x y text la ra sa]
(love.graphics.polygon ...)
(love.graphics.printf text menu-font x (+ y ...) (+ x ...))
(var (left-area right-area mid-area) (values ...))
(when (left-area) (la))
(when (right-area) (ra))
(when (mid-area) (sa))
```
There should also be a way to navigate with the keyboard. Using up and down
arrows or keys will move the "selected" button, left/right arrows/keys will
activate the left/right actions, and enter/use will activate the select action.

View file

@ -53,10 +53,81 @@
(- x dx) (+ y by dy))) (- x dx) (+ y by dy)))
(set dx (+ dx bb)))) (set dx (+ dx bb))))
(fn overlay [dx dy] ; This draws barriers around the screen
; Eventually to be improved into a helmet
(fn helmet-hud []
(love.graphics.setColor 0 1 0 0.25)
(love.graphics.line 0 0
(+ (/ screen-width 6) 0) 35
(+ (/ screen-width 3) 0) 30
(- screen-width (/ screen-width 3)) 30
(- screen-width (/ screen-width 6)) 35
screen-width 0)
; (love.graphics.polygon "fill" (- screen-width 20) 0
; screen-width 0
; screen-width (- screen-height 20)
; (- screen-width 20) (- screen-height 20))
; (love.graphics.polygon "fill" 0 0
; 20 0
; 20 screen-height
; 0 screen-height)
; (love.graphics.polygon "fill" 0 (- screen-height 50)
; (/ screen-width 6) (- screen-height 35)
; (/ screen-width 3) (- screen-height 30)
; 0 screen-height)
; (love.graphics.polygon "fill" screen-width (- screen-height 50)
; (- screen-width (/ screen-width 6)) (- screen-height 35)
; (- screen-width (/ screen-width 3)) (- screen-height 30)
; screen-width screen-height)
)
; This draws a compass bar at the top of the HUD
(var hc-bar-east ["-" "-" "|" "N" "|"
"-" "-" "|" "NE" "|"
"-" "-" "|" "E" "|"
"-" "-" "|" "SE" "|"
"-" "|" "S" "|" "-" ])
(var hc-bar-west ["-" "-" "|" "N" "|"
"-" "-" "|" "NW" "|"
"-" "-" "|" "W" "|"
"-" "-" "|" "SW" "|"
"-" "|" "S" "|" "-" ])
(var hc-bar-limit 6)
(fn circular-compass [l c n]
(if (< (+ c n) 1) (length l)
(> (+ c n) (length l)) 1
(+ c n)))
(fn compass-bar []
(love.graphics.setColor 0 1 0 0.25)
(var (hc-output hc-padding) (values "" " "))
(var hc-idx (math.floor (+ 10 (* 10 (player.getDirX)))))
(var hc-idx-mod 1)
(for [i 1 (+ 1 hc-bar-limit)]
(if (> (player.getDirY) 0)
(do
(set hc-idx-mod 1)
(set hc-idx (circular-compass hc-bar-east hc-idx hc-idx-mod))
(set hc-output (.. hc-output (. hc-bar-east hc-idx) hc-padding)))
(do
(set hc-idx-mod 1)
(set hc-idx (circular-compass hc-bar-west hc-idx hc-idx-mod))
(set hc-output (.. (. hc-bar-west hc-idx) hc-padding hc-output)))))
hc-output)
(fn hud-compass []
(var old-font (love.graphics.getFont))
(love.graphics.setNewFont 20)
(love.graphics.setColor 0.5 1 1 0.5)
(var compass-bar-output (compass-bar))
(love.graphics.printf compass-bar-output 0 50 screen-width :center)
(love.graphics.setFont old-font))
(fn overlay [dx dy pos-x]
(love.graphics.translate dx (- dy)) (love.graphics.translate dx (- dy))
(oxygen-ui (+ (/ screen-width 2) 100) (- screen-height 100)) (oxygen-ui (+ (/ screen-width 2) 100) (- screen-height 100))
(power-ui (- (/ screen-width 2) 100) (- screen-height 100)) ; (power-ui (- (/ screen-width 2) 100) (- screen-height 100))
(helmet-hud)
(hud-compass)
(love.graphics.setColor 1 1 1) (love.graphics.setColor 1 1 1)
) )

View file

@ -2,34 +2,35 @@
(local pi math.pi) (local pi math.pi)
; The Player table holds all the player stuff ; The Player table holds all the player stuff
; The Inventory table holds the player's inventory ; [x y] coordinates, [d] distance
; [x y] coordinates, [d]irection, [f]ield-of-view ; [dx dy] direction vector
; [o]xygen and [p]ower ; [o]xygen
(var player {:x 3.5 :y 3.5 :d 0 :f (/ pi 3) (var player {:x 3.5 :y 3.5 :d 0
:o 100 :p 45}) :o 100})
(var inventory []) (var inventory [])
; The Map table holds the map ; The Map table holds the map meta-data
(var map []) ; [n] number of cells
; [h w] hall and wall widths
(var map {:n 10 :h 2 :w 2})
{:getPlayer (fn getPlayer [] player) {:getPlayer (fn getPlayer [] player)
:getX (fn getX [] player.x) :getX (fn getX [] player.x)
:setX (fn setX [x] (set player.x x)) :setX (fn setX [x] (set player.x x))
:getY (fn getY [] player.y) :getY (fn getY [] player.y)
:setY (fn setY [y] (set player.y y)) :setY (fn setY [y] (set player.y y))
:getD (fn getD [] player.d) :getDirX (fn getDirX [] player.dx)
:setD (fn setD [d] (set player.d d)) :setDirX (fn setDirX [x] (set player.dx x))
:getX (fn getX [] player.x) :getDirY (fn getDirY [] player.dy)
:setDirY (fn setDirY [y] (set player.dy y))
:getO (fn getO [] player.o) :getO (fn getO [] player.o)
:setO (fn setO [x] (set player.o x)) :setO (fn setO [x] (set player.o x))
:getDis (fn getDis [] player.d)
:setDis (fn setDis [x] (set player.d x))
:modDis (fn modDis [x] (set player.d (+ player.d x)))
:modO (fn modO [x] :modO (fn modO [x]
(if (< (+ player.o x) 0) (if (< (+ player.o x) 0)
(set player.o 0) (set player.o 0)
(set player.o (+ player.o x)))) (set player.o (+ player.o x))))
:getP (fn getP [] player.p) :getMap (fn getMap [] map)
:setP (fn setP [x] (set player.p x))
:modP (fn modP [x]
(if (< (+ player.p x) 0)
(set player.p 0)
(set player.p (+ player.p x))))
} }

View file

@ -4,8 +4,6 @@
(love.graphics.newCanvas w h))) (love.graphics.newCanvas w h)))
(var scale 1) (var scale 1)
(love.mouse.setGrabbed true)
(love.mouse.setRelativeMode true)
;; set the first mode ;; set the first mode
(var (mode mode-name) nil) (var (mode mode-name) nil)
@ -19,9 +17,8 @@
(fn love.load [args] (fn love.load [args]
; THIS IS WHERE WE SET THE START MODE ; THIS IS WHERE WE SET THE START MODE
; ################################### ; ###################################
; (set-mode :ray-cast-vectors) (set-mode :mode-intro)
; (set-mode :mode-intro) ; (set-mode :mode-play)
(set-mode :raycaster)
; ################################### ; ###################################
(canvas:setFilter "nearest" "nearest") (canvas:setFilter "nearest" "nearest")
(when (~= :web (. args 1)) (repl.start))) (when (~= :web (. args 1)) (repl.start)))