a better approach to dialogue treees.

This commit is contained in:
2014-09-26 16:51:27 -07:00
parent 51be2e0e14
commit 27d992776a
3 changed files with 61 additions and 39 deletions

View File

@@ -5,6 +5,7 @@
[play-clj.g2d :refer :all]
[clojure.pprint]
[clojure.string :as s]
[clojure.zip :as zip]
[advent.pathfind]
[advent.actions :as actions]
[advent.screens.dialogue :as dialogue]
@@ -148,18 +149,48 @@
(stop screen entities target-id)
entities)))))
(defn present-choices [entities & pairs]
(run-action entities
(begin [this screen entities]
(run! dialogue/choice-screen :on-present-choices :pairs pairs)
(run! @(resolve 'advent.screens.scene/scene) :on-deactivate)
entities)
(defn something-else [zipper]
(-> zipper zip/up zip/up))
(continue [this screen entities] entities)
(defn previous-choices [zipper]
(-> zipper zip/up))
(done? [this screen entities] true)
(defn nth-child [zipper i]
(loop [so-far 0
zipper (zip/down zipper)]
(if (= so-far i)
zipper
(recur (inc so-far) (zip/right zipper)))))
(terminate [this screen entities] entities)))
(defn make-zipper [tree]
(zip/zipper map? (comp vals :choices) (fn [n c] nil) tree))
(defn present-choices [entities choices]
(loop [zipper (make-zipper choices)]
(let [selected-choice (atom nil)
node (zip/node zipper)]
(run-action entities
(begin [this screen entities]
(run! dialogue/choice-screen :on-present-choices :choices (:choices node) :callback #(reset! selected-choice %))
(run! @(resolve 'advent.screens.scene/scene) :on-deactivate)
entities)
(continue [this screen entities] entities)
(done? [this screen entities] (not (nil? @selected-choice)))
(terminate [this screen entities]
(run! @(resolve 'advent.screens.scene/scene) :on-reactivate)
entities))
(let [zipper (nth-child zipper (-> node :choices keys (.indexOf @selected-choice)))
node (zip/node zipper)]
(when-let [run (:run node)]
(run @selected-choice))
(when-let [next-choices (:choices node)]
(if (fn? next-choices)
(recur (next-choices zipper))
(recur zipper)))))))
(defn give [entities target-id item]

View File

@@ -68,28 +68,29 @@
entities)
:on-present-choices
(fn [{:keys [pairs]} [entities]]
(fn [{:keys [choices callback]} [entities]]
(let [font (bitmap-font "ego/font.fnt" )
tr (bitmap-font! font :get-region)
scale 1
tx (.getTexture tr)
_ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear)]
(into entities (for [[[text result-script] i] (map vector pairs (range))]
[i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i) :result-script result-script)]))))
(-> entities
(into (for [[text i] (map vector (keys choices) (range))]
[i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i))]))
(assoc :state {:object nil :callback callback :choices choices}))))
:on-touch-down (fn [screen [entities]]
(let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})]
(when (seq entities)
(when (< y (* 30 (count entities)))
(run! @(resolve 'advent.screens.scene/scene) :on-reactivate)
(run! @(resolve 'advent.screens.scene/scene) :on-start-script :script (:result-script (entities (int (/ y 30)))))
((get-in entities [:state :callback]) (nth (keys (get-in entities [:state :choices])) (int (/ y 30))))
{}))))
:on-mouse-moved (fn [screen [entities]]
(let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})
font (bitmap-font "ego/font.fnt" )]
(when (seq entities)
(doseq [index (range (count entities))]
(doseq [index (range (dec (count entities)))]
(if (< (* index 30) y (* (inc index) 30))
(label! (entities index) :set-style (style :label font (color :yellow)))
(label! (entities index) :set-style (style :label font (color :white))))))))

View File

@@ -151,7 +151,7 @@
(if (= :choices subject)
(apply actions/present-choices entities (for [choice (partition 2 arg)]
[(first choice) (actions/get-script entities
(run-dialogue-tree entities (second choice) (first choice)))]))
(run-dialogue-tree entities (doto (second choice) println) (first choice)))]))
(if (= :line arg)
(actions/talk entities subject previous-line)
(actions/talk entities subject arg))))))
@@ -179,28 +179,18 @@
:cursor :down}
:wizard {:box [228 80 248 126]
:script (actions/get-script entities
(run-dialogue-tree entities [:ego "Hello there Mr. Fangald!"
:wizard "Oh no, not you again!"
:choices ["You're not happy to see me?" [:ego :line
:wizard "Of course not!"
:wizard "Not after all the hell you've put me through."
:choices ["You mean the time I set your rabbit loose?" [:ego :line
:wizard "Fluffy was my best rabbit!"]
"You're not still sore about my stealing your magic cowboy hat." [:ego :line
:ego "Are you?"
:wizard "That cowboy hat was one of a kind!"
:wizard "Truly unique."
:wizard "It accented my unique facial physique."
:wizard "And now it's gone forever."
:wizard "Leave me to die in peace."]
"You mean the time I set your house on fire with a fire mint?" [:ego :line
:wizard "That was you? I spent a fortune cleaning up the mess you made!"
:wizard "You ruined my life work!"]
"An old hoot like you needs a kick the pants every now and again!" [:ego :line
:wizard "Maybe so, but not from a cheating little boy like you!"]]]
"What do you mean, 'not you again'?" [:ego :line
:wizard "I mean get lost kid."]]]))}}
(actions/present-choices entities {:choices {"Hello there" {:run #(do (actions/talk entities :ego %)
(actions/talk entities :wizard "Oh, hello."))
:choices {"How are you doing?" {:run #(do (actions/talk entities :ego %)
(actions/talk entities :wizard "I'm ok."))
:choices actions/previous-choices}
"Any news?" {:run #(do (actions/talk entities :ego %)
(actions/talk entities :wizard "Not really"))
:choices actions/previous-choices}
"Something Else" {:choices actions/something-else}}}
"Good bye" {:run #(actions/talk entities :ego %)}}})
)}}
:layers [(assoc (texture "inside-house/background.png") :x 0 :y 0 :baseline 0)
(assoc (texture "inside-house/desk.png") :x 0 :y 0 :baseline 200)
(assoc (texture "inside-house/sillhoute.png") :x 0 :y 0 :baseline 240)]
@@ -356,7 +346,7 @@
(update! screen :renderer (stage) :camera (orthographic))
(let [_ (input! :set-cursor-image (utils/cursor "cursor.png" :main) 0 0)
music (sound "town-music.mp3")
_ (sound! music :loop 0.20)
;; _ (sound! music :loop 0.20)
backgrounds (backgrounds screen)]
{:backgrounds backgrounds
:state {:object nil