You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.0 KiB

(ns topdown2d.core
(:require [topdown2d.demoscene]))
(def gamestate {
:canvas (.getElementById js/document "gamecanvas")
:2d (.getContext (.getElementById js/document "gamecanvas") "2d")
:timing {
:prev 0
:now 0
:fps 0
}
:scene :demo
:scenes {
:demo {
:update topdown2d.demoscene/update
:draw topdown2d.demoscene/draw
:data {}
}
}
})
(aset (:2d gamestate) "font" "10px monospace")
(def keysdown (atom []))
(defn keydown? [keycode]
(some #{keycode} @keysdown))
(.addEventListener js/document
"keydown"
(fn [event]
(let [code (symbol (.-code event))]
(swap! keysdown #(set (conj %1 code))))))
(.addEventListener js/document
"keyup"
(fn [event]
(let [code (symbol (.-code event))]
(swap! keysdown
(fn [coll]
(remove #(= % code) coll))))))
(defn set-timing [state timingkey]
(update-in state
[:timing timingkey]
#(.now js/performance)))
(defn set-fps [state]
(let [newstate (set-timing state :now)
now (get-in newstate [:timing :now])
prev (get-in newstate [:timing :prev])
duration (- now prev)
fps (/ 1000 duration)]
(update-in newstate [:timing :fps] (fn [] fps))))
(defn update-scene [gamestate]
(let [scenekey (:scene gamestate)
scenedata (get-in gamestate [:scenes scenekey])
updatefunc (:update scenedata)
newdata (updatefunc gamestate scenedata)]
(update-in gamestate [:scenes scenekey] (fn [] newdata))))
(defn update-step [gamestate]
(-> gamestate
(set-fps)
(set-timing :prev)
(update-scene)))
(defn draw-step [gamestate]
(.clearRect (:2d gamestate) 0 0 400 600)
(.fillText
(:2d gamestate)
(int (get-in gamestate [:timing :fps]))
0 10))
(defn mainloop [gamestate]
(let [newstate (update-step gamestate)]
(draw-step newstate)
(.setTimeout js/window
(fn []
(.requestAnimationFrame js/window
#(mainloop newstate)))
(/ 1000 30))))
(mainloop gamestate)