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] [play-clj.g2d :refer :all]
[clojure.pprint] [clojure.pprint]
[clojure.string :as s] [clojure.string :as s]
[clojure.zip :as zip]
[advent.pathfind] [advent.pathfind]
[advent.actions :as actions] [advent.actions :as actions]
[advent.screens.dialogue :as dialogue] [advent.screens.dialogue :as dialogue]
@@ -148,18 +149,48 @@
(stop screen entities target-id) (stop screen entities target-id)
entities))))) entities)))))
(defn present-choices [entities & pairs] (defn something-else [zipper]
(run-action entities (-> zipper zip/up zip/up))
(begin [this screen entities]
(run! dialogue/choice-screen :on-present-choices :pairs pairs)
(run! @(resolve 'advent.screens.scene/scene) :on-deactivate)
entities)
(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] (defn give [entities target-id item]

View File

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

View File

@@ -151,7 +151,7 @@
(if (= :choices subject) (if (= :choices subject)
(apply actions/present-choices entities (for [choice (partition 2 arg)] (apply actions/present-choices entities (for [choice (partition 2 arg)]
[(first choice) (actions/get-script entities [(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) (if (= :line arg)
(actions/talk entities subject previous-line) (actions/talk entities subject previous-line)
(actions/talk entities subject arg)))))) (actions/talk entities subject arg))))))
@@ -179,28 +179,18 @@
:cursor :down} :cursor :down}
:wizard {:box [228 80 248 126] :wizard {:box [228 80 248 126]
:script (actions/get-script entities :script (actions/get-script entities
(run-dialogue-tree entities [:ego "Hello there Mr. Fangald!" (actions/present-choices entities {:choices {"Hello there" {:run #(do (actions/talk entities :ego %)
:wizard "Oh no, not you again!" (actions/talk entities :wizard "Oh, hello."))
:choices ["You're not happy to see me?" [:ego :line :choices {"How are you doing?" {:run #(do (actions/talk entities :ego %)
:wizard "Of course not!" (actions/talk entities :wizard "I'm ok."))
:wizard "Not after all the hell you've put me through." :choices actions/previous-choices}
:choices ["You mean the time I set your rabbit loose?" [:ego :line "Any news?" {:run #(do (actions/talk entities :ego %)
:wizard "Fluffy was my best rabbit!"] (actions/talk entities :wizard "Not really"))
"You're not still sore about my stealing your magic cowboy hat." [:ego :line :choices actions/previous-choices}
:ego "Are you?" "Something Else" {:choices actions/something-else}}}
:wizard "That cowboy hat was one of a kind!" "Good bye" {:run #(actions/talk entities :ego %)}}})
: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."]]]))}}
:layers [(assoc (texture "inside-house/background.png") :x 0 :y 0 :baseline 0) :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/desk.png") :x 0 :y 0 :baseline 200)
(assoc (texture "inside-house/sillhoute.png") :x 0 :y 0 :baseline 240)] (assoc (texture "inside-house/sillhoute.png") :x 0 :y 0 :baseline 240)]
@@ -356,7 +346,7 @@
(update! screen :renderer (stage) :camera (orthographic)) (update! screen :renderer (stage) :camera (orthographic))
(let [_ (input! :set-cursor-image (utils/cursor "cursor.png" :main) 0 0) (let [_ (input! :set-cursor-image (utils/cursor "cursor.png" :main) 0 0)
music (sound "town-music.mp3") music (sound "town-music.mp3")
_ (sound! music :loop 0.20) ;; _ (sound! music :loop 0.20)
backgrounds (backgrounds screen)] backgrounds (backgrounds screen)]
{:backgrounds backgrounds {:backgrounds backgrounds
:state {:object nil :state {:object nil