diff --git a/src/sprite_atlas.clj b/src/sprite_atlas.clj index b466fce..f1489c8 100644 --- a/src/sprite_atlas.clj +++ b/src/sprite_atlas.clj @@ -1,48 +1,56 @@ (ns sprite-atlas + (:use + [util]) (:require [clojure.java.io :as io] - [engine] - [rl :as rl])) + [engine :as e] + [rl :as rl] + [watch :as w])) -(def screen-width 1250) -(def screen-height 780) +(def ^:const screen-width 1280) +(def ^:const screen-height 630) -(defonce state (atom {})) - -;; (defn tile-source [game] -;; {:x -;; :y -;; :width -;; :height -;; :name }) +(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] - (let [path (:sprite-path @state)] - (-> (if (.exists (io/file path)) - {:atlas (rl/load-texture path)} - {}) - (assoc :zoom 1)))) + {:zoom 1 + :atlas (e/load-texture-once :main-atlas (sprite-atlas-path)) + :atlas-pos [0 0] + :drag-delta [0 0]}) (defn- auto-tile [game cell-size cell-count] (assoc game :auto-tile-info {:cell-size 16 :cell-count 11})) -(defn handle-sprite-atlas-input [_ game] - (let [game (cond-> game - (rl/mouse-button-pressed? rl/mouse-button-left) - (assoc :drag-start (rl/get-mouse-position)) +(defn handle-input [_ game] + (update-as-> [g game] + (when (rl/key-pressed? rl/key-r) + (assoc g :atlas-pos [0 0])) - (rl/mouse-button-released? rl/mouse-button-left) - (assoc :event-drag-ended true) - - :always - (as-> g (cond-> g - (contains? g :drag-start) - (assoc :current-mouse-pos (rl/get-mouse-position))))) - move (rl/get-mouse-wheel-move) - game (cond-> game - (not (zero? move)) - (update :zoom #(+ % move)))] - game)) + (when (rl/mouse-button-pressed? rl/mouse-button-left) + (assoc g :drag-start-pos (rl/get-mouse-position) :drag-mode :zooming)) + (when (rl/mouse-button-released? rl/mouse-button-left) + (-> g + (assoc :selected-sprite (get-selection-rect (:drag-start-pos g) (:current-mouse-pos g))) + (dissoc :drag-start-pos :current-mouse-pos :drag-mode))) + (when (rl/mouse-button-pressed? rl/mouse-button-right) + (assoc g :drag-start-pos (rl/get-mouse-position) :drag-mode :dragging :drag-delta [0 0])) + (when (rl/mouse-button-released? rl/mouse-button-right) + (-> g + (assoc :atlas-pos (let [[dx dy] (:drag-delta g) + [ax ay] (:atlas-pos g)] + [(+ ax dx) (+ ay dy)])) + (dissoc :drag-start-pos :current-mouse-pos :drag-mode :drag-delta))) + (let [move (rl/get-mouse-wheel-move)] + (when (not (zero? move)) + (let [new-scale (max 1.0 ((if (pos? move) * /) (:zoom g) 1.2)) + [ax ay] (:atlas-pos g) + {mx :x my :y} (rl/get-mouse-position) + k (/ new-scale (:zoom g))] + (assoc g :zoom new-scale :atlas-pos [(- mx (* k (- mx ax))) + (- my (* k (- my ay)))])))))) (defn- get-selection-rect [{ax :x ay :y} {bx :x by :y}] (let [start-x (min ax bx) @@ -52,16 +60,26 @@ {:x start-x :y start-y :w (- end-x start-x) :h (- end-y start-y)})) (defn update-sprite-atlas [_ game] - (cond-> game - (contains? game :event-drag-ended) - (-> (assoc :selected-sprite (get-selection-rect (:drag-start game) (:current-mouse-pos game))) - (dissoc :event-drag-ended :drag-start :current-mouse-pos)))) + (update-as-> [g game] + (handle-input {} g) + (when (contains? g :drag-start-pos) + (case (:drag-mode g) + :zooming (assoc g :current-mouse-pos (rl/get-mouse-position)) + :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 zoom drag-start current-mouse-pos selected-sprite auto-tile-info]}] +(defn draw-sprite-atlas [_ {:keys [atlas atlas-pos drag-delta zoom drag-start current-mouse-pos selected-sprite auto-tile-info]}] (rl/clear-background!* rl/black) - (let [current-scale (* (/ screen-height (:height atlas)) (max 0.1 (* zoom 0.1)))] + (let [current-scale (* (/ screen-height (:height atlas)) (max 0.1 (* zoom 0.1))) + [ax ay] atlas-pos + [dx dy] (or drag-delta [0 0]) + ax (+ ax dx) + ay (+ ay dy)] (when atlas - (rl/draw-texture-ex!* (:seg atlas) (rl/vec2-seg 0 0) 0.0 current-scale rl/white) + (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) @@ -76,31 +94,42 @@ cols 12] (doseq [row (range rows) col (range cols)] - (rl/draw-rectangle-lines!* (* col cell-size current-scale) - (* row cell-size current-scale) + (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/gray))))) + (let [font-size 28 + width (quot screen-width 2) + height 30 + x width + y (- screen-height height) + {mx :x my :y} (rl/get-mouse-position)] + (rl/draw-rectangle!* x y width height rl/white) + (rl/draw-text!* (format " X: %d" (int mx)) x y font-size rl/black) + (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) + :atlas-pos (:atlas-pos game) + :drag-delta (:drag-delta game)}) (defn unload-sprite-atlas [game] (rl/unload-texture! (:atlas game))) -(defn -main [& sprite-path] - (swap! state assoc :sprite-path (first sprite-path)) +(defn -main [& _args] (engine/run-game! {:title "Sprite Atlas" :width screen-width :height screen-height :init #'init-sprite-atlas - :input #'handle-sprite-atlas-input :update #'update-sprite-atlas :draw #'draw-sprite-atlas :unload #'unload-sprite-atlas :watch-fn #'watch-sprite-atlas})) (comment - (future (-main "source-assets/Sprout Lands - Sprites - premium pack/Sprout Lands - Sprites - premium pack/Tilesets/ground tiles/New tiles/Grass_tiles_v2.png")) + (future (-main)) + (reset! e/game-state (init-sprite-atlas {})) + (rl/set-clipboard-text!* "foo bar") :-)