|
|
|
@ -8,7 +8,6 @@
|
|
|
|
|
(def gamestate
|
|
|
|
|
{:canvas (by-id "gamecanvas")
|
|
|
|
|
:ctx (.getContext (by-id "gamecanvas") "2d")
|
|
|
|
|
:target-fps 60
|
|
|
|
|
:continue? true
|
|
|
|
|
:timing {;; msecs of previous frame
|
|
|
|
|
:prev 0
|
|
|
|
@ -40,7 +39,7 @@
|
|
|
|
|
(defn set-fps
|
|
|
|
|
"calculates the current fps using the elapsed time"
|
|
|
|
|
[state]
|
|
|
|
|
(let [elapsed (get-in state [:timing :elapsed])
|
|
|
|
|
(let [elapsed (-> state :timing :elapsed)
|
|
|
|
|
fps (/ 1 elapsed)]
|
|
|
|
|
(assoc-in state [:timing :fps] fps)))
|
|
|
|
|
|
|
|
|
@ -98,15 +97,13 @@
|
|
|
|
|
[gamestate]
|
|
|
|
|
(let [ctx (:ctx gamestate)]
|
|
|
|
|
(aset ctx "fillStyle" "white")
|
|
|
|
|
(.fillRect
|
|
|
|
|
ctx
|
|
|
|
|
0 0 13 13)
|
|
|
|
|
(.fillRect ctx
|
|
|
|
|
0 0 13 13)
|
|
|
|
|
(aset ctx "fillStyle" "black")
|
|
|
|
|
(aset ctx "font" "10px monospace")
|
|
|
|
|
(.fillText
|
|
|
|
|
(:ctx gamestate)
|
|
|
|
|
(int (get-in gamestate [:timing :fps]))
|
|
|
|
|
0 10)))
|
|
|
|
|
(.fillText (:ctx gamestate)
|
|
|
|
|
(int (get-in gamestate [:timing :fps]))
|
|
|
|
|
0 10)))
|
|
|
|
|
|
|
|
|
|
(defn draw-step
|
|
|
|
|
"clears the canvas, draws fps and invokes the scene draw function"
|
|
|
|
@ -116,44 +113,29 @@
|
|
|
|
|
(get-in gamestate [:dimensions :w])
|
|
|
|
|
(get-in gamestate [:dimensions :h]))
|
|
|
|
|
(let [scenekey (:scene gamestate)
|
|
|
|
|
{:keys [draw] :as scene} (get-in gamestate [:scenes scenekey])]
|
|
|
|
|
{:keys [draw] :as scene} (-> gamestate :scenes scenekey)]
|
|
|
|
|
(draw gamestate scene))
|
|
|
|
|
(draw-fps gamestate))
|
|
|
|
|
|
|
|
|
|
(defn timeout
|
|
|
|
|
"calculates the duration of update-step and draw-step.
|
|
|
|
|
substracts that from the wait time to reach target-fps
|
|
|
|
|
more accurately.
|
|
|
|
|
if continue? is true, wait for 5 seconds plain"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(let [update-elapsed (- (.now js/performance)
|
|
|
|
|
(get-in gamestate [:timing :now]))]
|
|
|
|
|
(if (:continue? gamestate)
|
|
|
|
|
(/ (- 1000 update-elapsed)
|
|
|
|
|
(:target-fps gamestate))
|
|
|
|
|
5000)))
|
|
|
|
|
|
|
|
|
|
(defn mainloop
|
|
|
|
|
"transforms the given gamestate by invoking a series of update
|
|
|
|
|
functions and draws it using the 2d context of the gamestate.
|
|
|
|
|
then, it calls itself again with a delay according to the target fps"
|
|
|
|
|
then, it calls itself again using requestAnimationFrame"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(let [newstate (update-step gamestate)]
|
|
|
|
|
(set! (.-imageSmoothingEnabled (:ctx gamestate)) false)
|
|
|
|
|
(draw-step newstate)
|
|
|
|
|
(when-not @reloaded
|
|
|
|
|
(.setTimeout js/window
|
|
|
|
|
(fn []
|
|
|
|
|
(.requestAnimationFrame
|
|
|
|
|
js/window
|
|
|
|
|
#(mainloop newstate)))
|
|
|
|
|
(timeout newstate)))))
|
|
|
|
|
(.requestAnimationFrame js/window
|
|
|
|
|
#(mainloop newstate)))))
|
|
|
|
|
|
|
|
|
|
(defn init-scenes
|
|
|
|
|
"initiates the scene data maps using their respective init functions"
|
|
|
|
|
[]
|
|
|
|
|
(set! (.-width (:canvas gamestate)) (get-in gamestate [:dimensions :w]))
|
|
|
|
|
(set! (.-height (:canvas gamestate)) (get-in gamestate [:dimensions :h]))
|
|
|
|
|
(set! (.-width (:canvas gamestate))
|
|
|
|
|
(-> gamestate :dimensions :w))
|
|
|
|
|
(set! (.-height (:canvas gamestate))
|
|
|
|
|
(-> gamestate :dimensions :h))
|
|
|
|
|
(update gamestate
|
|
|
|
|
:scenes
|
|
|
|
|
#(reduce
|
|
|
|
|