61 lines
1.8 KiB
Fennel
61 lines
1.8 KiB
Fennel
|
|
(fn held-directions [keymap]
|
|
(let [dirs {}]
|
|
(each [_ dir (ipairs [:up :down :left :right])]
|
|
(when (love.keyboard.isDown (. keymap dir)) (tset dirs dir true)))
|
|
dirs))
|
|
|
|
(fn dirs-from-dir [dir]
|
|
(if dir {dir true} {}))
|
|
|
|
(fn vec-from-dirs [dirs]
|
|
[(if dirs.left -1 dirs.right 1 0)
|
|
(if dirs.up -1 dirs.down 1 0)])
|
|
|
|
(fn dir-from-key [keymap]
|
|
(vec-from-dirs (held-directions keymap)))
|
|
|
|
(fn vec-scalarop [op]
|
|
(fn [vec scalar]
|
|
(icollect [_ v (ipairs vec)] (op v scalar))))
|
|
|
|
(fn vec-op [op]
|
|
(fn [vec val]
|
|
(icollect [i left (ipairs vec)]
|
|
(let [right (match (type val)
|
|
:table (. val i)
|
|
_ val)]
|
|
(op left right)))))
|
|
|
|
(local vec* (vec-op #(* $1 $2)))
|
|
(local vec+ (vec-op #(+ $1 $2)))
|
|
|
|
(fn coordinate-iterator [state]
|
|
(let [{: x : y} state
|
|
xnext (+ (or x state.w) 1)
|
|
ynext (+ (or y state.h) 1)]
|
|
(if (< xnext state.w) (set state.x xnext)
|
|
(< ynext state.h) (do (set state.x 0) (set state.y ynext))
|
|
(do (set state.x nil) (set state.y nil)))
|
|
(values x y)))
|
|
|
|
(fn all-coordinates [w h] (values coordinate-iterator {: w : h :x 0 :y 0}))
|
|
|
|
(fn edge [c dc neg-offset ?pos-offset]
|
|
(local pos-offset (if (= ?pos-offset nil) neg-offset ?pos-offset))
|
|
(if (= dc 0) (values c c)
|
|
(< dc 0) (values (- c neg-offset) (+ c dc (- neg-offset)))
|
|
(values (+ c pos-offset) (+ c dc pos-offset))))
|
|
|
|
(fn edge-crosses [c1 c2 width]
|
|
(let [t1 (math.floor (/ c1 width))
|
|
t2 (math.floor (/ c2 width))]
|
|
(if (= c1 c2) false
|
|
(= (% c1 width) 0) (values true c1)
|
|
(= (% c2 width) 0) (values true c2)
|
|
(not= t1 t2) (values true (* (math.max t1 t2) width))
|
|
false)))
|
|
|
|
{: dir-from-key : held-directions : vec-from-dirs : dirs-from-dir
|
|
: vec* : vec+ : vec-op : all-coordinates : edge : edge-crosses}
|