diff --git a/.dir-locals.el b/.dir-locals.el index 2351726..681edb2 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -34,6 +34,7 @@ (define-key m (kbd "C-c g r") #'clj-game-run-main) (define-key m (kbd "C-c g e") #'clj-game-clear-error) (define-key m (kbd "C-c g c") #'clj-game-reload-config) + ;; (define-key m (kbd "C-c g s") #'clj-game-reload-config) (define-key m (kbd "C-c g x") #'clj-game-throw-last-error) m))) diff --git a/src/game.clj b/src/game.clj index d50da08..66c43a6 100644 --- a/src/game.clj +++ b/src/game.clj @@ -5,15 +5,17 @@ [watch :as w] [rl :as rl])) -;; (def ^:const screen-width 1280) -;; (def ^:const screen-height 630) -(def ^:const screen-width 970) -(def ^:const screen-height 530) +(def ^:const screen-width 1280) +(def ^:const screen-height 630) +;; (def ^:const screen-width 970) +;; (def ^:const screen-height 530) (def ^:const cell-size 16) (def ^:const rows (quot screen-width cell-size)) (def ^:const cols (quot screen-height cell-size)) (def ^:const grid-len (* rows cols)) +(def scale 4.0) + (set! *warn-on-reflection* true) ;; (set! *unchecked-math* :warn-on-boxed) @@ -42,75 +44,126 @@ :grid (object-array (* rows cols)) :texture (load-texture-once "source-assets/Sprout Lands - Sprites - premium pack/Sprout Lands - Sprites - premium pack/Tilesets/ground tiles/New tiles/Grass_Hill_Tiles_v2.png")}) -(def tilemap-bitmask - {[0 0] :NW - [0 1] :N - [0 2] :NW - [1 0] :W - [1 1] :C - [1 2] :E - [2 0] :SW - [2 1] :S - [2 2] :SE}) +(def edge-set + {0 [3 3], + 70 [0 0], + 7 [4 4], + 59 [2 1], + 175 [4 5], + 27 [3 6], + 1 [2 3], + 206 [0 1], + 239 [2 5], + 4 [0 3], + 95 [4 6], + 141 [2 7], + 15 [4 8], + 159 [1 9], + 31 [3 9], + 223 [2 6], + 13 [4 7], + 191 [1 5], + 143 [2 10], + 41 [2 2], + 43 [3 5], + 6 [0 4], + 111 [0 9], + 3 [3 4], + 12 [0 7], + 2 [3 0], + 142 [0 5], + 23 [1 4], + 47 [3 10], + 127 [1 6], + 19 [2 0], + 11 [3 8], + 255 [6 5], + 9 [3 7], + 5 [1 3], + 14 [0 8], + 45 [1 7], + 78 [0 6], + 140 [0 2], + 79 [2 9], + 173 [1 2], + 87 [1 0], + 207 [2 8], + 10 [3 1], + 71 [2 4], + 63 [1 8], + 8 [3 2]}) -(def tilemap-bitmask - {[0 0 0 - 0 0 1 - 0 1 1] :NW - [0 0 0 - 1 0 1 - 1 1 1] :N - [0 0 0 - 1 0 0 - 1 1 0] :NE - [0 1 1 - 0 0 1 - 0 1 1] :W - [1 1 0 - 1 0 0 - 1 1 0] :E - [0 1 1 - 0 0 1 - 0 0 0] :SW - [1 1 1 - 1 0 1 - 0 0 0] :S - [1 1 0 - 1 0 0 - 0 0 0] :SE}) +(def directions + [[:N [-1 0]] + [:E [0 1]] + [:S [1 0]] + [:W [0 -1]] + [:NE [-1 1]] + [:NW [-1 -1]] + [:SE [1 1]] + [:SW [1 -1]]]) + +(defn normalize-mask [m] + (cond-> m + (not (and (bit-test m 0) (bit-test m 1))) (bit-clear 4) ; NE needs N+E + (not (and (bit-test m 0) (bit-test m 3))) (bit-clear 5) ; NW needs N+W + (not (and (bit-test m 2) (bit-test m 1))) (bit-clear 6) ; SE needs S+E + (not (and (bit-test m 2) (bit-test m 3))) (bit-clear 7))) ; SW needs S+W (defn surrounding-tiles [game at-row at-col] - (let [idx (idx at-row at-col)] - (persistent! - (reduce (fn [acc num] - (let [cell-idx (+ idx num)] - (println cell-idx) - (if (or (< cell-idx 0) - (>= cell-idx 9 #_grid-len) - (= num 0)) - (conj! acc 0) - (conj! acc (if (tile-at-idx game cell-idx) - 1 - 0))))) - (transient []) - (range -4 5))))) + (normalize-mask + (reduce-kv (fn [acc i [_ [dy dx]]] + (if (tile-at game (+ at-row dy) (+ at-col dx)) + (bit-set acc i) + acc)) + 0 + directions))) -(defn auto-tile []) +(defn auto-tile! [game at-row at-col] + (let [me (surrounding-tiles game at-row at-col) + north (tile-at game (dec at-row) at-col) + south (tile-at game (inc at-row) at-col) + west (tile-at game at-row (dec at-col)) + east (tile-at game at-row (inc at-col)) + tile (edge-set me)] + (println me tile) + (set-tile! game at-row at-col tile) + (when north + (set-tile! game (dec at-row) at-col (edge-set (surrounding-tiles game (dec at-row) at-col)))) + (when south + (set-tile! game (inc at-row) at-col (edge-set (surrounding-tiles game (inc at-row) at-col)))) + (when west + (set-tile! game at-row (dec at-col) (edge-set (surrounding-tiles game at-row (dec at-col))))) + (when east + (set-tile! game at-row (inc at-col) (edge-set (surrounding-tiles game at-row (inc at-col))))))) (defn handle-game-input [config game] (let [game (assoc game :event-queue [])] (when (rl/key-pressed? rl/key-r)) - (when (rl/mouse-button-pressed? rl/mouse-button-left) - (let [{mx :x my :y} (rl/get-mouse-position)] - (set-tile! game (quot my cell-size) (quot mx cell-size) [3 3]))) + (when (rl/mouse-button-pressed? rl/mouse-button-right) + (let [{mx :x my :y} (rl/get-mouse-position) + at-row (quot my (* scale cell-size)) + at-col (quot mx (* scale cell-size))] + (auto-tile! game at-row at-col) + (set-tile! game at-row at-col nil))) + (when (rl/mouse-button-pressed? rl/mouse-button-left)) (cond-> game (rl/key-pressed? rl/key-space) - (update :editor-mode not)))) + (update :editor-mode not) + + (rl/mouse-button-pressed? rl/mouse-button-left) + (assoc :draw-drag true) + + (rl/mouse-button-released? rl/mouse-button-left) + (dissoc :draw-drag)))) (defn update-game [config game] - (if (:editor-mode game) - () - ()) + (when (:draw-drag game) + (let [{mx :x my :y} (rl/get-mouse-position) + row (quot my (* cell-size scale)) + col (quot mx (* cell-size scale))] + (when-not (tile-at game row col) + (auto-tile! game row col)))) game) (defn draw-tile! [game row-idx col-idx x y scale] @@ -120,22 +173,22 @@ dst-rect (rl/rect-seg dst-x dst-y (* cell-size scale) (* cell-size scale))] (rl/draw-texture-pro!* (:seg (:texture game)) src-rect dst-rect (rl/vec2-seg 0 0) (float 0.0) rl/white))) -(def scale 4.0) (defn draw-game [config game] (rl/clear-background!* color-ground) (doseq [row (range rows) col (range cols)] (when-let [[tx ty] (tile-at game row col)] - (draw-tile! game tx ty (* col cell-size) (* row cell-size) scale))) - (let [{mx :x my :y :as mouse-pos} (rl/get-mouse-position)] - (draw-tile! game 3 3 mx my scale)) + (draw-tile! game tx ty (* col cell-size scale) (* row cell-size scale) scale))) + (when (not (contains? game :draw-drag)) + (let [{mx :x my :y :as mouse-pos} (rl/get-mouse-position)] + (draw-tile! game 3 3 mx my scale))) (when (:editor-mode game) (rl/draw-rectangle!* 0 0 screen-width screen-height color-tint-gray) (rl/draw-rectangle!* (/ screen-width 2) (/ screen-height 2) 100 100 rl/white) (rl/draw-text!* "EDIT MODE" (- screen-width 100) 10 16 rl/green))) (defn watch-game [config game] - {:color-idx (:color-idx game)}) + {}) (defn unload-game [game] (rl/unload-texture! (:texture game)) @@ -158,4 +211,5 @@ (future (-main)) (reset! @#'engine/game-state (init-game {})) (swap! @#'engine/game-state :assoc {}) + (set-tile! @@#'engine/game-state 1 1 [2 2]) :-) diff --git a/src/tilemap_blob.clj b/src/tilemap_blob.clj new file mode 100644 index 0000000..3c32f80 --- /dev/null +++ b/src/tilemap_blob.clj @@ -0,0 +1,92 @@ +(ns tilemap-blob + (:import + [javax.imageio ImageIO] + [java.io File] + [java.awt.image BufferedImage])) + +(def img-path + "source-assets/Sprout Lands - Sprites - premium pack/Sprout Lands - Sprites - premium pack/Tilesets/ground tiles/New tiles/Grass_Hill_Tiles_v2.png") + + +(def img (ImageIO/read (File. img-path))) + +(.getRGB img 100 100) + +(class img) +(def buf (let [w (.getWidth img) + h (.getHeight img)] + (.getRGB img 0 0 w h nil 0 w))) + +(defn tile-subimages [^BufferedImage img tile-size] + (let [rows (quot (.getHeight img) tile-size) + cols (quot (.getWidth img) tile-size)] + (vec (for [r (range rows) + c (range cols)] + (.getSubimage img (* c tile-size) (* r tile-size) tile-size tile-size))))) + +(def tile-size 16) + +(def tiles (tile-subimages img tile-size)) + +(def ref-colors #{(unchecked-int 0xFFC0D470) (unchecked-int 0xFFA4C263)}) + +#_(= (.getRGB (get tiles 0) 15 15) ref-color) + +(def edges + (let [half (dec (quot tile-size 2)) + full (dec tile-size)] + [[:N [half 0]] + [:E [full half]] + [:S [half full]] + [:W [0 half]] + [:NE [full 0]] + [:NW [0 0]] + [:SE [full full]] + [:SW [0 full]]])) + +(defn tile-directions [tile] + (reduce (fn [acc [k [x y]]] + (if (contains? ref-colors (.getRGB tile x y)) + (conj acc k) + acc)) + [] + edges)) + +(tile-directions (get tiles (+ (* 3 11) 2))) + +(defn scale [^BufferedImage src n] + (let [w (* n (.getWidth src)) h (* n (.getHeight src)) + out (BufferedImage. w h BufferedImage/TYPE_INT_ARGB) + g (.createGraphics out)] + (.setRenderingHint g java.awt.RenderingHints/KEY_INTERPOLATION + java.awt.RenderingHints/VALUE_INTERPOLATION_NEAREST_NEIGHBOR) + (.drawImage g src 0 0 w h nil) + (.dispose g) + out)) + +(scale (get tiles (+ (* 3 11) 2)) 32) + +(partition 11 (mapv tile-directions tiles)) + + +(defn tile-bitmask [tile] + (reduce-kv (fn [acc i [_ [x y]]] + (if (contains? ref-colors (.getRGB tile x y)) + (bit-set acc i) + acc)) + 0 + edges)) + +(mapv tile-bitmask tiles) + +(into {} (map-indexed (fn [i t] + [(tile-bitmask t) + ((juxt quot rem) i (quot (.getWidth img) tile-size))])) + tiles) + +(comment + ;; #C0D470 + ;; #A4C263 + ;; #78A158 + ;; rgb(192, 212, 112) + :-)