From fd96d53a347d0349603f17b7c4bc26ce49d0e1e8 Mon Sep 17 00:00:00 2001 From: Bill Niblock Date: Sat, 2 Nov 2024 17:09:38 -0400 Subject: [PATCH] Use state more, start on menus --- mapper.fnl | 6 +- mode-intro.fnl | 163 ++++++++++++--------------------- raycaster.fnl => mode-play.fnl | 160 +++++++++++++++----------------- notes.md | 88 ++++++++++++++++++ overlay.fnl | 75 ++++++++++++++- state.fnl | 33 +++---- wrap.fnl | 7 +- 7 files changed, 315 insertions(+), 217 deletions(-) rename raycaster.fnl => mode-play.fnl (65%) diff --git a/mapper.fnl b/mapper.fnl index 553fa92..0517e33 100644 --- a/mapper.fnl +++ b/mapper.fnl @@ -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)) diff --git a/mode-intro.fnl b/mode-intro.fnl index 86c6417..45f45eb 100644 --- a/mode-intro.fnl +++ b/mode-intro.fnl @@ -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))) +} diff --git a/raycaster.fnl b/mode-play.fnl similarity index 65% rename from raycaster.fnl rename to mode-play.fnl index d5dba9f..32f1b6e 100644 --- a/raycaster.fnl +++ b/mode-play.fnl @@ -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)) ) } diff --git a/notes.md b/notes.md index 877225d..1651e9f 100644 --- a/notes.md +++ b/notes.md @@ -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 []) +(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. diff --git a/overlay.fnl b/overlay.fnl index 012bdd2..ea2665a 100644 --- a/overlay.fnl +++ b/overlay.fnl @@ -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) ) diff --git a/state.fnl b/state.fnl index b694d99..d970d66 100644 --- a/state.fnl +++ b/state.fnl @@ -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) } diff --git a/wrap.fnl b/wrap.fnl index 825e3da..19aac87 100644 --- a/wrap.fnl +++ b/wrap.fnl @@ -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)))