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.

99 lines
3.4 KiB

(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)))