Drag LMB to select tiles, draw bottom bar, wip file picker

This commit is contained in:
Joseph Ferano 2026-08-29 18:24:59 +07:00
parent 2aeda5c833
commit 6f3948d62e
2 changed files with 97 additions and 42 deletions

View File

@ -287,7 +287,6 @@
(reset! e/game-state (init-game {}))
(swap! e/game-state :assoc {})
hello
(:tilemaps @e/game-state)
:-)

View File

@ -5,32 +5,56 @@
[clojure.java.io :as io]
[engine :as e]
[rl :as rl]
[watch :as w]))
[watch :as w])
(:import (java.awt FileDialog Frame)))
(def ^:const screen-width 1280)
(def ^:const screen-height 630)
(def screen-width 1280)
(def screen-height 630)
;; (def screen-width 960)
;; (def screen-height 490)
(def cell-size 16)
(defn sprite-atlas-path []
(let [asset-path "./source-assets/Sprout Lands Premium/"
level-deco "Objects/Mushrooms, Flowers, Stones.png"]
(str asset-path level-deco)))
(defn init-sprite-atlas [config]
{:zoom 1
:atlas (e/load-texture-once :main-atlas (sprite-atlas-path))
:atlas-pos [0 0]
:drag-delta [0 0]})
(defn zoom-to-fit [{:keys [width height]}]
(min (/ screen-width (double width))
(/ screen-height (double height))))
(defn- auto-tile [game cell-size cell-count]
(assoc game :auto-tile-info {:cell-size 16 :cell-count 11}))
(defn init-sprite-atlas [config]
(let [atlas (e/load-texture-once :main-atlas (sprite-atlas-path))]
{:zoom (zoom-to-fit atlas)
:selected-cells #{}
:atlas atlas
:atlas-pos [0 0]
:drag-delta [0 0]}))
(defn handle-input [_ game]
(update-as-> [g game]
(when (rl/key-pressed? rl/key-r)
(assoc g :atlas-pos [0 0]))
;; TODO: We want to add auto sprite sheet gen, so first detect non-empty, and we populate with that
;; then we have a selection box that allows grouping
(when (rl/key-pressed? rl/key-enter)
(let [d (doto (FileDialog. (Frame.) "Open" FileDialog/LOAD)
;; TODO: Maybe add a check if the directory exists?
(.setDirectory (str (System/getProperty "user.dir") "/assets"))
(.setVisible true))]
(when-let [f (.getFile d)]
(println (str (.getDirectory d) f)))
game)
#_(this should be to write the sprite sheet to some path))
(when (rl/key-pressed? rl/key-zero)
(assoc g :zoom (zoom-to-fit (:atlas g))))
(when (rl/mouse-button-pressed? rl/mouse-button-left)
(assoc g :drag-start-pos (rl/get-mouse-position) :drag-mode :zooming))
(assoc g
:drag-start-pos (rl/get-mouse-position)
:current-mouse-pos (rl/get-mouse-position)
:drag-mode :selecting
:selected-cells #{}))
(when (rl/mouse-button-released? rl/mouse-button-left)
(-> g
(assoc :selected-sprite (get-selection-rect (:drag-start-pos g) (:current-mouse-pos g)))
@ -64,41 +88,70 @@
(handle-input {} g)
(when (contains? g :drag-start-pos)
(case (:drag-mode g)
:zooming (assoc g :current-mouse-pos (rl/get-mouse-position))
:selecting (assoc g
:current-mouse-pos (rl/get-mouse-position)
;; TODO: I have to fix this algorith, I'm pretty sure there's a way to make it O(1)
:selected-cells
(let [zoom (:zoom g)
{:keys [drag-start-pos current-mouse-pos atlas-pos]} g
{dsp-x :x dsp-y :y} drag-start-pos
{mx :x my :y} current-mouse-pos
[ax ay] atlas-pos
x0 (- (min dsp-x mx) ax)
y0 (- (min dsp-y my) ay)
x1 (- (max dsp-x mx) ax)
y1 (- (max dsp-y my) ay)
curr-cell-size (* cell-size zoom)
start-row (quot y0 curr-cell-size)
start-col (quot x0 curr-cell-size)
start-x (* start-col curr-cell-size)
start-y (* start-row curr-cell-size)
w (+ (- x0 start-x) (- x1 x0))
h (+ (- y0 start-y) (- y1 y0))
row-count (inc (quot h curr-cell-size))
col-count (inc (quot w curr-cell-size))]
(w/spy :info [row-count col-count])
(when (> (* w h) 256)
(set (for [r (range row-count)
c (range col-count)]
[(+ start-row r) (+ start-col c)])))))
:dragging (assoc g :drag-delta (let [{mx :x my :y} (rl/get-mouse-position)
{:keys [x y]} (:drag-start-pos g)]
[(- mx x) (- my y)]))))))
(swap! e/game-state assoc :atlas-pos [0 0])
(defn draw-sprite-atlas [_ {:keys [atlas atlas-pos drag-delta zoom drag-start current-mouse-pos selected-sprite auto-tile-info]}]
(defn draw-sprite-atlas [_ {:keys [atlas atlas-pos drag-delta zoom drag-mode drag-start-pos current-mouse-pos selected-cells]}]
(rl/clear-background!* rl/black)
(let [current-scale (* (/ screen-height (:height atlas)) (max 0.1 (* zoom 0.1)))
[ax ay] atlas-pos
(let [[ax ay] atlas-pos
[dx dy] (or drag-delta [0 0])
ax (+ ax dx)
ay (+ ay dy)]
ay (+ ay dy)
curr-cell-size (* cell-size zoom)]
(when atlas
(let []
(rl/draw-texture-ex!* (:seg atlas) (rl/vec2-seg ax ay) 0.0 current-scale rl/white))
(when drag-start
(let [start-x (:x drag-start)
start-y (:y drag-start)
(rl/draw-texture-ex!* (:seg atlas) (rl/vec2-seg ax ay) 0.0 zoom rl/white))
(when (= :selecting drag-mode)
(let [start-x (:x drag-start-pos)
start-y (:y drag-start-pos)
end-x (:x current-mouse-pos)
end-y (:y current-mouse-pos)]
(rl/draw-rectangle-lines!* start-x start-y (- end-x start-x) (- end-y start-y) rl/white)))
#_(when selected-sprite
(let [{:keys [x y w h]} selected-sprite]
(rl/draw-texture-rec!* (:seg atlas) (rl/rect-seg x y w h) (rl/vec2-seg 30 30) rl/white)))
(let [cell-size 16
rows 11
cols 12]
(let [{:keys [x y w h]} selected-sprite]
(rl/draw-texture-rec!* (:seg atlas) (rl/rect-seg x y w h) (rl/vec2-seg 30 30) rl/white)))
(let [rows (quot (:height atlas) cell-size)
cols (quot (:width atlas) cell-size)]
(doseq [row (range rows)
col (range cols)]
(rl/draw-rectangle-lines!* (+ ax (* col cell-size current-scale))
(+ ay (* row cell-size current-scale))
(* cell-size current-scale)
(* cell-size current-scale)
rl/gray)))))
(rl/draw-rectangle-lines!* (+ ax (* col curr-cell-size))
(+ ay (* row curr-cell-size))
curr-cell-size
curr-cell-size
rl/gray)))
(doseq [[row col] selected-cells]
(rl/draw-rectangle-lines!* (+ ax (* col curr-cell-size)) (+ ay (* row curr-cell-size))
(* cell-size zoom) (* cell-size zoom)
rl/white))))
(let [font-size 28
width (quot screen-width 2)
height 30
@ -110,26 +163,29 @@
(rl/draw-text!* (format "Y: %d" (int my)) (+ x 150) y font-size rl/black)))
(defn watch-sprite-atlas [config game]
{:zoom (:zoom game)
{#_#_:zoom (:zoom game)
:selected-cells (:selected-cells game)
:mouse-pos (:current-mouse-pos game)
:atlas-pos (:atlas-pos game)
:drag-delta (:drag-delta game)})
#_#_:drag-delta (:drag-delta game)})
(defn unload-sprite-atlas [game]
(rl/unload-texture! (:atlas game)))
(defn -main [& _args]
(engine/run-game!
{:title "Sprite Atlas"
:width screen-width
:height screen-height
:init #'init-sprite-atlas
:update #'update-sprite-atlas
:draw #'draw-sprite-atlas
:unload #'unload-sprite-atlas
:watch-fn #'watch-sprite-atlas}))
{:title "Sprite Atlas"
:width screen-width
:height screen-height
:init #'init-sprite-atlas
:update #'update-sprite-atlas
:draw #'draw-sprite-atlas
:unload #'unload-sprite-atlas
:watch-fn #'watch-sprite-atlas}))
(comment
(future (-main))
(reset! e/game-state (init-sprite-atlas {}))
(rl/set-clipboard-text!* "foo bar")
(swap! e/game-state assoc :atlas-pos [0 0])
:-)