WIP Manually place tiles with a tilemap palette

This commit is contained in:
Joseph Ferano 2026-09-05 09:56:18 +07:00
parent 8eb9a8b7f9
commit a2f53900f9

View File

@ -8,8 +8,8 @@
[clojure.edn :as edn]
[rl :as rl]))
(def ^:const screen-width 1280)
(def ^:const screen-height 630)
(def screen-width 1280)
(def screen-height 630)
;; (def ^:const screen-width 970)
;; (def ^:const screen-height 530)
(def ^:const cell-size 16)
@ -19,6 +19,7 @@
(def scale 4.0)
(def num-layers 5)
(def ^:const stride 3)
(set! *warn-on-reflection* true)
;; (set! *unchecked-math* :warn-on-boxed)
@ -27,10 +28,24 @@
(def color-ground (rl/color-seg 0xE8CFA6))
(def color-tint-gray (rl/color-seg 0 0 0 100))
(defn idx [row col] (+ (* row cols) col))
(defn tile-at [game layer r c] (aget ^objects (get (:layers game) layer) (idx r c)))
(defn tile-at-idx [game layer idx] (aget ^objects (get (:layers game) layer) idx))
(defn set-tile! [game layer r c tile] (aset ^objects (get (:layers game) layer) (idx r c) tile))
(defn idx [row col] (* (+ (* row cols) col) stride))
(defn tile-at [game layer r c]
(let [grid ^ints (e/cells (get (:layers game) layer))
i (idx r c)]
[(aget grid i) (aget grid (+ i 1)) (aget grid (+ i 2))]))
(defn tile-at-idx [game layer i]
(let [grid ^ints (e/cells (get (:layers game) layer))]
[(aget grid i) (aget grid (+ i 1)) (aget grid (+ i 2))]))
(defn set-tile! [game layer atlas-id tr tc cr cc]
(let [i (idx cr cc)]
(doto ^ints (e/cells (get (:layers game) layer))
(aset i (int atlas-id))
(aset (+ i 1) (int tr))
(aset (+ i 2) (int tc)))))
(defn cell-at-mouse-pos [game]
(let [{mx :x my :y} (rl/get-mouse-position)
row (quot my (* cell-size scale))
@ -41,11 +56,10 @@
(let [tileset-path "./source-assets/Sprout Lands Premium/Tilesets/ground tiles/New tiles/"]
{:editor-mode false
:color-idx 0
;; :event-queue []
;; TODO: Once we have a proper ID system for the cells, use int-array for performance
:layers (vec (repeatedly num-layers #(object-array (* rows cols))))
:layers (vec (repeatedly num-layers #(e/make-int-grid (* rows cols stride) -1)))
:current-layer 0
:current-tilemap 0
:selected-tile [-1 -1 -1]
:atlases
;; (edn/read-string (slurp "./assets/Mushrooms, Flowers, Stones.edn"))
(let [path "./assets/Mushrooms, Flowers, Stones.edn"
@ -159,9 +173,12 @@
(defn set-random-tile! [game layer row col]
(let [tile (edge-set (tile-bitset game layer row col))
tilemap (get (:tilemaps game) (:current-tilemap game))]
(if (vector? tile)
(set-tile! game layer row col [tilemap tile])
atlas-id (:current-tilemap game)
tilemap (get (:tilemaps game) atlas-id)]
(set-tile! game layer atlas-id row col #_[tilemap tile])
#_(if (vector? tile)
(set-tile! game layer atlas-id row col #_[tilemap tile])
;; TODO: This is still calling the old API
(set-tile! game layer row col
(reduce (fn [acc [tile weight]]
(if (< acc weight) (reduced [tilemap tile]) (- acc weight)))
@ -185,18 +202,12 @@
;; (when (contains? (:tags tile) :randomized)
(defn set-tile2! [game layer row col tile]
)
(defn handle-game-input [config game]
(update-as-> [g game]
(assoc g :event-queue [])
(when (not (:editor-mode game))
(cond-> g
(rl/key-pressed? rl/key-space)
(update :editor-mode not)
;; (rl/key-pressed? rl/key-r)
;; (assoc :layers (object-array (* rows cols)))
@ -210,12 +221,15 @@
(rl/mouse-button-released? rl/mouse-button-right))
(dissoc :drag-mode)))
(when (rl/key-pressed? rl/key-space)
(update g :editor-mode not))
#_(when (and (:editor-mode game)
(rl/mouse-button-pressed? rl/mouse-button-left))
(let [{mx :x my :y} (rl/get-mouse-position)]
(doseq)))
(when (rl/mouse-button-pressed? rl/mouse-button-middle)
#_(when (rl/mouse-button-pressed? rl/mouse-button-middle)
(do-grid [r 10 c 20]
(auto-tile! g r c)))
@ -244,12 +258,19 @@
(when (and existing (= mode :erase))
(delete-tile! game (:current-layer game) row col))
(when (and (= mode :draw)
(not= -1 (first (:selected-tile game)))
(not= (cell-at-mouse-pos game) (:last-filled-cell game)))
(let [[atlas-id tr tc] (:selected-tile game)]
(set-tile! game (:current-layer game) atlas-id tr tc row col))
(assoc game :last-filled-cell [row col]))
;; TODO: Add single vs auto mode
#_(when (and (= mode :draw)
(not= (cell-at-mouse-pos game) (:last-filled-cell game)))
(auto-tile! game (:current-layer game) row col)
(assoc game :last-filled-cell [row col]))))))
(defn draw-tile! [game tilemap row-idx col-idx x y scale]
(let [src-rect (rl/rect-seg (* col-idx cell-size) (* row-idx cell-size) cell-size cell-size)
(defn draw-tile! [game tilemap row col x y scale]
(let [src-rect (rl/rect-seg (* col cell-size) (* row cell-size) cell-size cell-size)
dst-x (* (quot x (* cell-size scale)) cell-size scale)
dst-y (* (quot y (* cell-size scale)) cell-size scale)
dst-rect (rl/rect-seg dst-x dst-y (* cell-size scale) (* cell-size scale))]
@ -258,14 +279,18 @@
(defn draw-game [config game]
(rl/clear-background!* color-ground)
(dotimes [layer num-layers]
(do-grid [row rows col cols]
(when-let [[tilemap [tx ty]] (tile-at game layer row col)]
(draw-tile! game tilemap tx ty (* col cell-size scale) (* row cell-size scale) scale))))
(when (and (not (contains? game :draw-drag))
(do-grid [cr rows cc cols]
(let [[aid tr tc] (tile-at game layer cr cc)]
(when (and (not= aid -1)
(get (:atlases game) aid))
(draw-tile! game (second (get (:atlases game) aid)) tr tc (* cc cell-size scale) (* cr cell-size scale) scale)))))
#_(when (and (not= (first (:selected-tile game)) -1)
(not (contains? game :draw-drag))
(not (:editor-mode game)))
(let [{mx :x my :y :as mouse-pos} (rl/get-mouse-position)]
(let [{mx :x my :y :as mouse-pos} (rl/get-mouse-position)
[aid tr tc] (:selected-tile game)]
;; TODO: Maybe better if we create a get-tilemap-by-name
(draw-tile! game (get (:tilemaps game) 0) 3 3 mx my scale)))
(draw-tile! game (second (get (:atlases game) aid)) tr tc mx my scale)))
#_(rl/draw-texture-pro!* (:seg (:bush (:tilemaps game)))
(rl/rect-seg 0 0 54 35)
(rl/rect-seg 600 180 (* 54 2) (* 35 2))
@ -293,7 +318,8 @@
(when (rl/collision-point-rec? mouse-pos {:x pos-x :y pos-y :width curr-size :height curr-size})
(rl/draw-rectangle-lines!* pos-x pos-y curr-size curr-size rl/green)
(when (rl/mouse-button-pressed? rl/mouse-button-left)
(swap! e/game-state assoc :selected-tile [r c])
;; TODO: For the love of god fix this
(swap! e/game-state assoc :selected-tile [(:current-tilemap game) r c])
(swap! e/game-state dissoc :editor-mode))))))
#_(doseq [[idx [k {:keys [width height seg]}]] (into [] (map-indexed vector) (:tilemaps game))
:let [padding 10]]
@ -326,7 +352,8 @@
(future (-main))
;; TODO: I hate this, terrible way to read game state, maybe pass an atom in?
(reset! e/game-state (init-game {}))
(swap! e/game-state :assoc {})
(swap! e/game-state :assoc :selected-tile [0 0 6])
e/game-state
(:tilemaps @e/game-state)