diff --git a/src/hottub/core.clj b/src/hottub/core.clj index b29c5f8..2527b27 100644 --- a/src/hottub/core.clj +++ b/src/hottub/core.clj @@ -3,33 +3,74 @@ [hottub.gs :as gs] [hottub.resource :as res] [hottub.timeline :as tln] - [hottub.screen :as scr])) + [hottub.screen :as scr] + [hottub.util :as u])) (defn -main [& args] (res/start-resource-expiry-thread) (slick/start-game "Test game" {:id :game})) (defmethod scr/screen-from-spec :game [spec] - {:gs (gs/update-gs gs/gs-empty - (gs/add-index :name) - (gs/add-index :type) - (gs/set-entity (gs/gen-id) {:type :sprite :x 50 :y 50 - :image "res/man.png" :name :man}))}) + {:tln (tln/timeline-insert (tln/timeline-create) 0 + (gs/update-gs gs/gs-empty + (gs/add-index :name) + (gs/add-index :type) + (gs/set-entity (gs/gen-id) {:type :sprite :x 50 :y 50 + :image "res/man.png" :name :man}))) + :timestamp-last (u/timestamp)}) -(defmethod scr/spec-from-screen :game [screen] {:id :game}) +(defn update-gs [input] + (let [man (first (gs/q :name :man))] + (gs/update-entity (assoc man :x (:mousex input) :y (:mousey input))))) -(defmethod slick/update-game :game [state inputtln delta] - (assoc state :gs (gs/update-gs (:gs state) - (if-let [input (tln/timeline-last-value inputtln)] - (let [man (first (gs/q :name :man))] - (gs/update-entity (assoc man :x (:mousex input) :y (:mousey input)))))))) - -(defmethod slick/render-game :game [state graphics] - (gs/with-gs (:gs state) +(defn render-gs [gs] + (gs/with-gs gs (doseq [sprite (gs/q :type :sprite)] (if-let [image (res/get-image (:image sprite))] (.draw image (:x sprite) (:y sprite)))))) +(defmethod slick/update-game :game [screen inputtln delta] + (if-let [input (tln/timeline-last-value inputtln)] + (if (contains? (:keys input) ",") + (scr/push-modal-screen screen + {:id :timeshift + :ts (-> (:tln screen) last key)}) + + (let [ts (u/timestamp) + screentslast (-> (:tln screen) last key) + screents (+ screentslast (- ts (:timestamp-last screen))) + tln (:tln screen) + gslast (tln/timeline-last-value tln) + gsnext (gs/update-gs gslast (update-gs input)) + tlnnext (tln/timeline-insert tln screents gsnext) + screennext (assoc screen :timestamp-last ts :tln tlnnext)] + (scr/update-screen screen screennext))))) + +(defmethod slick/render-game :game [screen graphics] + (render-gs (tln/timeline-last-value (:tln screen)))) + +(defmethod slick/update-game :timeshift [screen inputtln delta] + (let [input-from-tln (tln/timeline-last-value inputtln) + input-from-screen (:input screen) + input (or input-from-tln input-from-screen) + keys (:keys input)] + (if (contains? keys " ") + (scr/pop-modal-screen screen) + (let [ts (:ts screen) + ts (cond + (contains? keys ",") (- ts delta) + (contains? keys ".") (+ ts delta) + :else ts) + screennext (assoc screen :ts ts :input input)] + (scr/update-screen screen screennext))))) + +(defmethod slick/render-game :timeshift [screen graphics] + (let [subscreen (scr/screen-behind-modal screen) + tln (:tln subscreen) + ts (tln/time-nearest tln (:ts screen)) + gs (last (get tln ts))] + (render-gs gs))) + ;;; repl helpers (def ^:dynamic g nil) (def ^:dynamic s nil) @@ -40,4 +81,4 @@ (defmethod slick/eval-with-bindings :default [state game f] (binding [g game s state *newscreen* (atom nil)] (let [gsnew (gs/update-gs (:gs state) (f))] - (slick/game-setstate! game (or @*newscreen* (assoc state :gs gsnew)))))) + (slick/game-setscreen! game (or @*newscreen* (assoc state :gs gsnew))))))