Skip to content
This repository has been archived by the owner on May 21, 2021. It is now read-only.

Commit

Permalink
Use z-index to order rendering
Browse files Browse the repository at this point in the history
- Adds z property to the position component
- Sorts sprites by z-index in the render system
  • Loading branch information
alexkehayias committed Oct 24, 2016
1 parent d6dc35a commit b22cfe5
Show file tree
Hide file tree
Showing 11 changed files with 49 additions and 31 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ pom.xml.asc
/resources/public/js/compiled/*
/figwheel_server.log
/resources/assets
./push-master.sh
./push-master.sh
*.*~
5 changes: 3 additions & 2 deletions src/cljs/chocolatier/engine/components/attack.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
[entity-id component-state event position]
(let [{:keys [action direction]} (:msg event)
{:keys [damage type width height ttl sprite-fn speed]} (get component-state action)
{:keys [screen-x screen-y]} position
{:keys [screen-x screen-y screen-z]} position
cooldown (get-in component-state [action :cooldown])
[cooldown-state cooldown?] (tick-cooldown cooldown)
next-state (assoc-in component-state [action :cooldown] cooldown-state)]
Expand All @@ -54,7 +54,8 @@
position-state (mk-position-state (+ screen-x 16)
(+ screen-y 24)
(+ screen-x 16)
(+ screen-y 24))
(+ screen-y 24)
screen-z)
ephemeral-state (mk-ephemeral-state ttl)
sprite-state (sprite-fn)
msg {:type :entity
Expand Down
4 changes: 2 additions & 2 deletions src/cljs/chocolatier/engine/components/damage.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
- Creates an text entity with the amount of damage taken"
[entity-id component-state position-state attacks]
;; TODO emit action events like hit animation
(let [{:keys [screen-x screen-y]} position-state
(let [{:keys [screen-x screen-y screen-z]} position-state
text-fn (:text-fn component-state)
damage (transduce (map :damage) + 0 attacks)
next-state (-> component-state
Expand All @@ -53,7 +53,7 @@
:opts {:uid entity-id}} [:meta])]]
[next-state [(ev/mk-event {:type :entity
:opts {:uid (keyword (gensym "damage-"))
:components [{:uid :position :state (mk-position-state screen-x screen-y screen-x screen-y)}
:components [{:uid :position :state (mk-position-state screen-x screen-y screen-x screen-y screen-z)}
{:uid :moveable :state (mk-moveable-state 2 :up)}

{:uid :ephemeral :state (mk-ephemeral-state 10)}
Expand Down
11 changes: 6 additions & 5 deletions src/cljs/chocolatier/engine/components/position.cljs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
(ns chocolatier.engine.components.position)


(defrecord Position [map-x map-y screen-x screen-y])
(defrecord Position [map-x map-y screen-x screen-y screen-z])

(defn mk-position-state
[map-x map-y screen-x screen-y]
(->Position map-x map-y screen-x screen-y))
[map-x map-y screen-x screen-y screen-z]
(->Position map-x map-y screen-x screen-y screen-z))

(defn position
"Calculates the entities position on the map and on the screen. Listens
Expand All @@ -14,7 +14,7 @@
[entity-id component-state {:keys [inbox]}]
;; If there are no messages then no-op
(if (seq inbox)
(let [{:keys [map-x map-y screen-x screen-y]} component-state
(let [{:keys [map-x map-y screen-x screen-y screen-z]} component-state
[offset-x offset-y] (reduce
(fn [[x y] {msg :msg}]
[(+ x (:offset-x msg))
Expand All @@ -25,5 +25,6 @@
{:map-x (- screen-x offset-x)
:map-y (- screen-y offset-y)
:screen-x (- screen-x offset-x)
:screen-y (- screen-y offset-y)})
:screen-y (- screen-y offset-y)
:screen-z screen-z})
component-state))
8 changes: 4 additions & 4 deletions src/cljs/chocolatier/engine/components/renderable.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
"Update the screen x, y position of the sprite based on any move events
from a component inbox. Returns the updated sprite."
[sprite position]
(let [{:keys [screen-x screen-y]} position]
(let [{:keys [screen-x screen-y screen-z]} position]
;; Mutate the x and y position of the sprite if there was any
;; move changes
(aset sprite "position" (js-obj "x" screen-x "y" screen-y))))
(aset sprite "position" (js-obj "x" screen-x "y" screen-y "z" screen-z))))

;; TODO figure out a way to not need the stage so we can more easily
;; create sprite state. For example, in the attack component we must
Expand All @@ -38,8 +38,8 @@
sprite frame as the last argument to render to the position right away"
([stage loader img-path]
{:sprite (pixi/mk-sprite-from-cache! stage loader img-path)})
([stage loader img-path frame]
{:sprite (pixi/mk-sprite-from-cache! stage loader img-path frame)}))
([stage loader img-path frame z-index]
{:sprite (pixi/mk-sprite-from-cache! stage loader img-path frame z-index)}))

(defn mk-text-sprite-state
[stage text styles]
Expand Down
14 changes: 10 additions & 4 deletions src/cljs/chocolatier/engine/pixi.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
(set! (.-frame texture) bounds))
sprite)

(defn set-sprite-zindex! [sprite idx]
(set! (.-position.z sprite) idx))

(defn mk-sprite-from-cache!
"Returns a sprite that has been added to the stage. The image for the sprite
is loaded from the cache. If a frame is not passed in the sprite will not
Expand All @@ -66,14 +69,16 @@
- image-location: a path to the image to use for the sprite
Optional args:
- frame: a vector of x, y, w, h in relation to the sprite image"
- frame: a vector of x, y, w, h in relation to the sprite image
- z-index: the z dimension when drawing the sprite"
([stage loader image-location]
(mk-sprite-from-cache! stage loader image-location [0 0 0 0]))
([stage loader image-location frame]
(mk-sprite-from-cache! stage loader image-location [0 0 0 0] 0))
([stage loader image-location frame z-index]
(let [cached-texture (.-texture (aget (.-resources loader) image-location))
texture (new js/PIXI.Texture (.-baseTexture cached-texture))
sprite (new js/PIXI.Sprite texture)]
(set-sprite-frame! sprite frame)
(set-sprite-zindex! sprite z-index)
(add-child! stage sprite)
sprite)))

Expand Down Expand Up @@ -142,7 +147,8 @@
(let [texture (.generateTexture container renderer)
sprite (new js/PIXI.Sprite texture)]
;; This is a side-effect with no return value
(add-child! stage sprite)))
(add-child! stage sprite)
sprite))

(defn mk-text!
"Creates a PIXI.Text object with styles.
Expand Down
10 changes: 9 additions & 1 deletion src/cljs/chocolatier/engine/systems/render.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
[chocolatier.engine.pixi :as pixi]))


(defn sort-by-zindex [a b]
(cond
(< (.-position.z a) (.-position.z b)) -1
(> (.-position.z a) (.-position.z b)) 1
:else 0))

(defn render-system
"Renders all the changes to sprites and other Pixi objects"
"Renders all the changes to sprites and other Pixi objects.
Draws sprites in order of their zindex."
[state]
(let [{:keys [renderer stage]} (-> state :game :rendering-engine)]
(.sort (.-children stage) sort-by-zindex)
(pixi/render! renderer stage)
state))
11 changes: 5 additions & 6 deletions src/cljs/chocolatier/engine/systems/tiles.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,15 @@
map-x map-y
tileset-x tileset-y
attributes)]
(pixi/add-child-at! container (:sprite tile) 0)
(pixi/add-child! container (:sprite tile))
;; Add to the accumulator
(.push accum tile)
(recur (rest tile-specs)))
(recur (rest tile-specs)))
(do (log/debug "Rendering tile map container")
(pixi/render-from-object-container! renderer
stage
container)
accum)))))
(let [sprite (pixi/render-from-object-container! renderer stage container)]
(log/debug "Rendering tile map container")
(set! (.-position.z sprite) 0)
accum)))))

(defn mk-tiles-from-tilemap!
"Returns a collection of tile hashmaps according to the spec.
Expand Down
3 changes: 2 additions & 1 deletion src/cljs/chocolatier/entities/enemy.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
[state stage loader uid]
(let [pos-x (* 1000 (js/Math.random))
pos-y (* 1000 (js/Math.random))
pos-z 10
sprite-state (mk-sprite-state stage loader "/img/bunny.png")
animation-state (mk-animateable-state :stand-down
[:stand-up 26 37 26 37 0 0 1]
Expand All @@ -25,7 +26,7 @@
[:stand-right 26 37 26 37 0 0 1]
[:hit-up 20 30 20 30 0 0 1])
move-state (mk-moveable-state 4 :down)
position-state (mk-position-state pos-x pos-y pos-x pos-y)
position-state (mk-position-state pos-x pos-y pos-x pos-y pos-z)
collision-state (mk-collidable-state 26 37 nil)
damage-state (mk-damage-state 50 5 5
#(mk-text-sprite-state stage % {"font" "bold 12px Arial"
Expand Down
9 changes: 5 additions & 4 deletions src/cljs/chocolatier/entities/player.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

(defn create-player!
"Create a player by initializing some component state"
[stage loader uid pos-x pos-y map-x map-y]
(info "Creating player" pos-x pos-y map-x map-y)
[stage loader uid pos-x pos-y pos-z map-x map-y]
(info "Creating player" pos-x pos-y pos-z map-x map-y)
(let [text-state (mk-text-sprite-state stage "Player 1" {"font" "bold 12px Arial"
"stroke" "white"
"strokeThickness" 3})
Expand Down Expand Up @@ -52,7 +52,7 @@
[:spear-down-left 8321344 64 64 6 0 8]
[:spear-left 8321344 64 64 5 0 8]
[:spear-right 8321344 64 64 7 0 8])
position-state (mk-position-state pos-x pos-y pos-x pos-y)
position-state (mk-position-state pos-x pos-y pos-x pos-y pos-z)
move-state (mk-moveable-state 4 :down)
collision-state (mk-collidable-state 64 64 nil)
attacks [[:fireball {:damage 10
Expand All @@ -65,7 +65,8 @@
:sprite-fn #(mk-sprite-state stage
loader
"/img/fireball.png"
[0 0 30 30])}]
[0 0 30 30]
0)}]
[:spear {:damage 10
:cooldown 4
:type :fire
Expand Down
2 changes: 1 addition & 1 deletion src/cljs/chocolatier/examples/action_rpg/game.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
:tilemap tilemap}}
;; Player 1 entity
{:type :entity
:opts (create-player! stage loader :player1 20 20 0 0)}
:opts (create-player! stage loader :player1 20 20 1000 0 0)}
;; Script enemy creation
;; {:type :script
;; :opts {:fn (fn [state]
Expand Down

0 comments on commit b22cfe5

Please sign in to comment.