From 3639e4fd064c734d3f5f5711b25b73c69fede9bf Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Wed, 10 Dec 2014 13:07:08 -0800 Subject: [PATCH] refinement. --- desktop/resources/cursor.png | Bin 5691 -> 5687 bytes .../advent/screens/rooms/inside_castle.clj | 66 ++++++++++++------ .../advent/screens/rooms/outside_castle.clj | 51 ++++++-------- desktop/src-common/advent/utils.clj | 5 ++ 4 files changed, 72 insertions(+), 50 deletions(-) diff --git a/desktop/resources/cursor.png b/desktop/resources/cursor.png index ded4268659e705fafa36cffc7e31b234b34a0849..6be25ca1bacb0dfa5de01da0436d4f679ba8699e 100644 GIT binary patch delta 4623 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 FV1iq66|w*T delta 4627 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 screen trophy) + :x 253 :y 69 :baseline 191 + :anim trophy + :anim-start 0 + :script (actions/get-script entities + (walk-to-player entities) + (if (= nil (get-in @entities [:state :current-riddle])) + (let [{:keys [run choices]} (nice-trophy-dialogue entities)] + (run "Nice trophy.") + (actions/present-choices entities {:choices choices})) + (actions/do-dialogue entities :ego "Can't you give me your trophy of wisdom?" + :game-player "If you want my trophy, you'll have to help me with my riddles.")))) + :game-player (assoc (texture "inside-castle/gameplayer.png") :x 266 :y 49 :baseline 191 :script (actions/get-script entities (do-game-player-dialogue entities)) :scripts {:wool (actions/get-script entities + (walk-to-player entities) (if (= :wool (get-in @entities [:state :current-riddle])) (do (actions/update-state entities #(assoc % :current-riddle :balloon)) (actions/remove-item entities :wool) @@ -144,6 +165,7 @@ :game-player "If you want to keep it, best have a tether.")) (actions/talk entities :ego "He doesn't need it."))) :balloon (actions/get-script entities + (walk-to-player entities) (if (= :balloon (get-in @entities [:state :current-riddle])) (do (actions/update-state entities #(assoc % :current-riddle :frog-legs)) (actions/remove-item entities :balloon) @@ -153,6 +175,7 @@ :game-player "Now I'm dead, or at least a have a scar.")) (actions/talk entities :ego "He doesn't need it."))) :frog-legs (actions/get-script entities + (walk-to-player entities) (if (= :frog-legs (get-in @entities [:state :current-riddle])) (do (actions/update-state entities #(assoc % :current-riddle :done)) @@ -161,7 +184,8 @@ :game-player "Wow! That's right!" :game-player "I guess I'm not the wisest person in Remington." :game-player "You have earned my trophy.") - (actions/give entities :trophy)) + (actions/give entities :trophy) + (actions/remove-entity entities :trophy)) (actions/talk entities :ego "He doesn't need it.")))} :anim nil :talk game-player-talk)} diff --git a/desktop/src-common/advent/screens/rooms/outside_castle.clj b/desktop/src-common/advent/screens/rooms/outside_castle.clj index 6ef10631..b7ab910e 100644 --- a/desktop/src-common/advent/screens/rooms/outside_castle.clj +++ b/desktop/src-common/advent/screens/rooms/outside_castle.clj @@ -14,7 +14,7 @@ (let [peddler-sheet (texture! (texture "outside-castle/peddler-talk.png" ) :split 18 36) peddler-talk (animation 0.18 (for [i (flatten [2 3 2 3 2 3 6 1 0 1 0 1 0 1 0 1 2 3 2 3 2 3 6 4 5 4 5 4 5 4 5])] (aget peddler-sheet 0 i))) - peddler-stand (animation 0.2 (for [i (flatten [(repeat 5 0) 6])] + peddler-stand (animation 0.2 (for [i (flatten [(repeat 8 0) 6 (repeat 8 0) 6 (repeat 5 0) 4 5 4 5 4 5])] (aget peddler-sheet 0 i))) balloon-sheet (texture! (texture "outside-castle/balloons.png") :split 20 36) balloon-stand (animation 0.25 (for [i [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 0 1 2 1 0 1 2 1 0 1 2 1 0 1 2]] @@ -22,16 +22,11 @@ bird-sheet (texture! (texture "outside-castle/bird.png") :split 1 2) bird-stand (animation 0.15 (for [i [0 1]] (aget bird-sheet 0 i))) - butterfly-sheet (texture! (texture "butterfly.png") :split 7 7) - butterfly-stand (animation 0.1 (for [i [0 1]] - (aget butterfly-sheet 0 i))) + butterfly-stand (utils/make-anim "butterfly.png" [7 7] 0.1 [0 1]) steer-sheet (texture! (texture "outside-castle/steer.png") :split 50 35) steer-stand (animation 0.2 (for [i [0 0 0 0 0 0 0 0 0 1 0 2 0 1 0 2 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 0 0 0 0]] (aget steer-sheet 0 i))) - flies-sheet (texture! (texture "outside-castle/flies.png") :split 15 15) - flies-stand (animation 0.075 (for [i [0 1 2 1]] - (aget flies-sheet 0 i))) - ] + flies-stand (utils/make-anim "outside-castle/flies.png" [15 15] 0.075 [0 1 2 1])] (rooms/make :music :town-2 :interactions {:right-dir {:box [300 40 320 140] @@ -187,27 +182,25 @@ a (catmull-rom-spline! (:path entity) :value-at v pos-f)] (assoc entity :x (vector-2! v :x) :y (vector-2! v :y))))) :stand) - :butterfly (actions/start-animation screen - (assoc (animation->texture screen butterfly-stand) - :x 161 - :y 218 - :baseline 240 - :stand butterfly-stand - :path (catmull-rom-spline (map #(apply vector-2* %) (take 10 (repeatedly #(vector (rand-int 320) (rand-int 180))))) true) - :update-fn (fn [screen entities entity] - (let [speed 0.009 - pos-f (- (* (:total-time screen) speed) (int (* (:total-time screen) speed))) - v (vector-2 0 0) - a (catmull-rom-spline! (:path entity) :value-at v pos-f)] - (assoc entity :x (vector-2! v :x) :y (vector-2! v :y))))) - :stand) - :flies (actions/start-animation screen - (assoc (animation->texture screen flies-stand) - :x 201 - :y 175 - :baseline 240 - :stand flies-stand) - :stand)} + :butterfly (assoc (animation->texture screen butterfly-stand) + :x 161 + :y 218 + :baseline 240 + :anim butterfly-stand + :anim-start 0 + :path (catmull-rom-spline (map #(apply vector-2* %) (take 10 (repeatedly #(vector (rand-int 320) (rand-int 180))))) true) + :update-fn (fn [screen entities entity] + (let [speed 0.009 + pos-f (- (* (:total-time screen) speed) (int (* (:total-time screen) speed))) + v (vector-2 0 0) + a (catmull-rom-spline! (:path entity) :value-at v pos-f)] + (assoc entity :x (vector-2! v :x) :y (vector-2! v :y))))) + :flies (assoc (animation->texture screen flies-stand) + :x 201 + :y 175 + :anim flies-stand + :anim-start 0 + :baseline 240)} :collision "outside-castle/collision.png" :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.00) :start-pos [310 80]))) diff --git a/desktop/src-common/advent/utils.clj b/desktop/src-common/advent/utils.clj index 4254e56e..79b57360 100644 --- a/desktop/src-common/advent/utils.clj +++ b/desktop/src-common/advent/utils.clj @@ -74,3 +74,8 @@ (texture! frame :set-region src-frame) (texture! frame :flip true false) frame)))) + +(defn make-anim [file [w h] speed frames] + (let [sheet (texture! (texture file) :split w h)] + (animation speed (for [i frames] + (aget sheet 0 i)))))