(ns topdown2d.demoscene (:require [topdown2d.collision :as collision] [topdown2d.input :as input] [topdown2d.sprites :as sprites] [topdown2d.dom :refer [by-id]] [topdown2d.tileset :as tileset] [clojure.walk :as walk])) (def map-def (atom nil)) (defn init [gamestate scenestate] (-> (.fetch js/window "map/map.json") (.then #(.json %)) (.then #(reset! map-def (js->clj %)))) (merge scenestate {:map-def {:images {:pokelike (by-id "demoscene-tileset")} :def nil :zoom 3} :player {:x (/ (get-in gamestate [:dimensions :w]) 2) :y (/ (get-in gamestate [:dimensions :h]) 2) :w 0 :h 0 :d :s :animation {:ids {:s 778 :n 778 :e 819 :w 819} :last-cycle 0 :curr-id 778 :tileset :pokelike}} :viewport {:keep-in {:x 0 :y 0 :w 0 :h 0} :tileset :pokelike :x 6 :y 9 :w (get-in gamestate [:dimensions :w]) :h (get-in gamestate [:dimensions :h]) :d :? ;; pixels per second :pps 150}})) (defn update-player [gamestate player dir] (let [old-dir (:d player) new-dir (if (= :? dir) old-dir dir)] (as-> player p (assoc p :d new-dir) (if (= :? dir) (sprites/reset player) (sprites/proc gamestate p))))) (defn update-viewport [gamestate viewport dir] (collision/move-inside (assoc viewport :d dir) (:keep-in viewport) (collision/pps->px gamestate viewport))) (defn init-map-def [scenestate] (if (and (not (get-in scenestate [:map-def :def])) (some? @map-def)) (let [loaded-def (walk/keywordize-keys @map-def) zoom (get-in scenestate [:map-def :zoom]) {mw :width mh :height tw :tilewidth th :tileheight} loaded-def] (-> scenestate (assoc-in [:map-def :def] loaded-def) (update-in [:map-def :def] (partial tileset/prepare-map-def zoom)) (assoc-in [:viewport :keep-in :w] (* (dec mw) zoom tw)) (assoc-in [:viewport :keep-in :h] (* (dec mh) zoom th)) (update-in [:viewport :x] * tw zoom) (update-in [:viewport :y] * th zoom) (assoc-in [:player :w] (- tw 2)) (assoc-in [:player :h] (- th 2)) (update-in [:player :w] - (/ tw 2)) (update-in [:player :h] - (/ th 2)))) scenestate)) (defn update-scene [gamestate scenestate] (let [new-scenestate (init-map-def scenestate) player (:player new-scenestate) viewport (:viewport new-scenestate) dir (get-in gamestate [:input :dir])] (assoc new-scenestate :player (update-player gamestate player dir) :viewport (update-viewport gamestate viewport dir)))) (defn draw-scene [gamestate scenestate] (let [viewport (:viewport scenestate) {:keys [x y w h background]} viewport] (when (get-in scenestate [:map-def :def]) (tileset/draw-viewport (:map-def scenestate) (:ctx gamestate) viewport)) #_(.drawImage (:ctx gamestate) (:image viewport) x y w h 0 0 w h)) #_ (sprites/draw (:ctx gamestate) (:player scenestate)))