|
|
|
@ -29,68 +29,56 @@
|
|
|
|
|
|
|
|
|
|
(def reloaded (atom false))
|
|
|
|
|
|
|
|
|
|
(defn set-timing
|
|
|
|
|
"sets the current time at the given key"
|
|
|
|
|
[state timingkey]
|
|
|
|
|
(assoc-in state
|
|
|
|
|
[:timing timingkey]
|
|
|
|
|
(.now js/performance)))
|
|
|
|
|
|
|
|
|
|
(defn set-fps
|
|
|
|
|
(defn curr-fps
|
|
|
|
|
"calculates the current fps using the elapsed time"
|
|
|
|
|
[state]
|
|
|
|
|
(let [elapsed (-> state :timing :elapsed)
|
|
|
|
|
fps (/ 1 elapsed)]
|
|
|
|
|
(assoc-in state [:timing :fps] fps)))
|
|
|
|
|
[elapsed]
|
|
|
|
|
(/ 1 elapsed))
|
|
|
|
|
|
|
|
|
|
(defn elapsed-seconds
|
|
|
|
|
"calculates the elapsed seconds since the last frame"
|
|
|
|
|
[gamestate now]
|
|
|
|
|
(/ (- now (-> gamestate :timing :prev))
|
|
|
|
|
1000))
|
|
|
|
|
|
|
|
|
|
(defn set-elapsed-seconds
|
|
|
|
|
"calculates and writes the elapsed seconds since the last frame"
|
|
|
|
|
(defn curr-scene
|
|
|
|
|
"returns the current scene"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(update gamestate
|
|
|
|
|
:timing
|
|
|
|
|
#(let [{:keys [now prev]} %]
|
|
|
|
|
(assoc % :elapsed
|
|
|
|
|
(/ (- now prev)
|
|
|
|
|
1000)))))
|
|
|
|
|
(get-in gamestate [:scenes (:scene gamestate)]))
|
|
|
|
|
|
|
|
|
|
(defn update-scene
|
|
|
|
|
(defn run-scene-update
|
|
|
|
|
"updates the current scene using its udpate function"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(if-not (:continue? gamestate)
|
|
|
|
|
gamestate
|
|
|
|
|
(let [scenekey (:scene gamestate)
|
|
|
|
|
{updatefunc :update
|
|
|
|
|
:as scene} (get-in gamestate [:scenes scenekey])
|
|
|
|
|
newstate (updatefunc gamestate scene)]
|
|
|
|
|
(assoc-in gamestate [:scenes scenekey] newstate))))
|
|
|
|
|
[gamestate scene]
|
|
|
|
|
((:update scene) gamestate scene))
|
|
|
|
|
|
|
|
|
|
(defn continue-running?
|
|
|
|
|
"checks if the gameloop should keep running, based on input"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(update
|
|
|
|
|
gamestate
|
|
|
|
|
:continue?
|
|
|
|
|
(fn [continue?]
|
|
|
|
|
[prev-continue?]
|
|
|
|
|
(cond
|
|
|
|
|
(and continue?
|
|
|
|
|
(and prev-continue?
|
|
|
|
|
(input/keydown? :Digit2)
|
|
|
|
|
(input/keydown? :ControlLeft)) false
|
|
|
|
|
(and (not continue?)
|
|
|
|
|
(and (not prev-continue?)
|
|
|
|
|
(input/keydown? :Digit3)
|
|
|
|
|
(input/keydown? :ControlLeft)) true
|
|
|
|
|
:else continue?))))
|
|
|
|
|
:else prev-continue?))
|
|
|
|
|
|
|
|
|
|
(defn update-step
|
|
|
|
|
"updates timing information and the current scene"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(-> gamestate
|
|
|
|
|
(assoc-in [:input :dir] (input/dir))
|
|
|
|
|
(set-timing :now)
|
|
|
|
|
(set-elapsed-seconds)
|
|
|
|
|
(set-fps)
|
|
|
|
|
(continue-running?)
|
|
|
|
|
(update-scene)
|
|
|
|
|
(set-timing :prev)))
|
|
|
|
|
(let [now (.now js/performance)
|
|
|
|
|
secs (elapsed-seconds gamestate now)
|
|
|
|
|
scene (curr-scene gamestate)
|
|
|
|
|
continue? (continue-running? (:continue? gamestate))]
|
|
|
|
|
(as-> gamestate $
|
|
|
|
|
(assoc-in $ [:input :dir] (input/dir))
|
|
|
|
|
(assoc $ :timing {:now now
|
|
|
|
|
:elapsed secs
|
|
|
|
|
:fps (curr-fps secs)})
|
|
|
|
|
(assoc-in $ [:scenes (:scene gamestate)]
|
|
|
|
|
(if continue?
|
|
|
|
|
(run-scene-update $ scene)
|
|
|
|
|
scene))
|
|
|
|
|
(assoc-in $ [:timing :prev] (.now js/performance)))))
|
|
|
|
|
|
|
|
|
|
(defn draw-fps
|
|
|
|
|
"draws the current fps"
|
|
|
|
@ -123,7 +111,6 @@
|
|
|
|
|
then, it calls itself again using requestAnimationFrame"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(let [newstate (update-step gamestate)]
|
|
|
|
|
(set! (.-imageSmoothingEnabled (:ctx gamestate)) false)
|
|
|
|
|
(draw-step newstate)
|
|
|
|
|
(when-not @reloaded
|
|
|
|
|
(.requestAnimationFrame js/window
|
|
|
|
@ -136,6 +123,8 @@
|
|
|
|
|
(-> gamestate :dimensions :w))
|
|
|
|
|
(set! (.-height (:canvas gamestate))
|
|
|
|
|
(-> gamestate :dimensions :h))
|
|
|
|
|
(set! (.-imageSmoothingEnabled (:ctx gamestate))
|
|
|
|
|
false)
|
|
|
|
|
(update gamestate
|
|
|
|
|
:scenes
|
|
|
|
|
#(reduce
|
|
|
|
|