forked from pedestal/app-tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
End a Game
Brenton Ashworth edited this page Jun 29, 2013
·
6 revisions
in behavior add transform function
(defn high-score [scores {:keys [player score]}]
(let [s ((fnil conj []) scores {:player player :score score})]
(reverse (sort-by :score s))))add continue function end-game
(defn clear-end-game [players]
(vec (reduce (fn [a b]
(conj a ^:input {msg/type :swap msg/topic [:other-counters b] :value 0}))
[^:input {msg/type :swap msg/topic [:my-counter] :value 0}
^:input {msg/type :swap msg/topic [:max-count] :value 0}]
(keys players))))
(defn end-game [{:keys [players total active]}]
(when (and active (>= total (* (count players) 100)))
(let [[player score] (last (sort-by val (seq players)))]
(into (clear-end-game players)
[{msg/type :swap msg/topic [:active-game] :value false}
{msg/type :swap msg/topic [:winner] :value {:player player :score score}}
{msg/type :high-score msg/topic [:high-scores] :player player :score score}
^:input {msg/topic msg/app-model msg/type :set-focus :name :wait}]))))update transforms
:transform [[:inc [:*] inc-transform]
[:swap [:**] swap-transform]
[:debug [:pedestal :**] swap-transform]
[:add-points [:my-counter] add-points]
[:high-score [:high-scores] high-score]]add continue
[{[:players] :players [:total-count] :total [:active-game] :active} end-game :map]update emitters
[#{[:winner]} (app/default-emitter :wait)]
[#{[:high-scores]} (app/default-emitter :wait)]point out how critical it is that we can record the end of a game.
<_within file="application.html">
<div id="content">
<div class="row-fluid" template="wait" field="id:id">
<div>
<div class="winner" field="content:winner">Morwen wins with a score of 500</div>
</div>
<div>
<button class="btn btn-success" id="start-button">Start Game</button>
</div>
<div class="row-fluid">
<div class="span6">
<h2>Current Players</h2>
<div id="players">
<div template="player" class="player-row" field="id:id,content:player-name">Feanor</div>
<div class="player-row">Fingolfin</div>
<div class="player-row">Morgoth</div>
<div class="player-row">Morwen</div>
</div>
<!-- this is required because of a bug -->
<div field="content:something"></div>
</div>
<div class="span6">
<h2>High Scores</h2>
<table id="high-scores" field="content:high-scores">
<tr template="high-score" class="high-score">
<td field="content:player-name">Feanor</td>
<td field="content:player-score">500</td>
</tr>
<tr class="high-score"><td>Morgoth</td><td>350</td></tr>
<tr class="high-score"><td>Fingolfin</td><td>310</td></tr>
</table>
</div>
</div>
</div>
</div>
</_within>update css
.high-score td {
line-height: 40px;
font-size: 30px;
font-weight: bold;
padding-right: 20px;
color: #888;
}
.winner {
font-size: 30px;
line-height: 40px;
text-align: center;
color: #888;
}slice templates
(defmacro tutorial-client-templates
[]
{:tutorial-client-page (dtfn (tnodes "game.html" "tutorial") #{:id})
:login-page (tfn (tnodes "login.html" "login"))
:wait-page (dtfn (tnodes "wait.html" "wait" [[:#players] [:#high-scores]]) #{:id})
:player (tfn (tnodes "wait.html" "player"))
:high-score (tfn (tnodes "wait.html" "high-score"))})rendering.cljs
Note: destroy-game should be added earlier in the process.
(defn destroy-game [renderer [_ path :as delta] input-queue]
(js/destroyGame (game renderer))
(render/drop-data! renderer path)
(h/default-destroy renderer delta input-queue))(defn render-winner [renderer [_ path _ v] _]
(templates/update-t renderer [:wait]
{:winner (str (:player v) " wins with a score of " (:score v))}))
(defn render-high-scores [renderer [_ path _ v] _]
(let [t (:high-score templates)
high-scores (apply str
(map (fn [{:keys [player score]}]
(t {:player-name player :player-score score})) v))]
(templates/update-t renderer [:wait]
{:high-scores high-scores})))[:value [:wait :winner] render-winner]
[:value [:wait :high-scores] render-high-scores]We now have a multi-player game that starts and ends.
The tag for this step is step17.