|
|
@ -10,15 +10,21 @@
|
|
|
|
:2d (.getContext (.getElementById js/document "gamecanvas") "2d")
|
|
|
|
:2d (.getContext (.getElementById js/document "gamecanvas") "2d")
|
|
|
|
:target-fps 30
|
|
|
|
:target-fps 30
|
|
|
|
:timing {
|
|
|
|
:timing {
|
|
|
|
|
|
|
|
; msecs of previous frame
|
|
|
|
:prev 0
|
|
|
|
:prev 0
|
|
|
|
|
|
|
|
; msecs of current frame
|
|
|
|
:now 0
|
|
|
|
:now 0
|
|
|
|
|
|
|
|
; fps resulting of prev and now
|
|
|
|
:fps 0
|
|
|
|
:fps 0
|
|
|
|
|
|
|
|
; difference between prev and now in seconds
|
|
|
|
:elapsed 0
|
|
|
|
:elapsed 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
; width and height of the canvas
|
|
|
|
:dimensions {
|
|
|
|
:dimensions {
|
|
|
|
:w 600
|
|
|
|
:w 600
|
|
|
|
:h 400
|
|
|
|
:h 400
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
; currently active scene
|
|
|
|
:scene :demo
|
|
|
|
:scene :demo
|
|
|
|
:scenes {
|
|
|
|
:scenes {
|
|
|
|
:demo {
|
|
|
|
:demo {
|
|
|
@ -32,17 +38,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
(aset (:2d gamestate) "font" "10px monospace")
|
|
|
|
(aset (:2d gamestate) "font" "10px monospace")
|
|
|
|
|
|
|
|
|
|
|
|
(defn set-timing [state timingkey]
|
|
|
|
(defn set-timing
|
|
|
|
|
|
|
|
"sets the current time at the given key"
|
|
|
|
|
|
|
|
[state timingkey]
|
|
|
|
(assoc-in state
|
|
|
|
(assoc-in state
|
|
|
|
[:timing timingkey]
|
|
|
|
[:timing timingkey]
|
|
|
|
(.now js/performance)))
|
|
|
|
(.now js/performance)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn set-fps [state]
|
|
|
|
(defn set-fps
|
|
|
|
|
|
|
|
"calculates the current fps using the elapsed time"
|
|
|
|
|
|
|
|
[state]
|
|
|
|
(let [elapsed (get-in state [:timing :elapsed])
|
|
|
|
(let [elapsed (get-in state [:timing :elapsed])
|
|
|
|
fps (/ 1 elapsed)]
|
|
|
|
fps (/ 1 elapsed)]
|
|
|
|
(assoc-in state [:timing :fps] fps)))
|
|
|
|
(assoc-in state [:timing :fps] fps)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn set-elapsed-seconds [gamestate]
|
|
|
|
(defn set-elapsed-seconds
|
|
|
|
|
|
|
|
"calculates and writes the elapsed seconds since the last frame"
|
|
|
|
|
|
|
|
[gamestate]
|
|
|
|
(assoc-in gamestate
|
|
|
|
(assoc-in gamestate
|
|
|
|
[:timing :elapsed]
|
|
|
|
[:timing :elapsed]
|
|
|
|
(/
|
|
|
|
(/
|
|
|
@ -51,14 +63,18 @@
|
|
|
|
(get-in gamestate [:timing :prev]))
|
|
|
|
(get-in gamestate [:timing :prev]))
|
|
|
|
1000)))
|
|
|
|
1000)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn update-scene [gamestate]
|
|
|
|
(defn update-scene
|
|
|
|
|
|
|
|
"updates the current scene using its udpate function"
|
|
|
|
|
|
|
|
[gamestate]
|
|
|
|
(let [scenekey (:scene gamestate)
|
|
|
|
(let [scenekey (:scene gamestate)
|
|
|
|
scenedata (get-in gamestate [:scenes scenekey])
|
|
|
|
scenedata (get-in gamestate [:scenes scenekey])
|
|
|
|
updatefunc (:update scenedata)
|
|
|
|
updatefunc (:update scenedata)
|
|
|
|
newdata (updatefunc gamestate scenedata)]
|
|
|
|
newdata (updatefunc gamestate scenedata)]
|
|
|
|
(update-in gamestate [:scenes scenekey] (fn [] newdata))))
|
|
|
|
(update-in gamestate [:scenes scenekey] (fn [] newdata))))
|
|
|
|
|
|
|
|
|
|
|
|
(defn update-step [gamestate]
|
|
|
|
(defn update-step
|
|
|
|
|
|
|
|
"updates timing information and the current scene"
|
|
|
|
|
|
|
|
[gamestate]
|
|
|
|
(-> gamestate
|
|
|
|
(-> gamestate
|
|
|
|
(set-timing :now)
|
|
|
|
(set-timing :now)
|
|
|
|
(set-elapsed-seconds)
|
|
|
|
(set-elapsed-seconds)
|
|
|
@ -66,7 +82,9 @@
|
|
|
|
(update-scene)
|
|
|
|
(update-scene)
|
|
|
|
(set-timing :prev)))
|
|
|
|
(set-timing :prev)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn draw-step [gamestate]
|
|
|
|
(defn draw-step
|
|
|
|
|
|
|
|
"clears the canvas, draws fps and invokes the scene draw function"
|
|
|
|
|
|
|
|
[gamestate]
|
|
|
|
(.clearRect (:2d gamestate)
|
|
|
|
(.clearRect (:2d gamestate)
|
|
|
|
0 0
|
|
|
|
0 0
|
|
|
|
(get-in gamestate [:dimensions :w])
|
|
|
|
(get-in gamestate [:dimensions :w])
|
|
|
@ -80,7 +98,11 @@
|
|
|
|
drawfunc (:draw scene)]
|
|
|
|
drawfunc (:draw scene)]
|
|
|
|
(drawfunc gamestate scene)))
|
|
|
|
(drawfunc gamestate scene)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn mainloop [gamestate]
|
|
|
|
(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"
|
|
|
|
|
|
|
|
[gamestate]
|
|
|
|
(let [newstate (update-step gamestate)]
|
|
|
|
(let [newstate (update-step gamestate)]
|
|
|
|
(draw-step newstate)
|
|
|
|
(draw-step newstate)
|
|
|
|
(.setTimeout js/window
|
|
|
|
(.setTimeout js/window
|
|
|
@ -89,7 +111,9 @@
|
|
|
|
#(mainloop newstate)))
|
|
|
|
#(mainloop newstate)))
|
|
|
|
(/ 1000 (:target-fps gamestate)))))
|
|
|
|
(/ 1000 (:target-fps gamestate)))))
|
|
|
|
|
|
|
|
|
|
|
|
(defn init-scenes []
|
|
|
|
(defn init-scenes
|
|
|
|
|
|
|
|
"initiates the scene data maps using their respective init functions"
|
|
|
|
|
|
|
|
[]
|
|
|
|
(assoc
|
|
|
|
(assoc
|
|
|
|
gamestate
|
|
|
|
gamestate
|
|
|
|
:scenes
|
|
|
|
:scenes
|
|
|
|