From a2f53900f948b7d09da6c646320833ddb9910bdf Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sat, 5 Sep 2026 09:56:18 +0700 Subject: [PATCH] WIP Manually place tiles with a tilemap palette --- src/game.clj | 85 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 29 deletions(-) diff --git a/src/game.clj b/src/game.clj index 2ac96a4..6b69a0f 100644 --- a/src/game.clj +++ b/src/game.clj @@ -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)