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
; 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
; ("hall-width").
(var cell-num 20)
(var (hall-width wall-width) (values 2 4))
(var map-meta (state.getMap))
(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))
; (fn wall-seg [] (+ 10 (math.random 1 3)))
(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 1280)
; (var screen-height 720)
(var texel-width 64)
(var texel-height 64)
(var (mx my) (values (/ screen-width 2) (/ screen-height 2)))
(love.mouse.setGrabbed false)
(love.mouse.setRelativeMode false)
; Ray-casting function
(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))))
(love.graphics.setNewFont 30)
(values distance hit-pos tex rays))
; Function to handle player movement
(fn move-player [move-speed]
(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))))
(var footer-font (love.graphics.newFont 19))
(local (major minor revision) (love.getVersion))
; Draw function for rendering
{:draw (fn love.draw []
(love.graphics.clear)
; For each vertical slice of the screen
(var (last-x last-y) (values 0 0))
(for [i 0 (- screen-width 1)]
; Calculate angle of ray relative to player direction
(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))
(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))
; Draw a textured wall
(local wall-texture (. walls tex))
(var texture-x 0)
(if (> (/ (- (. rays 1) last-x) (- (. rays 2) last-y)) (/ (- (. rays 2) last-y) (- (. rays 1) last-x)))
(set texture-x (math.floor (* (. hit-pos :y) (. wall-texture :w))))
(set texture-x (math.floor (* (. hit-pos :x) (. wall-texture :w)))))
(love.graphics.draw (. wall-texture :t)
(love.graphics.newQuad texture-x 0 1 (. wall-texture :h) (. wall-texture :w) (. wall-texture :h))
i start-y 0 1 (/ wall-height (. wall-texture :h)))
(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)))
)
(var menu-font (love.graphics.newFont 20))
(fn menu-button [x y t]
(love.graphics.polygon "line" x y
(+ x 100) y
(+ x 120) (+ y 20)
(+ x 100) (+ y 40)
x (+ y 40)
(- x 20) (+ y 20))
(love.graphics.printf t x (+ y 11) (+ x 100))
)
(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]
(when (= key "j") (state.setD (- player.d (/ pi 2))))
(when (= key "l") (state.setD (+ player.d (/ pi 2))))
(when (= key "i") (move-player 1))
(when (= key "k") (move-player -1))
(when (= key "x") (love.event.quit)))}
:keypressed
(fn keypressed [key set-mode]
(when (= key "d")
(set-mode :mode-play))
(when (= key "q")
(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 overlay (require :overlay))
(local pi math.pi)
(var count-down true)
; ### Screen Size ###
(var (screen-width screen-height) (love.window.getMode))
(love.mouse.setGrabbed true)
(love.mouse.setRelativeMode true)
; ### Map Information ###
(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 ###
(var walls [])
@ -55,6 +43,8 @@
{
:draw (fn love.draw []
(state.setDirX dirx)
(state.setDirY diry)
; Mouse-Look
(love.graphics.translate offst-x offst-y)
@ -63,56 +53,57 @@
; (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 cf-f-tex-num (. walls 2))
(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)))
; (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)))
(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)))
; 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))
; 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))
; 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))
; 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))))
; 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)))
; 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)))))
; 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)
;; Draw the texture
; (var tex-num cf-f-tex-num)
; (love.graphics.draw (. tex-num :t)
; (love.graphics.newQuad cf-tx 0 1 (. tex-num :h) (. tex-num :w) (. tex-num :h))
; i cf-ty 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))
; )
; )
; 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
@ -204,15 +195,17 @@
(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 7)))
(love.graphics.setColor 1 1 1 fog-dist)
(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))
(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.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)))
@ -228,52 +221,40 @@
(when (love.keyboard.isDown "e")
(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))))
(set posy (+ (* mvspeed diry) posy)))
(set posy (+ (* mvspeed diry) posy))
(state.modDis mvspeed))
)
(when (love.keyboard.isDown "d")
(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)))))
(set posy (- posy (* mvspeed diry))))
(set posy (- posy (* mvspeed diry)))
(state.modDis mvspeed))
)
(when (love.keyboard.isDown "f")
(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))))
(set posy (+ (* mvspeed planey) posy)))
(set posy (+ (* mvspeed planey) posy))
(state.modDis mvspeed))
)
(when (love.keyboard.isDown "s")
(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)))))
(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")
(var old-dirx dirx)
(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 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]
@ -308,6 +295,7 @@
)
:keypressed (fn keypressed [k]
(when (= k "o") (state.modO -1))
(when (= k "x") (love.event.quit))
)
}

View file

@ -186,3 +186,91 @@ Remaining tasks:
2. Draw floors
3. Draw sky-boxen
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)))
(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))
(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)
)

View file

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

View file

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