Skip to content
Brenton Ashworth edited this page Jun 29, 2013 · 6 revisions

End a Game

End of game behavior

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)]

Rendering the end of a game

point out how critical it is that we can record the end of a game.

Update the wait template

<_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]

Next steps

We now have a multi-player game that starts and ends.

The tag for this step is step17.

Home | Parallel Processing

Clone this wiki locally