|
|
|
@ -31,10 +31,9 @@
|
|
|
|
|
(defn set-timing
|
|
|
|
|
"sets the current time at the given key"
|
|
|
|
|
[state timingkey]
|
|
|
|
|
(assoc-in
|
|
|
|
|
state
|
|
|
|
|
[:timing timingkey]
|
|
|
|
|
(.now js/performance)))
|
|
|
|
|
(assoc-in state
|
|
|
|
|
[:timing timingkey]
|
|
|
|
|
(.now js/performance)))
|
|
|
|
|
|
|
|
|
|
(defn set-fps
|
|
|
|
|
"calculates the current fps using the elapsed time"
|
|
|
|
@ -46,12 +45,12 @@
|
|
|
|
|
(defn set-elapsed-seconds
|
|
|
|
|
"calculates and writes the elapsed seconds since the last frame"
|
|
|
|
|
[gamestate]
|
|
|
|
|
(assoc-in
|
|
|
|
|
gamestate
|
|
|
|
|
[:timing :elapsed]
|
|
|
|
|
(/ (-(get-in gamestate [:timing :now])
|
|
|
|
|
(get-in gamestate [:timing :prev]))
|
|
|
|
|
1000)))
|
|
|
|
|
(update gamestate
|
|
|
|
|
:timing
|
|
|
|
|
#(let [{:keys [now prev]} %]
|
|
|
|
|
(assoc % :elapsed
|
|
|
|
|
(/ (- now prev)
|
|
|
|
|
1000)))))
|
|
|
|
|
|
|
|
|
|
(defn update-scene
|
|
|
|
|
"updates the current scene using its udpate function"
|
|
|
|
@ -59,9 +58,9 @@
|
|
|
|
|
(if-not (:continue? gamestate)
|
|
|
|
|
gamestate
|
|
|
|
|
(let [scenekey (:scene gamestate)
|
|
|
|
|
scenestate (get-in gamestate [:scenes scenekey])
|
|
|
|
|
updatefunc (:update scenestate)
|
|
|
|
|
newstate (updatefunc gamestate scenestate)]
|
|
|
|
|
{updatefunc :update
|
|
|
|
|
:as scene} (get-in gamestate [:scenes scenekey])
|
|
|
|
|
newstate (updatefunc gamestate scene)]
|
|
|
|
|
(assoc-in gamestate [:scenes scenekey] newstate))))
|
|
|
|
|
|
|
|
|
|
(defn continue-running?
|
|
|
|
@ -74,14 +73,11 @@
|
|
|
|
|
(cond
|
|
|
|
|
(and continue?
|
|
|
|
|
(input/keydown? :Digit2)
|
|
|
|
|
(input/keydown? :ControlLeft))
|
|
|
|
|
false
|
|
|
|
|
(input/keydown? :ControlLeft)) false
|
|
|
|
|
(and (not continue?)
|
|
|
|
|
(input/keydown? :Digit3)
|
|
|
|
|
(input/keydown? :ControlLeft))
|
|
|
|
|
true
|
|
|
|
|
:else
|
|
|
|
|
continue?))))
|
|
|
|
|
(input/keydown? :ControlLeft)) true
|
|
|
|
|
:else continue?))))
|
|
|
|
|
|
|
|
|
|
(defn update-step
|
|
|
|
|
"updates timing information and the current scene"
|
|
|
|
@ -118,11 +114,22 @@
|
|
|
|
|
(get-in gamestate [:dimensions :w])
|
|
|
|
|
(get-in gamestate [:dimensions :h]))
|
|
|
|
|
(let [scenekey (:scene gamestate)
|
|
|
|
|
scene (get-in gamestate [:scenes scenekey])
|
|
|
|
|
drawfunc (:draw scene)]
|
|
|
|
|
(drawfunc gamestate scene))
|
|
|
|
|
{:keys [draw] :as scene} (get-in 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]
|
|
|
|
|
(if (:continue? gamestate)
|
|
|
|
|
(/ (- 1000 (- (.now js/performance)
|
|
|
|
|
(get-in gamestate [:timing :now])))
|
|
|
|
|
(: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.
|
|
|
|
@ -130,35 +137,21 @@
|
|
|
|
|
[gamestate]
|
|
|
|
|
(let [newstate (update-step gamestate)]
|
|
|
|
|
(draw-step newstate)
|
|
|
|
|
;; calculate the duration of update-step and draw-step
|
|
|
|
|
;; substract that from the wait time to reach target-fps
|
|
|
|
|
;; more accurately
|
|
|
|
|
(let [now (get-in newstate [:timing :now])
|
|
|
|
|
duration (- (.now js/performance) now)
|
|
|
|
|
timeout (if (:continue? newstate)
|
|
|
|
|
(/
|
|
|
|
|
(- 1000 duration)
|
|
|
|
|
(:target-fps newstate))
|
|
|
|
|
5000)]
|
|
|
|
|
(.setTimeout js/window
|
|
|
|
|
(fn []
|
|
|
|
|
(.requestAnimationFrame
|
|
|
|
|
js/window
|
|
|
|
|
#(mainloop newstate)))
|
|
|
|
|
timeout))))
|
|
|
|
|
(.setTimeout js/window
|
|
|
|
|
(fn []
|
|
|
|
|
(.requestAnimationFrame
|
|
|
|
|
js/window
|
|
|
|
|
#(mainloop newstate)))
|
|
|
|
|
(timeout newstate))))
|
|
|
|
|
|
|
|
|
|
(defn init-scenes
|
|
|
|
|
"initiates the scene data maps using their respective init functions"
|
|
|
|
|
[]
|
|
|
|
|
(assoc
|
|
|
|
|
gamestate
|
|
|
|
|
:scenes
|
|
|
|
|
(reduce
|
|
|
|
|
(fn [scenes [scenekey scenestate]]
|
|
|
|
|
(let [initfunc (:init scenestate)
|
|
|
|
|
newstate (initfunc gamestate scenestate)]
|
|
|
|
|
(assoc scenes scenekey newstate)))
|
|
|
|
|
{}
|
|
|
|
|
(:scenes gamestate))))
|
|
|
|
|
(update gamestate
|
|
|
|
|
:scenes
|
|
|
|
|
#(reduce
|
|
|
|
|
(fn [carr [key scene]]
|
|
|
|
|
(assoc carr key ((:init scene) gamestate scene)))
|
|
|
|
|
{} %)))
|
|
|
|
|
|
|
|
|
|
(mainloop (init-scenes))
|
|
|
|
|