(local map-util (require "map-util.fnl")) (var player-sprite nil) ; 20x20 pixels (var dust-sprite nil) ; 35x35 pixels (local game-state { :player-pos [0 0] :player-dir :n ; n = north, s = south, e = east, w = west :level 1 :world [] }) (fn start-level [] ;; set player position to the start of the current level (tset game-state :player-pos (. map-util :levels (. game-state :level) :player-start)) ;; set fresh world (let [world []] (each [y walls (ipairs (. map-util :levels (. game-state :level) :walls))] (table.insert world []) (each [x wall (ipairs walls)] (table.insert (. world y) {:revealed false :type (if (= wall 1) :wall :floor) }) ) ) (tset game-state :world world) ) ) (fn love.load [] (map-util:load) (love.window.setMode 600 640) (set player-sprite (love.graphics.newImage "assets/player_001.png")) (set dust-sprite (love.graphics.newImage "assets/dust_001.png")) (start-level) (print (fennel.view game-state)) ;; start a thread listening on stdin (: (love.thread.newThread "require('love.event') while 1 do love.event.push('stdin', io.read('*line')) end") :start)) (fn love.handlers.stdin [line] ;; evaluate lines read from stdin as fennel code (let [(ok val) (pcall fennel.eval line)] (print (if ok (fennel.view val) val)))) ;; drawing (lambda color [full-r full-g full-b] (let [(r g b) (love.math.colorFromBytes full-r full-g full-b)] [r g b] )) (local off-white (color 237 230 200)) (local black [0 0 0]) (local black-half-tone [0 0 0 0.25]) (fn draw-game-outline [] (love.graphics.setColor (unpack black)) (love.graphics.rectangle "line" 50 50 500 500)) (fn draw-world [] (love.graphics.setColor (unpack black)) ; (love.graphics.rectangle "fill" 50 50 500 500)) (each [y cells (ipairs (. game-state :world))] (each [x cell (ipairs cells)] (case [(. cell :revealed) (. cell :type)] [false _] (do (love.graphics.setColor 1 1 1) ; reset color to white (no tinting) (love.graphics.draw dust-sprite (+ 45 (* 25 (- x 1))) (+ 45 (* 25 (- y 1))))) [true :wall] (do (love.graphics.setColor (unpack black)) (love.graphics.rectangle "fill" (+ 50 (* 25 (- x 1))) (+ 50 (* 25 (- y 1))) 25 25)) ) ) ) ) ; (print (fennel.view game-state)) (fn draw-player [] (love.graphics.setColor 1 1 1) ; reset color to white (no tinting) (let [ [player-x player-y] (. game-state :player-pos) rot (case (. game-state :player-dir) :n 0 :s (* math.pi 1) :e (* math.pi 0.5) :w (* math.pi 1.5)) x-offset (case (. game-state :player-dir) :n 0 :s 25 :e 25 :w 0) y-offset (case (. game-state :player-dir) :n 0 :s 25 :e 0 :w 25) ] (love.graphics.draw player-sprite (+ (* 25 player-x) x-offset 25) (+ (* 25 player-y) y-offset 25) rot 1.25 1.25))) (fn draw-ghost-grid [] (love.graphics.setColor (unpack black-half-tone)) (for [y 0 19 1] (for [x 0 19 1] (love.graphics.rectangle "line" (+ 50 (* x 25)) (+ 50 (* y 25)) 25 25)))) (fn love.draw [] ;; clear the screen and set bg to off white (love.graphics.clear) (love.graphics.setColor (unpack off-white)) (love.graphics.rectangle "fill" 0 0 600 640) (draw-game-outline) (draw-ghost-grid) (draw-world) (draw-player) ) ; (love.graphics.print "Hello from Fennel!\nPress any key to quit" 10 10)) (fn love.keypressed [key] (let [ [player-x player-y] (. game-state :player-pos) [next-player-x next-player-y] (case key :left [(- player-x 1) player-y] :up [player-x (- player-y 1)] :right [(+ player-x 1) player-y] :down [player-x (+ player-y 1)] _ [player-x player-y]) next-cell (. game-state :world next-player-y next-player-x) valid-move (not= :wall (. next-cell :type)) ] (when valid-move (tset game-state :player-pos [next-player-x next-player-y])) (tset game-state :world next-player-y next-player-x :revealed true) (case key :left (tset game-state :player-dir :w) :up (tset game-state :player-dir :n) :right (tset game-state :player-dir :e) :down (tset game-state :player-dir :s))) )