(ns play-clj.g2d (:require [play-clj.entities] [play-clj.utils :as u]) (:import [com.badlogic.gdx Files Gdx] [com.badlogic.gdx.files FileHandle] [com.badlogic.gdx.graphics Pixmap Texture] [com.badlogic.gdx.graphics.g2d Animation BitmapFont NinePatch ParticleEffect TextureAtlas TextureRegion] [play_clj.entities TextureEntity NinePatchEntity ParticleEffectEntity])) (defn bitmap-font* [path] (if (nil? path) (BitmapFont.) (let [^Files files (Gdx/files) ^FileHandle fh (if (string? path) (.internal files path) path)] (or (u/load-asset (.path fh) BitmapFont) (BitmapFont. fh))))) (defmacro bitmap-font "Returns a [BitmapFont](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/BitmapFont.html). (bitmap-font) (bitmap-font \"default.fnt\")" [& [path & options]] `(let [^BitmapFont object# (bitmap-font* ~path)] (u/calls! object# ~@options))) (defmacro bitmap-font! "Calls a single method on a `bitmap-font`." [object k & options] `(u/call! ^BitmapFont ~object ~k ~@options)) ; texture (defn texture* [arg] (TextureEntity. (cond (string? arg) (-> (or (u/load-asset arg Texture) (Texture. ^String arg)) TextureRegion.) (isa? (type arg) Pixmap) (-> ^Pixmap arg Texture. TextureRegion.) (isa? (type arg) Texture) (-> ^Texture arg TextureRegion.) (isa? (type arg) TextureEntity) (-> ^TextureRegion (:object arg) TextureRegion.) :else arg))) (defmacro texture "Returns an entity based on [TextureRegion](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/TextureRegion.html). ; load image.png (texture \"image.png\") ; load image.png, flip it, and only display the specified region (texture \"image.png\" :flip true false :set-region 0 0 100 100) ; create a new texture based on an existing one (texture (texture \"image.png\")) ; rotate a texture 45 degress (assoc (texture \"image.png\") :angle 45)" [arg & options] `(let [entity# (texture* ~arg)] (u/calls! ^TextureRegion (u/get-obj entity# :object) ~@options) entity#)) (defmacro texture! "Calls a single method on a `texture`. (texture! entity :flip true false) (texture! entity :get-region-width)" [entity k & options] `(u/call! ^TextureRegion (u/get-obj ~entity :object) ~k ~@options)) (defn texture? "Returns true if `entity` is a `texture`." [entity] (isa? (type (u/get-obj entity :object)) TextureRegion)) ; nine-patch (defn nine-patch* [arg] (NinePatchEntity. (cond (string? arg) (-> (or (u/load-asset arg Texture) (Texture. ^String arg)) TextureRegion. NinePatch.) (isa? (type arg) NinePatchEntity) (NinePatch. (:object arg)) (map? arg) (let [{:keys [region left right top bottom]} arg] (NinePatch. region left right top bottom)) :else arg))) (defmacro nine-patch "Returns an entity based on [NinePatch](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/NinePatch.html). (nine-patch \"image.png\") (nine-patch \"image.png\" :set-color (color :blue))" [arg & options] `(let [entity# (nine-patch* ~arg)] (u/calls! ^NinePatch (u/get-obj entity# :object) ~@options) entity#)) (defmacro nine-patch! "Calls a single method on a `nine-patch`. (nine-patch! entity :set-color (color :blue)) (nine-patch! entity :get-middle-width)" [entity k & options] `(u/call! ^NinePatch (u/get-obj ~entity :object) ~k ~@options)) (defn nine-patch? "Returns true if `entity` is a `nine-patch`." [entity] (isa? (type (u/get-obj entity :object)) NinePatch)) ; particle-effect (defn particle-effect* [path] (ParticleEffectEntity. (if (nil? path) (ParticleEffect.) (let [^Files files (Gdx/files) ^FileHandle fh (if (string? path) (.internal files path) path)] (or (u/load-asset (.path fh) ParticleEffect) (doto (ParticleEffect.) (.load fh (.parent fh)))))))) (defmacro particle-effect "Returns an entity based on [ParticleEffect](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/ParticleEffect.html). (particle-effect) (particle-effect \"particles/fire.p\")" [& [path & options]] `(let [entity# (particle-effect* ~path)] (u/calls! ^ParticleEffect (u/get-obj entity# :object) ~@options) entity#)) (defmacro particle-effect! "Calls a single method on a `particle-effect`. (particle-effect! entity :set-position 10 10)" [entity k & options] `(u/call! ^ParticleEffect (u/get-obj ~entity :object) ~k ~@options)) (defn particle-effect? "Returns true if `entity` is a `particle-effect`." [entity] (isa? (type (u/get-obj entity :object)) ParticleEffect)) ; texture-atlas (defn texture-atlas* [^String path] (or (u/load-asset path TextureAtlas) (TextureAtlas. path))) (defmacro texture-atlas "Returns a [TextureAtlas](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/TextureAtlas.html). (texture-atlas \"packed.txt\")" [path & options] `(let [^TextureAtlas object# (texture-atlas* path)] (u/calls! object# ~@options) object#)) (defmacro texture-atlas! "Calls a single method on a `texture-atlas`. (texture-atlas! object :create-patch \"test\")" [object k & options] `(u/call! ^TextureAtlas ~object ~k ~@options)) ; animation (defmacro play-mode "Returns a static field from [Animation.PlayMode](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Animation.PlayMode.html). (play-mode :loop)" [k] (u/gdx-field :graphics :g2d "Animation$PlayMode" (u/key->upper k))) (defn animation* [duration textures] (Animation. duration (u/gdx-array (map #(u/get-obj % :object) textures)) (play-mode :normal))) (defmacro animation "Returns an [Animation](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Animation.html). (animation 0.2 [walk-1 walk-2 walk-3] :set-play-mode (play-mode :loop-pingpong))" [duration textures & options] `(u/calls! ^Animation (animation* ~duration ~textures) ~@options)) (defmacro animation! "Calls a single method on an `animation`. (animation! object :set-play-mode (play-mode :loop))" [object k & options] `(u/call! ^Animation ~object ~k ~@options)) (defn animation->texture "Returns a `texture` entity with a frame from `animation` based on the total time the `screen` has been showing. (animation->texture screen anim)" ([{:keys [total-time] :as screen} ^Animation animation] (texture* (.getKeyFrame animation total-time true))) ([{:keys [total-time] :as screen} ^Animation animation is-looping?] (texture* (.getKeyFrame animation total-time is-looping?))))