diff --git a/src/cljs/topdown2d/core.cljs b/src/cljs/topdown2d/core.cljs index 1fb108f..7815f53 100644 --- a/src/cljs/topdown2d/core.cljs +++ b/src/cljs/topdown2d/core.cljs @@ -8,10 +8,12 @@ (def gamestate { :canvas (.getElementById js/document "gamecanvas") :2d (.getContext (.getElementById js/document "gamecanvas") "2d") + :target-fps 30 :timing { :prev 0 :now 0 :fps 0 + :elapsed 0 } :dimensions { :w 600 @@ -31,17 +33,23 @@ (aset (:2d gamestate) "font" "10px monospace") (defn set-timing [state timingkey] - (update-in state + (assoc-in state [:timing timingkey] - #(.now js/performance))) + (.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)))) + (let [elapsed (get-in state [:timing :elapsed]) + fps (/ 1 elapsed)] + (assoc-in state [:timing :fps] fps))) + +(defn set-elapsed-seconds [gamestate] + (assoc-in gamestate + [:timing :elapsed] + (/ + (- + (get-in gamestate [:timing :now]) + (get-in gamestate [:timing :prev])) + 1000))) (defn update-scene [gamestate] (let [scenekey (:scene gamestate) @@ -52,9 +60,11 @@ (defn update-step [gamestate] (-> gamestate + (set-timing :now) + (set-elapsed-seconds) (set-fps) - (set-timing :prev) - (update-scene))) + (update-scene) + (set-timing :prev))) (defn draw-step [gamestate] (.clearRect (:2d gamestate) @@ -77,7 +87,7 @@ (fn [] (.requestAnimationFrame js/window #(mainloop newstate))) - (/ 1000 30)))) + (/ 1000 (:target-fps gamestate))))) (defn init-scenes [] (assoc diff --git a/src/cljs/topdown2d/demoscene.cljs b/src/cljs/topdown2d/demoscene.cljs index 4c50d2d..305f6e9 100644 --- a/src/cljs/topdown2d/demoscene.cljs +++ b/src/cljs/topdown2d/demoscene.cljs @@ -13,7 +13,6 @@ :y 50 :w 10 :h 10 - :v 0 } :box { @@ -21,7 +20,7 @@ :y 5 :w 10 :h 10 - :v 5 + :pps 100 :d :? } })) @@ -30,9 +29,11 @@ (let [box (get-in scenedata [:data :box]) dir (input/dirinput) box (assoc box :d dir)] - (update-in scenedata + (assoc-in scenedata [:data :box] - #(objects/move-inside-gamestate gamestate box)))) + (objects/move-inside-gamestate + gamestate + box)))) (defn draw [gamestate scenedata] (let [{{:keys [bumper box]} :data} scenedata diff --git a/src/cljs/topdown2d/objects.cljs b/src/cljs/topdown2d/objects.cljs index d28d67c..10c677f 100644 --- a/src/cljs/topdown2d/objects.cljs +++ b/src/cljs/topdown2d/objects.cljs @@ -9,21 +9,21 @@ (< (+ x w) (+ cx cw)) (< (+ y h) (+ cy ch))))) -(defn moved-object [obj] - (let [{:keys [x y v d]} obj] +(defn moved-object [obj pxs] + (let [{:keys [x y d]} obj] (cond (= d :w) (assoc obj - :x (- x v)) + :x (- x pxs)) (= d :e) (assoc obj - :x (+ x v)) + :x (+ x pxs)) (= d :n) (assoc obj - :y (- y v)) + :y (- y pxs)) (= d :s) (assoc obj - :y (+ y v)) + :y (+ y pxs)) :else obj))) (defn bump-in-wall [obj container] @@ -36,14 +36,23 @@ :s (update obj :y #(- (+ cy ch) h 1)) :? obj))) -(defn move-inside [obj container] - (let [moved (moved-object obj)] +(defn pps->px [gamestate obj] + (let [prev (get-in gamestate [:timing :prev]) + now (get-in gamestate [:timing :now]) + secs (/ (- now prev) 1000) + pps (:pps obj)] + (* pps secs))) + +(defn move-inside [obj container pxs] + (let [moved (moved-object obj pxs)] (if (in? moved container) moved (bump-in-wall obj container)))) (defn move-inside-gamestate [gamestate obj] - (let [container (assoc (:dimensions gamestate) + (let [pxs (pps->px gamestate obj) + container (assoc + (:dimensions gamestate) :x 0 :y 0)] - (move-inside obj container))) + (move-inside obj container pxs)))