<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Coding.Cookies</title>
    <link>http://www.codingcookies.com/</link>
    <description>A blog all about programming something awesome.</description>
    <pubDate>Fri, 03 May 2013 16:51:33 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/codingcookies" /><feedburner:info uri="codingcookies" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Building a Roguelike in Javascript - Part 7</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/qozFZtnHz0Y/building-a-roguelike-in-javascript-part-7</link>
      <pubDate>Fri, 03 May 2013 00:30:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/05/03/building-a-roguelike-in-javascript-part-7</guid>
      <description>Building a Roguelike in Javascript - Part 7</description>
      <content:encoded><![CDATA[<p>This is the ninth post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to <a href="http://trystans.blogspot.ca/2011/09/roguelike-tutorial-07-z-levels-and.html">the seventh part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part7">part 7 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a> for rot.js.</p>
<p>Our game currently has one simple level. In this post we are going to make our cave have a third dimension allowing our hero to venture deeper and deeper into the cave! I am going to take Trystan's approach of creating the entire world at once, allowing us to freely roam through the various levels without encountering loading screens / delays. This is going to be a long post as there is quite a lot to change, but hang in there - it will be worth it. I'd hate to finish a post without you have a working game, so I'm not going to split it into two parts.</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part7">here</a></p>
<h1>assets/tile.js</h1>
<p>The first thing we are going to want to create is a tile which allows us to go up one level as well as a tile which allows us to go down a level. Traditionally, roguelikes use stairs for this, and represent stairs going up as <span class="rlify">&lt;</span> and similarly <span class="rlify">&gt;</span> for going down.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">stairsUpTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">({</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;&lt;&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
    <span class="nx">isWalkable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">stairsDownTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">({</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
    <span class="nx">isWalkable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>

<p>While we are here, we will also create a helper function which will return a list containing all 8 neighbors of a given tile. It will shuffle them using <a href="http://ondras.github.io/rot.js/doc/symbols/Array.html">Array.prototype.randomize</a> to prevent a bias, as or else we will always favor the top-left corner. Admittedly this may not be the best place for this code and if I find that there are too many coordinate helper functions I will move them to their own file.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">getNeighborPositions</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">tiles</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="c1">// Generate all possible offsets</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">dX</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="nx">dX</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">dX</span> <span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">dY</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="nx">dY</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">dY</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Make sure it isn&#39;t the same tile</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">dX</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="nx">dY</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">continue</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="nx">tiles</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">x</span><span class="o">:</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">dX</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">y</span> <span class="o">+</span> <span class="nx">dY</span><span class="p">});</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">tiles</span><span class="p">.</span><span class="nx">randomize</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/builder.js</h1>
<p>As our map generation code is starting to get complicated, we are going to move all the generation code to this file. We will have a <em>Builder</em> object which will be responsible for generating all the tiles for a world. We can then use these tiles to create a <em>Map</em> object. When we generate our map, we are going to have two key variables. The first will be a 3D array representing the tile at each cell in the world. The second will be a 3D array assigning a region number to each cell in a world. Note that for both arrays, the depth will be the first dimension rather than the 3rd one as this will allow us to manipulate an entire depth layer at once.</p>
<p>We are going to split each individual Z level into a bunch of regions. A region is essentialy a grouping of tiles such that any tile in the region can reach all other tiles in the region without having to dig! Every non-walkable tile will have a region value of 0. All walkable tiles will have a region value starting at 1 designating which region they belong to. Here is an example map with the region numbers shown in red:
<div class="image_container"><a href="/assets/rogue/7regions.png"><img class="image" src="/assets/rogue/7regions.png" height="140" width="150"/></a></div></p>
<p>Let's start with our basic constructor:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">,</span> <span class="nx">depth</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span> <span class="o">=</span> <span class="nx">depth</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">depth</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">depth</span><span class="p">);</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>In order to build the tiles, we're going to create a helper function <em>_generateLevel</em> which consists of our old map generation code and generates a single level using <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Map.Cellular.html">ROT.Map.Cellular</a>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_generateLevel</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Create the empty map</span>
    <span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">w</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">w</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span> <span class="nx">w</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">map</span><span class="p">[</span><span class="nx">w</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// Setup the cave generator</span>
    <span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">Cellular</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">);</span>
    <span class="nx">generator</span><span class="p">.</span><span class="nx">randomize</span><span class="p">(</span><span class="mf">0.5</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">totalIterations</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="c1">// Iteratively smoothen the map</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">totalIterations</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="c1">// Smoothen it one last time and then update our map</span>
    <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">,</span><span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">});</span>
    <span class="k">return</span> <span class="nx">map</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Using this function, we can now build our 3D tiles array! We are also going to want to create our 3D array of region numbers, starting out each cell as 0.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">,</span> <span class="nx">depth</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// Instantiate the arrays to be multi-dimension</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">z</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">z</span> <span class="o">&lt;</span> <span class="nx">depth</span><span class="p">;</span> <span class="nx">z</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Create a new cave at each level</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">]</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_generateLevel</span><span class="p">();</span>
        <span class="c1">// Setup the regions array for each depth</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">width</span><span class="p">);</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">width</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">height</span><span class="p">);</span>
            <span class="c1">// Fill with zeroes</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">height</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Now that we've got our arrays instantiated, we want to set up the regions for each depth level. In order to do this, we'll need a few helper methods. The first is going to be a method for filling the region that a certain tile belongs to using a <a href="https://en.wikipedia.org/wiki/Flood_fill">flood fill</a> technique. One way to visualize this is to suppose you had a water bucket and you dropped it on a particular tile - our approach then consists of simulating the water expanding out and covering all walkable tiles. Here is a <a href="http://goo.gl/1E8t2">great animation of this process</a> to make things even more clear. Our function will accept a starting tile and a region number and spread out from there, changing the region of all tiles which should belong in the same region. It will return the number of tiles affected. Note that we will be flood filling in all eight directions, even though we only currently have 4-directional movement! We can easily extend our movement and I encourage you to do so as a challenge. We also create a helper function which makes sure a tile can actually be assigned a region.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_canFillRegion</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Make sure the tile is within bounds</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">z</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">x</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">||</span>
        <span class="nx">y</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">||</span> <span class="nx">z</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">// Make sure the tile does not already have a region</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">// Make sure the tile is walkable</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">].</span><span class="nx">isWalkable</span><span class="p">();</span>
<span class="p">}</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_fillRegion</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">region</span><span class="p">,</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">tilesFilled</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">tiles</span> <span class="o">=</span> <span class="p">[{</span><span class="nx">x</span><span class="o">:</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span><span class="nx">y</span><span class="p">}];</span>
    <span class="kd">var</span> <span class="nx">tile</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">neighbors</span><span class="p">;</span>
    <span class="c1">// Update the region of the original tile</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">region</span><span class="p">;</span>
    <span class="c1">// Keep looping while we still have tiles to process</span>
    <span class="k">while</span> <span class="p">(</span><span class="nx">tiles</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">tile</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
        <span class="c1">// Get the neighbors of the tile</span>
        <span class="nx">neighbors</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getNeighborPositions</span><span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">x</span><span class="p">,</span> <span class="nx">tile</span><span class="p">.</span><span class="nx">y</span><span class="p">);</span>
        <span class="c1">// Iterate through each neighbor, checking if we can use it to fill</span>
        <span class="c1">// and if so updating the region and adding it to our processing</span>
        <span class="c1">// list.</span>
        <span class="k">while</span> <span class="p">(</span><span class="nx">neighbors</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">tile</span> <span class="o">=</span> <span class="nx">neighbors</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_canFillRegion</span><span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">x</span><span class="p">,</span> <span class="nx">tile</span><span class="p">.</span><span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">tile</span><span class="p">.</span><span class="nx">x</span><span class="p">][</span><span class="nx">tile</span><span class="p">.</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">region</span><span class="p">;</span>
                <span class="nx">tiles</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">tile</span><span class="p">);</span>
                <span class="nx">tilesFilled</span><span class="o">++</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>

    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">tilesFilled</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>In order to set up our map, we are going to iterate through each tile of each depth layer, and if it can be filled with a region, we try to fill it. If our region is too small (say 20 tiles or less were filled), then we are going to remove it by filling it with wall tiles. For the sake of simplicity when removing a region I will simply iterate through all tiles searching for tiles with a given region ID. While this may perform extra unnecessary lookups, it will keep the code much simpler.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// This removes all tiles at a given depth level with a region number.</span>
<span class="c1">// It fills the tiles with a wall tile.</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_removeRegion</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">region</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">==</span> <span class="nx">region</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Clear the region and set the tile to a wall tile</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// This sets up the regions for a given depth level.</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_setupRegions</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">region</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">tilesFilled</span><span class="p">;</span>
    <span class="c1">// Iterate through all tiles searching for a tile that</span>
    <span class="c1">// can be used as the starting point for a flood fill</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_canFillRegion</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">))</span> <span class="p">{</span>
                <span class="c1">// Try to fill</span>
                <span class="nx">tilesFilled</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_fillRegion</span><span class="p">(</span><span class="nx">region</span><span class="p">,</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
                <span class="c1">// If it was too small, simply remove it</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">tilesFilled</span> <span class="o">&lt;=</span> <span class="mi">20</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">_removeRegion</span><span class="p">(</span><span class="nx">region</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                    <span class="nx">region</span><span class="o">++</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We are now going to connect the depth levels using their regions! For example if we have a region at level 1, we want to try to connect it to all regions that it overlaps with on the level below it. This will help us minimize the number of times where a player is actualy stuck, and so we could make digging have an actual cost in the future. To do this we first need to be able to find where two regions overlap, and then we iterate through each tiles and try to connect each region at most once with all other regions it overlaps. Again this code may not be the best performance-wise but, like Trystan says, as world generation only happens once it is acceptable.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// This fetches a list of points that overlap between one</span>
<span class="c1">// region at a given depth level and a region at a level beneath it.</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_findRegionOverlaps</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">z</span><span class="p">,</span> <span class="nx">r1</span><span class="p">,</span> <span class="nx">r2</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">matches</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="c1">// Iterate through all tiles, checking if they respect</span>
    <span class="c1">// the region constraints and are floor tiles. We check</span>
    <span class="c1">// that they are floor to make sure we don&#39;t try to</span>
    <span class="c1">// put two stairs on the same tile.</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span>  <span class="o">==</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">&amp;&amp;</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">==</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">&amp;&amp;</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">==</span> <span class="nx">r1</span> <span class="o">&amp;&amp;</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">==</span> <span class="nx">r2</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">matches</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">x</span><span class="o">:</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">y</span><span class="p">});</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">// We shuffle the list of matches to prevent bias</span>
    <span class="k">return</span> <span class="nx">matches</span><span class="p">.</span><span class="nx">randomize</span><span class="p">();</span>
<span class="p">}</span>

<span class="c1">// This tries to connect two regions by calculating </span>
<span class="c1">// where they overlap and adding stairs</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_connectRegions</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">z</span><span class="p">,</span> <span class="nx">r1</span><span class="p">,</span> <span class="nx">r2</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">overlap</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_findRegionOverlaps</span><span class="p">(</span><span class="nx">z</span><span class="p">,</span> <span class="nx">r1</span><span class="p">,</span> <span class="nx">r2</span><span class="p">);</span>
    <span class="c1">// Make sure there was overlap</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">overlap</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">// Select the first tile from the overlap and change it to stairs</span>
    <span class="kd">var</span> <span class="nx">point</span> <span class="o">=</span> <span class="nx">overlap</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">point</span><span class="p">.</span><span class="nx">x</span><span class="p">][</span><span class="nx">point</span><span class="p">.</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">stairsDownTile</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="nx">point</span><span class="p">.</span><span class="nx">x</span><span class="p">][</span><span class="nx">point</span><span class="p">.</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">stairsUpTile</span><span class="p">;</span>
    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// This tries to connect all regions for each depth level,</span>
<span class="c1">// starting from the top most depth level.</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_connectAllRegions</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">z</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">z</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">z</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Iterate through each tile, and if we haven&#39;t tried</span>
        <span class="c1">// to connect the region of that tile on both depth levels</span>
        <span class="c1">// then we try. We store connected properties as strings</span>
        <span class="c1">// for quick lookups.</span>
        <span class="kd">var</span> <span class="nx">connected</span> <span class="o">=</span> <span class="p">{};</span>
        <span class="kd">var</span> <span class="nx">key</span><span class="p">;</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">key</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;,&#39;</span> <span class="o">+</span>
                      <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">];</span>
                <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">==</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">&amp;&amp;</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">==</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">&amp;&amp;</span>
                    <span class="o">!</span><span class="nx">connected</span><span class="p">[</span><span class="nx">key</span><span class="p">])</span> <span class="p">{</span>
                    <span class="c1">// Since both tiles are floors and we haven&#39;t </span>
                    <span class="c1">// already connected the two regions, try now.</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">_connectRegions</span><span class="p">(</span><span class="nx">z</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">],</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">_regions</span><span class="p">[</span><span class="nx">z</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]);</span>
                    <span class="nx">connected</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now all we have to do is update the constructor!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">,</span> <span class="nx">depth</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">z</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">z</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">;</span> <span class="nx">z</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_setupRegions</span><span class="p">(</span><span class="nx">z</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_connectAllRegions</span><span class="p">();</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Finally we want to provide some simple getter methods to be able to access the generated data.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getTiles</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getDepth</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getWidth</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getHeight</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/entity.js</h1>
<p>Now that we've added a notion of depth, we must add a Z coordinate to each entity:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// Instantiate any properties from the passed object</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_name</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;y&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_z</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;z&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setZ</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_z</span> <span class="o">=</span> <span class="nx">z</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getZ</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_z</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We are also going to add a function which will allow us to simply update all 3 coordinates at once:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">y</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_z</span> <span class="o">=</span> <span class="nx">z</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/map.js</h1>
<p>This file will require some pretty substantial changes to keep track of the third dimension. First we have to change the constructor to keep track of the depth (and change how we get the width and height). We also add a simple getter.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tiles</span><span class="p">,</span> <span class="nx">player</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">;</span>
    <span class="c1">// cache dimensions</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">.</span><span class="nx">length</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getDepth</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Now we need to update almost all our helper functions in order to have a third dimension. This is pretty tedious and so to save space I will simply give you the code for it, however feel free to ask for any clarifications in the comments.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Gets the tile for a given coordinate set</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getTile</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Make sure we are inside the bounds. If we aren&#39;t, return</span>
    <span class="c1">// null tile.</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">x</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">||</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">y</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">||</span>
        <span class="nx">z</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">z</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">||</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">dig</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// If the tile is diggable, update it to a floor</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">).</span><span class="nx">isDiggable</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">z</span><span class="p">][</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">isEmptyFloor</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Check if the tile is floor and also has no entity</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="o">==</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">&amp;&amp;</span>
           <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">getEntityAt</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// ...</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getEntityAt</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">){</span>
    <span class="c1">// Iterate through all entities searching for one with</span>
    <span class="c1">// matching position</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getX</span><span class="p">()</span> <span class="o">==</span> <span class="nx">x</span> <span class="o">&amp;&amp;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getY</span><span class="p">()</span> <span class="o">==</span> <span class="nx">y</span> <span class="o">&amp;&amp;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getZ</span><span class="p">()</span> <span class="o">==</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getEntitiesWithinRadius</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">centerX</span><span class="p">,</span> <span class="nx">centerY</span><span class="p">,</span>
                                                      <span class="nx">centerZ</span><span class="p">,</span> <span class="nx">radius</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">results</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="c1">// Determine our bounds</span>
    <span class="kd">var</span> <span class="nx">leftX</span> <span class="o">=</span> <span class="nx">centerX</span> <span class="o">-</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">rightX</span> <span class="o">=</span> <span class="nx">centerX</span> <span class="o">+</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">topY</span> <span class="o">=</span> <span class="nx">centerY</span> <span class="o">-</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">bottomY</span> <span class="o">=</span> <span class="nx">centerY</span> <span class="o">+</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="c1">// Iterate through our entities, adding any which are within the bounds</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">leftX</span> <span class="o">&amp;&amp;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="nx">rightX</span> <span class="o">&amp;&amp;</span> 
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">topY</span> <span class="o">&amp;&amp;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="nx">bottomY</span> <span class="o">&amp;&amp;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getZ</span><span class="p">()</span> <span class="o">==</span> <span class="nx">centerZ</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">results</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
<span class="p">}</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">addEntity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">entity</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Make sure the entity&#39;s position is within bounds</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">||</span>
        <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">||</span>
        <span class="nx">entity</span><span class="p">.</span><span class="nx">getZ</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getZ</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Adding entity out of bounds.&#39;</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// Update the entity&#39;s map</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setMap</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="c1">// Add the entity to the list of entities</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
    <span class="c1">// Check if this entity is an actor, and if so add</span>
    <span class="c1">// them to the scheduler</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Actor&#39;</span><span class="p">))</span> <span class="p">{</span>
       <span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">entity</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We also have to modify our function which generates a random position. I am going to add an argument allowing us to specify what level we want to generate a random floor position on. Finally we can add an entity at a random position on a given level.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Randomly generate a tile which is a floor</span>
    <span class="kd">var</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">;</span>
    <span class="k">do</span> <span class="p">{</span>
        <span class="nx">x</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
        <span class="nx">y</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">isEmptyFloor</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">));</span>
    <span class="k">return</span> <span class="p">{</span><span class="nx">x</span><span class="o">:</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="o">:</span> <span class="nx">z</span><span class="p">};</span>
<span class="p">}</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">entity</span><span class="p">,</span> <span class="nx">z</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">position</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span><span class="p">(</span><span class="nx">z</span><span class="p">);</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setX</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">x</span><span class="p">);</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setY</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">y</span><span class="p">);</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setZ</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">z</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">addEntity</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We now update our constructor to fix the player on level 1 as well as to generate more fungus so that it spreads out evenly throughout the dungeon.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tiles</span><span class="p">,</span> <span class="nx">player</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// add the player</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span><span class="p">(</span><span class="nx">player</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
    <span class="c1">// add random fungi</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">z</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">z</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_depth</span><span class="p">;</span> <span class="nx">z</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">25</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span><span class="p">(</span><span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span><span class="p">),</span> <span class="nx">z</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/entities.js</h1>
<p>We have to update some of our mixins which take location into consideration. The first one we will update is the movement mixin. While we are here we will also add some code to handle changing depth levels.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">,</span> <span class="nx">map</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">();</span>
        <span class="c1">// Must use starting z</span>
        <span class="kd">var</span> <span class="nx">tile</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">getZ</span><span class="p">());</span>
        <span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getEntityAt</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">getZ</span><span class="p">());</span>
        <span class="c1">// If our z level changed, check if we are on stair</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">z</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">getZ</span><span class="p">())</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span> <span class="o">!=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">stairsUpTile</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s2">&quot;You can&#39;t go up here!&quot;</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s2">&quot;You ascend to level %d!&quot;</span><span class="p">,</span> <span class="p">[</span><span class="nx">z</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]);</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">setPosition</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">z</span> <span class="o">&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">getZ</span><span class="p">())</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span> <span class="o">!=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">stairsDownTile</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s2">&quot;You can&#39;t go down here!&quot;</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">setPosition</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s2">&quot;You descend to level %d!&quot;</span><span class="p">,</span> <span class="p">[</span><span class="nx">z</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]);</span>
            <span class="p">}</span>
        <span class="c1">// If an entity was present at the tile</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// If we are an attacker, try to attack</span>
            <span class="c1">// the target</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Attacker&#39;</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">attack</span><span class="p">(</span><span class="nx">target</span><span class="p">);</span>
                <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="c1">// If not nothing we can do, but we can&#39;t </span>
                <span class="c1">// move to the tile</span>
                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="c1">// Check if we can walk on the tile</span>
        <span class="c1">// and if so simply walk onto it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isWalkable</span><span class="p">())</span> <span class="p">{</span>        
            <span class="c1">// Update the entity&#39;s position</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">setPosition</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="c1">// Check if the tile is diggable, and</span>
        <span class="c1">// if so try to dig it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isDiggable</span><span class="p">())</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">.</span><span class="nx">dig</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>As we changed our <em>getEntitiesWithinRadius</em> function, we also have to change our <em>sendMessageNearby</em> function:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessageNearby</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">map</span><span class="p">,</span> <span class="nx">centerX</span><span class="p">,</span> <span class="nx">centerY</span><span class="p">,</span> <span class="nx">centerZ</span><span class="p">,</span> <span class="nx">message</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// Get the nearby entities</span>
    <span class="nx">entities</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getEntitiesWithinRadius</span><span class="p">(</span><span class="nx">centerX</span><span class="p">,</span> <span class="nx">centerY</span><span class="p">,</span> <span class="nx">centerZ</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally we have to update our <em>FungusActor</em> to place newly grown fungus at the right depth level as well as use the updated <em>sendMessageNearby</em>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> 
                <span class="c1">// ...</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">xOffset</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">yOffset</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                    <span class="c1">// Check if we can actually spawn at that location, and if so</span>
                    <span class="c1">// then we grow!</span>
                    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">isEmptyFloor</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">xOffset</span><span class="p">,</span>
                                                   <span class="k">this</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">yOffset</span><span class="p">,</span>
                                                   <span class="k">this</span><span class="p">.</span><span class="nx">getZ</span><span class="p">()))</span> <span class="p">{</span>
                        <span class="kd">var</span> <span class="nx">entity</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span><span class="p">);</span>
                        <span class="nx">entity</span><span class="p">.</span><span class="nx">setPosition</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">xOffset</span><span class="p">,</span> 
                            <span class="k">this</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">yOffset</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">getZ</span><span class="p">());</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">addEntity</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">_growthsRemaining</span><span class="o">--</span><span class="p">;</span>
                        <span class="c1">// Send a message nearby!</span>
                        <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessageNearby</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">(),</span>
                            <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">(),</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">(),</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getZ</span><span class="p">(),</span>
                            <span class="s1">&#39;The fungus is spreading!&#39;</span><span class="p">);</span>
                    <span class="p">}</span>
                <span class="p">}</span>
                <span class="c1">// ...   </span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/game.js</h1>
<p>Before we can change the screen input handling, there is one small chnage we must make. Because we will be using the greater than and less than keys as our stairs keys, we must enable the 'keypress' event handler, as these are special keys and the character code can only be extracted from the key press data.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Bind keyboard input events</span>
<span class="nx">bindEventToScreen</span><span class="p">(</span><span class="s1">&#39;keydown&#39;</span><span class="p">);</span>
<span class="c1">//bindEventToScreen(&#39;keyup&#39;);</span>
<span class="nx">bindEventToScreen</span><span class="p">(</span><span class="s1">&#39;keypress&#39;</span><span class="p">);</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>Now that we've done all this work for generating our map usng the builder, let's update our <em>PlayScreen</em>'s enter function.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">_map</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">_player</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Create a map based on our size parameters</span>
        <span class="kd">var</span> <span class="nx">width</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">height</span> <span class="o">=</span> <span class="mi">48</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">depth</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span>
        <span class="c1">// Create our map from the tiles and player</span>
        <span class="kd">var</span> <span class="nx">tiles</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Builder</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">,</span> <span class="nx">depth</span><span class="p">).</span><span class="nx">getTiles</span><span class="p">();</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="nx">tiles</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">);</span>
        <span class="c1">//this._map = new Game.Map(map, this._player);</span>
        <span class="c1">// Start the map&#39;s engine</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">start</span><span class="p">();</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now our rendering code also needs to be updated to make sure we only render at the player's Z level.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="c1">// Iterate through all visible map cells</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="nx">topLeftX</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">topLeftX</span> <span class="o">+</span> <span class="nx">screenWidth</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="nx">topLeftY</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">topLeftY</span> <span class="o">+</span> <span class="nx">screenHeight</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Fetch the glyph for the tile and render it to the screen</span>
                <span class="c1">// at the offset position.</span>
                <span class="kd">var</span> <span class="nx">tile</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getZ</span><span class="p">());</span>
                <span class="c1">// ...</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// Render the entities</span>
        <span class="kd">var</span> <span class="nx">entities</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEntities</span><span class="p">();</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="kd">var</span> <span class="nx">entity</span> <span class="o">=</span> <span class="nx">entities</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
            <span class="c1">// Only render the entitiy if they would show up on the screen</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">topLeftX</span> <span class="o">&amp;&amp;</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">topLeftY</span> <span class="o">&amp;&amp;</span>
                <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&lt;</span> <span class="nx">topLeftX</span> <span class="o">+</span> <span class="nx">screenWidth</span> <span class="o">&amp;&amp;</span>
                <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&lt;</span> <span class="nx">topLeftY</span> <span class="o">+</span> <span class="nx">screenHeight</span> <span class="o">&amp;&amp;</span>
                <span class="nx">entity</span><span class="p">.</span><span class="nx">getZ</span><span class="p">()</span> <span class="o">==</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getZ</span><span class="p">())</span> <span class="p">{</span>
                <span class="c1">// ...</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Lastly we have to update our input handling! We have to add the cases for the stairs keys as update the movement to take the 3rd dimension into consideration. I also fixed a small bug which caused a turn to be executed when no valid key was pressed. Note that I had to use <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode">String.fromCharCode</a> to check if it was a stairs key as they require SHIFT and the Javascript key code always returned period or commma.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">inputType</span> <span class="o">===</span> <span class="s1">&#39;keydown&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// If enter is pressed, go to the win screen</span>
            <span class="c1">// If escape is pressed, go to lose screen</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RETURN</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">winScreen</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_ESCAPE</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">loseScreen</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="c1">// Movement</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_LEFT</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RIGHT</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_UP</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_DOWN</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                    <span class="c1">// Not a valid key</span>
                    <span class="k">return</span><span class="p">;</span>
                <span class="p">}</span>
                <span class="c1">// Unlock the engine</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">unlock</span><span class="p">();</span>
            <span class="p">}</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputType</span> <span class="o">===</span> <span class="s1">&#39;keypress&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="kd">var</span> <span class="nx">keyChar</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">charCode</span><span class="p">);</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">keyChar</span> <span class="o">===</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">keyChar</span> <span class="o">===</span> <span class="s1">&#39;&lt;&#39;</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="c1">// Not a valid key</span>
                <span class="k">return</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="c1">// Unlock the engine</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">unlock</span><span class="p">();</span>
        <span class="p">}</span> 
    <span class="p">},</span>
    <span class="nx">move</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dX</span><span class="p">,</span> <span class="nx">dY</span><span class="p">,</span> <span class="nx">dZ</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">newX</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">dX</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">newY</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">dY</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">newZ</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getZ</span><span class="p">()</span> <span class="o">+</span> <span class="nx">dZ</span><span class="p">;</span>
        <span class="c1">// Try to move to the new cell</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">tryMove</span><span class="p">(</span><span class="nx">newX</span><span class="p">,</span> <span class="nx">newY</span><span class="p">,</span> <span class="nx">newZ</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/index.html</h1>
<p>We are finally done! All we have to do now is update our scripts:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/tile.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/builder.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/map.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>Our dungeon now spans across multiple levels! Our hero can now descend into the deepest and darkest parts of the cave and then come back up. I'm terribly sorry about the length of this post, but as I've mentioned before I'd hate to leave you with something that you couldn't play with. In the next post we will add a field of vision so that we only see our hero's immediate surroundings. This will be a great addition and will add a nice touch of atmosphere to our cave.</p>
<p>I hope you enjoyed this post! Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part7">part 7 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. As always please feel free to post any comments whether questions, clarifications or criticism!</p>
<p>Thanks for reading,</p>
<p>Dominic</p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/qozFZtnHz0Y" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/05/03/building-a-roguelike-in-javascript-part-7</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 6</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/aIYmi4YHMR4/building-a-roguelike-in-javascript-part-6</link>
      <pubDate>Tue, 30 Apr 2013 00:30:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/30/building-a-roguelike-in-javascript-part-6</guid>
      <description>Building a Roguelike in Javascript - Part 6</description>
      <content:encoded><![CDATA[<p>This is the eight post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to <a href="http://trystans.blogspot.ca/2011/09/roguelike-tutorial-06-hitpoints-combat.html">the sixth part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part6">part 6 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a> for rot.js.</p>
<p>In the last post we introduced basic combat allowing our hero to whack down any pesky fungi by simply bumping into them. We're now going to make this combat system a bit more realistic, giving attack and defense stats to entities and adding a bit of a random factor to attack damage. As we play our game we're also going to want to know what's going on so we're going to add a simple way to show messages on the screen.</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part6">here</a></p>
<h1>Combat - assets/entities.js</h1>
<p>Our combat system will work by giving a defense value to <em>Destructible</em> mixins as well as an attack value to <em>Attacker</em> mixins. We will calculate the difference between the two (<em>attackValue - defenseValue</em>) and if the result is greater than zero, randomly select a damage amount in the range [1, <em>attackValue - defenseValue</em> ]. If our defense value is greater than or equal to our attack value, than we only do a damage of 1.</p>
<p>We're going to update the <em>Destructible</em> mixin first. In the last post this mixin always had 1 HP. We will change this so that an entity starts out with a given level of health (<em>maxHp</em>) which can be passed in the template. We also add some getters for the health point stats.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Destructible&#39;</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">template</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_maxHp</span> <span class="o">=</span> <span class="nx">template</span><span class="p">[</span><span class="s1">&#39;maxHp&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">10</span><span class="p">;</span>
        <span class="c1">// We allow taking in health from the template incase we want</span>
        <span class="c1">// the entity to start with a different amount of HP than the </span>
        <span class="c1">// max specified.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_hp</span> <span class="o">=</span> <span class="nx">template</span><span class="p">[</span><span class="s1">&#39;hp&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">_maxHp</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">getHp</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hp</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">getMaxHp</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_maxHp</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Now we want to add the defense value. This is going to be a function which all <em>Destructible</em> mixins will implement and will simply return an int. By doing it this way we can have all sorts of neat effects, such as an entity who can be in a defensive mode to get a defense bonus or a chest which gets harder to break the further in the game we are. To make our base destructible mixin more flexible, let's update our constructor to allow specifying a defense value in template. For now we'll make the default defense value function return 0.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">template</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_defenseValue</span> <span class="o">=</span> <span class="nx">template</span><span class="p">[</span><span class="s1">&#39;defenseValue&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">getDefenseValue</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_defenseValue</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Now to take care of the attacking mixin. We have a bit of refactoring to do from last post. We are going to <strong>rename SimpleAttacker to Attacker</strong>. </p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Attacker</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Attacker&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Attacker&#39;</span><span class="p">,</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we want to add an attack value function to the <em>Attacker</em> mixin similar to the defense value. As the default defense value was 0, our default attack value will be 1. We also want to add an option to read the attack value from the template used to create the mixin.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Attacker</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">template</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_attackValue</span> <span class="o">=</span> <span class="nx">template</span><span class="p">[</span><span class="s1">&#39;attackValue&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">getAttackValue</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_attackValue</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Finally we update the default <em>attack</em> method to calculate the damage using the formula we mentioned above.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Attacker</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">attack</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// If the target is destructible, calculate the damage</span>
        <span class="c1">// based on attack and defense value</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Destructible&#39;</span><span class="p">))</span> <span class="p">{</span>
            <span class="kd">var</span> <span class="nx">attack</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getAttackValue</span><span class="p">();</span>
            <span class="kd">var</span> <span class="nx">defense</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">getDefenseValue</span><span class="p">();</span>
            <span class="kd">var</span> <span class="nx">max</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">attack</span> <span class="o">-</span> <span class="nx">defense</span><span class="p">);</span>
            <span class="nx">target</span><span class="p">.</span><span class="nx">takeDamage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="mi">1</span> <span class="o">+</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="nx">max</span><span class="p">));</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Our combat system is now much more flexible and the aspect of randomness certainly makes it more interesting. Let's update our templates to give our player and fungus some stats. Our player will have a max HP of 40 for now and an attack value of 10. Our fungi will have the default defense value and 10 HP.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Player template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
    <span class="nx">maxHp</span><span class="o">:</span> <span class="mi">40</span><span class="p">,</span>
    <span class="nx">attackValue</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">PlayerActor</span><span class="p">,</span>
             <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Attacker</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span><span class="p">]</span>
<span class="p">}</span>
<span class="c1">// Fungus template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span>
    <span class="nx">maxHp</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>Messaging - assets/entities.js</h1>
<p>Now that we can hit our fungi with varying damage, we're going to want to know how much damage we're inflicting as well as when we sucesfully kill an enemy. To do this, we're going to want to be able to display messages on the screen. To keep in line with our mixin system, we are going to have a mixin for entities which can receive messages. Our player will have this mixin. As the entities take their turn, they will fill up the player's message queue. When the player's turn finally comes, we will display these messages on the screen. We will need a way to clear this message queue as well in order to make sure we don't show the same messages every single turn.</p>
<p>Let's create the MessageRecipient mixin. This will add an internal array of messages to the entity, and provide a method for receiving a message, which will be a string for now, as well methdods for fetching and clearing the messages.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">MessageRecipient</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;MessageRecipient&#39;</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">template</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_messages</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="p">},</span>
    <span class="nx">receiveMessage</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_messages</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="nx">getMessages</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_messages</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">clearMessages</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_messages</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We are now going to want a function to send a message to an entity if it can receive them. As this will be primarily used in the entity code, we will place the function here for now, although I may move it in the future if I can think of a better place or if we start needing more advanced message processing. Our message sending function will specify the entity we wish to target as well as the message itself. To make message formatting simple, I will be using the fantastic <a href="https://github.com/alexei/sprintf.js">sprintf.js library by Alexandru Marasteanu</a>, which is currently at <a href="https://github.com/alexei/sprintf.js/commit/2e852e4b7e3fd96b31f3a8e63e2393cee6e9b2a8">commit 2e852e4b7e</a>. This will allow us to send messages like so:</p>
<pre><code>Game.sendMessage(player, "You hit the %s for %d damage", [name, damage]);
</code></pre>
<p><br/>
<strong>To install this library you will want to download the <a href="https://github.com/alexei/sprintf.js/blob/2e852e4b7e3fd96b31f3a8e63e2393cee6e9b2a8/src/sprintf.min.js">sprintf.min.js</a> file (this is at the right commit) and add it to the assets folder.</strong></p>
<p>Let's define our sending function! This will take at least a recipient entity and a message as arguments, as well as an optional array of parameters to pass to vsprintf, which is a function similar to sprintf that accepts it's formatting arguments as an array. If our recipient entity has the <em>MessageRecipient</em> mixin, then we will send them the message!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">recipient</span><span class="p">,</span> <span class="nx">message</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Make sure the recipient can receive the message </span>
    <span class="c1">// before doing any work.</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">recipient</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">MessageRecipient</span><span class="p">))</span> <span class="p">{</span>
        <span class="c1">// If args were passed, then we format the message, else</span>
        <span class="c1">// no formatting is necessary</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">message</span> <span class="o">=</span> <span class="nx">vsprintf</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="nx">recipient</span><span class="p">.</span><span class="nx">receiveMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we are all set up to send some messages! Before we do that, we have some small updates to do to our entity templates. We will start using the name property to give a textual name to our entities so that our message could say something along the lines of 'you hit the fungus' rather than 'you hit the F'. We will also make the player a message recipient!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Player template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
    <span class="nx">maxHp</span><span class="o">:</span> <span class="mi">40</span><span class="p">,</span>
    <span class="nx">attackValue</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">PlayerActor</span><span class="p">,</span>
             <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Attacker</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span><span class="p">,</span>
             <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">MessageRecipient</span><span class="p">]</span>
<span class="p">}</span>
<span class="c1">// Fungus template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;fungus&#39;</span><span class="p">,</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span>
    <span class="nx">maxHp</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we're ready to add some messages! We want a message to appear when our hero attacks another entity as well as when damage is received in the future! So let's modify the <em>Attacker</em> mixin's attack function. </p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Attacker</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">attack</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// If the target is destructible, calculate the damage</span>
        <span class="c1">// based on attack and defense value</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Destructible&#39;</span><span class="p">))</span> <span class="p">{</span>
            <span class="kd">var</span> <span class="nx">attack</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getAttackValue</span><span class="p">();</span>
            <span class="kd">var</span> <span class="nx">defense</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">getDefenseValue</span><span class="p">();</span>
            <span class="kd">var</span> <span class="nx">max</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">attack</span> <span class="o">-</span> <span class="nx">defense</span><span class="p">);</span>
            <span class="kd">var</span> <span class="nx">damage</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="nx">max</span><span class="p">);</span>

            <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s1">&#39;You strike the %s for %d damage!&#39;</span><span class="p">,</span> 
                <span class="p">[</span><span class="nx">target</span><span class="p">.</span><span class="nx">getName</span><span class="p">(),</span> <span class="nx">damage</span><span class="p">]);</span>
            <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="nx">target</span><span class="p">,</span> <span class="s1">&#39;The %s strikes you for %d damage!&#39;</span><span class="p">,</span> 
                <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">getName</span><span class="p">(),</span> <span class="nx">damage</span><span class="p">]);</span>

            <span class="nx">target</span><span class="p">.</span><span class="nx">takeDamage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">damage</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Another potential message we could want is when an entity is destroyed! Let's modify the <em>Destructible</em> mixin!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">takeDamage</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">attacker</span><span class="p">,</span> <span class="nx">damage</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_hp</span> <span class="o">-=</span> <span class="nx">damage</span><span class="p">;</span>
        <span class="c1">// If have 0 or less HP, then remove ourseles from the map</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_hp</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="nx">attacker</span><span class="p">,</span> <span class="s1">&#39;You kill the %s!&#39;</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">getName</span><span class="p">()]);</span>
            <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s1">&#39;You die!&#39;</span><span class="p">);</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">removeEntity</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Our system seems pretty straightforward for direct entity to entity messaging! We may have cases where we wish to broadcast a message to all entities within a certain distance! In order to do this, we'll need to create some helper functions in our map class first!</p>
<h1>assets/map.js</h1>
<p>We currently only have methods for returning the entity at a given position! We are going to add a method which will return an array containing all entities which are within a given radial distance from the specified center X and Y position. An example of radial distance is:</p>
<pre><code>3333333
3222223
3211123
3210123
3211123
3222223
3333333
</code></pre>
<p><br/></p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getEntitiesWithinRadius</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">centerX</span><span class="p">,</span> <span class="nx">centerY</span><span class="p">,</span> <span class="nx">radius</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">results</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="c1">// Determine our bounds</span>
    <span class="kd">var</span> <span class="nx">leftX</span> <span class="o">=</span> <span class="nx">centerX</span> <span class="o">-</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">rightX</span> <span class="o">=</span> <span class="nx">centerX</span> <span class="o">+</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">topY</span> <span class="o">=</span> <span class="nx">centerY</span> <span class="o">-</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">bottomY</span> <span class="o">=</span> <span class="nx">centerY</span> <span class="o">+</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="c1">// Iterate through our entities, adding any which are within the bounds</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">leftX</span> <span class="o">&amp;&amp;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="nx">rightX</span> <span class="o">&amp;&amp;</span> 
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">topY</span> <span class="o">&amp;&amp;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="nx">bottomY</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">results</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/entities.js</h1>
<p>We are now ready to make a function for sending a message to all entities near a location. This function will be similar to the <em>sendMessage</em> function we previously defined, except it allows us to specify a location rather than a recipient entity. We will send the message to all entities within a given radius from the location (radius is fixed at 5 for now). </p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessageNearby</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">map</span><span class="p">,</span> <span class="nx">centerX</span><span class="p">,</span> <span class="nx">centerY</span><span class="p">,</span> <span class="nx">message</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// If args were passed, then we format the message, else</span>
    <span class="c1">// no formatting is necessary</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">message</span> <span class="o">=</span> <span class="nx">vsprintf</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// Get the nearby entities</span>
    <span class="nx">entities</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getEntitiesWithinRadius</span><span class="p">(</span><span class="nx">centerX</span><span class="p">,</span> <span class="nx">centerY</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span>
    <span class="c1">// Iterate through nearby entities, sending the message if</span>
    <span class="c1">// they can receive it.</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">hasMixin</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">MessageRecipient</span><span class="p">))</span> <span class="p">{</span>
            <span class="nx">entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">receiveMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>To make sure that this works, lets make it so that when a new fungus grows it will send a message to the entities nearby! This may not be the most efficient code, but it will serve our purposes just fine for now! We will update the <em>FungusActor</em> mixin!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> 
        <span class="c1">// ...</span>
                    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">isEmptyFloor</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">xOffset</span><span class="p">,</span>
                                                   <span class="k">this</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">yOffset</span><span class="p">))</span> <span class="p">{</span>
                        <span class="kd">var</span> <span class="nx">entity</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span><span class="p">);</span>
                        <span class="nx">entity</span><span class="p">.</span><span class="nx">setX</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">xOffset</span><span class="p">);</span>
                        <span class="nx">entity</span><span class="p">.</span><span class="nx">setY</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">yOffset</span><span class="p">);</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">addEntity</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">_growthsRemaining</span><span class="o">--</span><span class="p">;</span>

                        <span class="c1">// Send a message nearby!</span>
                        <span class="nx">Game</span><span class="p">.</span><span class="nx">sendMessageNearby</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">(),</span>
                            <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">(),</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">(),</span>
                            <span class="s1">&#39;The fungus is spreading!&#39;</span><span class="p">);</span>
                    <span class="p">}</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>The last thing we're going to want to do in this file is make it so that it clears the messages after they have been rendered to the screen. While we haven't done the actual rendering yet, we know that it will be done when we call <em>Game.refresh</em> in the <em>PlayerActor</em> mixin. So after we do this call, let's clear our messages!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Main player&#39;s actor mixin</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">PlayerActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;PlayerActor&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Actor&#39;</span><span class="p">,</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Re-render the screen</span>
        <span class="nx">Game</span><span class="p">.</span><span class="nx">refresh</span><span class="p">();</span>
        <span class="c1">// Lock the engine and wait asynchronously</span>
        <span class="c1">// for the player to press a key.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">lock</span><span class="p">();</span>        
        <span class="c1">// Clear the message queue</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">clearMessages</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>Now that our messaging system is up and running, let's start rendering them to the screen! For now we will simply render them in the top left corner. We have to make sure to render them after rendering the map! This may not be the most elegant location for them, and we may move them to a centralized message box in the future (or as a challenge try and modify the code to do that now!) but for now this will do. Luckily we can use the <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Display.html#drawText">drawText</a> function to wrap text and determine how many lines the text spanned across. This will allow us to easily messages that are too long to fit on one line. </p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="c1">// Get the messages in the player&#39;s queue and render them</span>
        <span class="kd">var</span> <span class="nx">messages</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getMessages</span><span class="p">();</span>
        <span class="kd">var</span> <span class="nx">messageY</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">messages</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Draw each message, adding the number of lines</span>
            <span class="nx">messageY</span> <span class="o">+=</span> <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span>
                <span class="mi">0</span><span class="p">,</span> 
                <span class="nx">messageY</span><span class="p">,</span>
                <span class="s1">&#39;%c{white}%b{black}&#39;</span> <span class="o">+</span> <span class="nx">messages</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
            <span class="p">);</span>
        <span class="p">}</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Now your hero can go around attacking and killing fungus and seeing feedback right on the screen! One last change I want to make before I finish off this post is to show the player's stats on the last row of the screen.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="c1">// Render player HP </span>
        <span class="kd">var</span> <span class="nx">stats</span> <span class="o">=</span> <span class="s1">&#39;%c{white}%b{black}&#39;</span><span class="p">;</span>
        <span class="nx">stats</span> <span class="o">+=</span> <span class="nx">vsprintf</span><span class="p">(</span><span class="s1">&#39;HP: %d/%d &#39;</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getHp</span><span class="p">(),</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getMaxHp</span><span class="p">()]);</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">screenHeight</span><span class="p">,</span> <span class="nx">stats</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<h1>assets/game.js</h1>
<p>As we want to reserve the last line of the display for rendering the stats, we are going to increase the size of the display by 1.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span>  <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Any necessary initialization will go here.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenWidth</span><span class="p">,</span>
                                         <span class="nx">height</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenHeight</span> <span class="o">+</span> <span class="mi">1</span><span class="p">})</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>index.html</h1>
<p>We have to update our scripts to include the <a href="https://github.com/alexei/sprintf.js">sprintf.js library</a>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/rot.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/sprintf.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/game.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>This post was pretty significant towards pushing our game closer to a real roguelike game! We now have a more robust combat system as well as a nice way of sending messages to the player! In the next post we will be making our cave have multiple levels, so stick around as it's going to be exciting!</p>
<p>I hope you enjoyed this post! Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part6">part 6 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. As always please feel free to post any comments whether questions, clarifications or criticism!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Next Part</h1>
<p><a href="/2013/05/03/building-a-roguelike-in-javascript-part-7/">Part 7 - Deeper Into the Cave</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/aIYmi4YHMR4" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/30/building-a-roguelike-in-javascript-part-6</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 5b</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/QaHgxB2RVE8/building-a-roguelike-in-javascript-part-5b</link>
      <pubDate>Tue, 23 Apr 2013 00:30:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/23/building-a-roguelike-in-javascript-part-5b</guid>
      <description>Building a Roguelike in Javascript - Part 5b</description>
      <content:encoded><![CDATA[<p>This is the seventh post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to <a href="http://trystans.blogspot.ca/2011/09/roguelike-tutorial-05-stationary.html">the fifth part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part5b">part 5b tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a> for rot.js.</p>
<p>Today we're going to make it so that we can interact with our fungi! We're going to add a basic attack system which will simply remove an entity when our player attacks it. For those unfamiliar with roguelikes, attacking is generally done by bumping into or moving into the entity we wish to attack. We're also going to make the fungus entity spread randomly over time, eventually taking over our cave unless our hero chooses to rise to the task and attack every fungus!</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part5b">here</a></p>
<h1>assets/map.js</h1>
<p>Before we can get started with our attack system, we need a way to actually remove an entity from the map. One special consideration to make is that we must also remove the entity from the scheduler if they were an actor. So you're going to want to add the following function:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">removeEntity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">entity</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Find the entity in the list of entities if it is present</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">==</span> <span class="nx">entity</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
            <span class="k">break</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">// If the entity is an actor, remove them from the scheduler</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Actor&#39;</span><span class="p">))</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>When we implement the fungi spreading, we're going to make it spread to an adjacent tile. In order to do this, we'll need to check whether a tile is an empty floor tile. As this will be a pretty common thing to check for, let's create a helper function which will do just that so we have a central place to add in features:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">isEmptyFloor</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Check if the tile is floor and also has no entity</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">==</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">&amp;&amp;</span>
           <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">getEntityAt</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>While we're here, let's go ahead and update our <em>getRandomFloorPosition</em> to make use of this function:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Randomly generate a tile which is a floor</span>
    <span class="kd">var</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">;</span>
    <span class="k">do</span> <span class="p">{</span>
        <span class="nx">x</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
        <span class="nx">y</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">isEmptyFloor</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">));</span>
    <span class="k">return</span> <span class="p">{</span><span class="nx">x</span><span class="o">:</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">y</span><span class="p">};</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>The last change we're going to want to make is to decrease the number of initial fungi. Because they will be spreading throughout the dungeon it will be much more apparent if we start with a small number. Feel free to play around with the number! We have to change:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tiles</span><span class="p">,</span> <span class="nx">player</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// add random fungi</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">50</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span><span class="p">(</span><span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span><span class="p">));</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We're now ready to make it so we can hack away at these pesky growing fungi!</p>
<h1>assets/entities.js</h1>
<p>In order to implement our basic attacking system, we're going to have two mixins. The first wil be a mixin denoting an entity that is destructible. For now the most basic mixin will have a certain number of hit points and a <em>takeDamage</em> function. The <em>takeDamage</em> function will subtract the damage caused by an attacker, and if the hit points are 0 or below, remove that entity from the map. For now all <em>Destructible</em> entities will have 1 hit point.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Destructible&#39;</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_hp</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">takeDamage</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">attacker</span><span class="p">,</span> <span class="nx">damage</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_hp</span> <span class="o">-=</span> <span class="nx">damage</span><span class="p">;</span>
        <span class="c1">// If have 0 or less HP, then remove ourseles from the map</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_hp</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">removeEntity</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>The second will be some kind of Attacker mixin, which has a sole method <em>attack</em>. When an entity chooses to attack a target, we will call the <em>attack</em> method with the target. Similar to the Actor mixin we implemented last post, the Attacker mixin will also be a common group (using the <em>groupName</em>) and we'll create more specific ones when necessary, allowing us to come up with really cool ways of attacking. To keep it simple, if our target is destructible, we will damage the target by 1 HP, removing it from the map.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">SimpleAttacker</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;SimpleAttacker&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Attacker&#39;</span><span class="p">,</span>
    <span class="nx">attack</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Only remove the entity if they were attackable</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Destructible&#39;</span><span class="p">))</span> <span class="p">{</span>
            <span class="nx">target</span><span class="p">.</span><span class="nx">takeDamage</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we need to update our templates to include these mixins! We want to add a SimpleAttacker and Destructible to the player's template as in the future the player will be attackable. We also want to add Destructible to the fungi.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Player template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">PlayerActor</span><span class="p">,</span>
             <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">SimpleAttacker</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span><span class="p">]</span>
<span class="p">}</span>
<span class="c1">// Fungus template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Destructible</span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>So now we have our attacking mixins set up and put in place. However we have to change our Moveable as well in order to make it so that if there is an entity present at the cell we wish to move to, and we are an attacker, than try to attack the entity!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Define our Moveable mixin</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">map</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">tile</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
        <span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getEntityAt</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
        <span class="c1">// If an entity was present at the tile</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// If we are an attacker, try to attack</span>
            <span class="c1">// the target</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Attacker&#39;</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">attack</span><span class="p">(</span><span class="nx">target</span><span class="p">);</span>
                <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="c1">// If not nothing we can do, but we can&#39;t </span>
                <span class="c1">// move to the tile</span>
                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="c1">// Check if we can walk on the tile</span>
        <span class="c1">// and if so simply walk onto it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isWalkable</span><span class="p">())</span> <span class="p">{</span>        
            <span class="c1">// Update the entity&#39;s position</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">y</span><span class="p">;</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="c1">// Check if the tile is diggable, and</span>
        <span class="c1">// if so try to dig it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isDiggable</span><span class="p">())</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">.</span><span class="nx">dig</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Our attacking system is now put in place! At this point you can go ahead and try it out! If everything went well you should be able to go up to a fungus on the map, walk into it and it will dissapear! In a few posts we'll turn this into a real attacking system with stats and health and all sorts of other goodies, but for it's pretty pleasing to see what we've already accomplished!</p>
<p>The next step is to implement the fungus growth. Recall last post that the scheduling system worked by calling the <em>act</em> method of entities turn by turn. We had created an actor mixin for the fungus, but it didn't do anything yet. As this is called every time the fungus has a turn, this seems like it could be the perfect place to put our spreading logic! </p>
<p>We want each fungus to be able to spread in one of the eight adjacent squares, however to make it interesting we don't want to do it every turn. Instead we are going to make it so that every turn the fungus has a fixed chance of growing. We're also going to want to limit the number of times a fungus can grow to let's say 5. Remember that mixins have an optional <em>init</em> function which can be called when the mixin is created to add state to the fungus. For now let's make it set up our state with a counter keeping trakc of how many times we can grow.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;FungusActor&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Actor&#39;</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_growthsRemaining</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> 
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>At every turn, if a fungus can still grow we use <em>Math.random</em>, which returns a number between 0.0 and 1.0, to determine if it should grow this turn. If so, then we generate the coordinates of a random adjacent square and check if we can grow to it. If we can, we will spawn a new fungus at that position and update our counters!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;FungusActor&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Actor&#39;</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_growthsRemaining</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> 
        <span class="c1">// Check if we are going to try growing this turn</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_growthsRemaining</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="mf">0.02</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Generate the coordinates of a random adjacent square by</span>
                <span class="c1">// generating an offset between [-1, 0, 1] for both the x and</span>
                <span class="c1">// y directions. To do this, we generate a number from 0-2 and then</span>
                <span class="c1">// subtract 1.</span>
                <span class="kd">var</span> <span class="nx">xOffset</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">3</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
                <span class="kd">var</span> <span class="nx">yOffset</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">3</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
                <span class="c1">// Make sure we aren&#39;t trying to spawn on the same tile as us</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">xOffset</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">yOffset</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                    <span class="c1">// Check if we can actually spawn at that location, and if so</span>
                    <span class="c1">// then we grow!</span>
                    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">isEmptyFloor</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">xOffset</span><span class="p">,</span>
                                                   <span class="k">this</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">yOffset</span><span class="p">))</span> <span class="p">{</span>
                        <span class="kd">var</span> <span class="nx">entity</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span><span class="p">);</span>
                        <span class="nx">entity</span><span class="p">.</span><span class="nx">setX</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">xOffset</span><span class="p">);</span>
                        <span class="nx">entity</span><span class="p">.</span><span class="nx">setY</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">yOffset</span><span class="p">);</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">addEntity</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
                        <span class="k">this</span><span class="p">.</span><span class="nx">_growthsRemaining</span><span class="o">--</span><span class="p">;</span>
                    <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>We are now just about ready to watch our fungus growth! We're going to reduce the map size as the fungus growing rapidly gets out of hand and depending on your computer may make movement very sluggish. So I've shrunk the map down to 100 by 48:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>  
        <span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="p">[];</span>
        <span class="c1">// Create a map based on our size parameters</span>
        <span class="kd">var</span> <span class="nx">mapWidth</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">mapHeight</span> <span class="o">=</span> <span class="mi">48</span><span class="p">;</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>We've now got a cave which gets overrun by fungus which our hero can then go and hack away with our simple attacking system! In the next post we are going to start focusing on real combat as well as giving some feedbak to the player through messages.</p>
<p>I hope you enjoyed this post and that you'll stick around for the next part! Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part5b">part 5b tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. Also please feel free to post any comments whether questions, clarifications or criticism!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Next Part</h1>
<p><a href="/2013/04/30/building-a-roguelike-in-javascript-part-6/">Part 6 - Combat and Messages</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/QaHgxB2RVE8" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/23/building-a-roguelike-in-javascript-part-5b</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 5a</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/Kmlb_EgJTxM/building-a-roguelike-in-javascript-part-5a</link>
      <pubDate>Mon, 22 Apr 2013 00:30:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/22/building-a-roguelike-in-javascript-part-5a</guid>
      <description>Building a Roguelike in Javascript - Part 5a</description>
      <content:encoded><![CDATA[<p>This is the sixth post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to <a href="http://trystans.blogspot.ca/2011/09/roguelike-tutorial-05-stationary.html">the fifth part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part5a">part 5a tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a> for rot.js <em>however there seemed to be an error in the rot.min.js file included in the github repository (it was missing ROT.Scheduler.Simple) so I fetched it again from the same commit</em>. You may need to do the same. It can be obtained <a href="https://github.com/ondras/rot.js/blob/d4ea2abb55432929aee1ed81cac10cebdda5aebb/rot.min.js">here</a>.</p>
<p>Today's going to be an exciting post! We are going to add more entities to our cave so that the player is not alone! This is going to be a pretty significant step towards populating our cave with a variety of terrifying monsters. To keep it simple our first monster will be a fungus. This fungus won't move for the moment and we can't currently walk through it, but in the next post it will spread over time and we'll be able to clear it by walking through it! I'm warning you ahead of time - this post is quite long, but builds some pretty fundamental stuff.</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part5a">here</a></p>
<h1>assets/entity.js</h1>
<p>Before we do anything, we're going to add an extra field to the Entity class. We want an entity to be associated with a map. Let's first update the constructor:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// Instantiate any properties from the passed object</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_name</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;y&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we'll also want our standard getter and setter:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setMap</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="nx">map</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getMap</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We are also going to add a way to group together mixins which offer a common interface. Consider the Moveable mixin we added last post. Suppose you wanted to have a ghost entity which could move through any type of cell and a molerat entity which could dig and move at the same time. Rather than creating an extremely complex and general Moveable mixin, we'd like to create a bunch of simple ones and just note that they offer the same common functionality. Once this is done, we'd like to be able to check if a mixin implements a given interface without being specific (eg. is it moveable rather than is it a ghost's moveable mixin). To do this we will add an optional <em>groupName</em> to mixins which acts similar to the name property but mixins implementing the same interface should have the same <em>groupName</em>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">PlayerMoveableMixin</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;PlayerMoveable&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">){...}</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">MoleratMoveableMixin</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;MoleratMoveable&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">){...}</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">GhostMoveableMixin</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;GhostMoveable&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">){...}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Ideally we'd like to be able to test both specifically for a given mixin by passing either the name or the mixin itself, as well as testing generally by passing the group name:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Testing specifically</span>
<span class="nx">entity</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;GhostMoveable&#39;</span><span class="p">)</span>
<span class="nx">entity</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="nx">GhostMoveableMixin</span><span class="p">)</span>

<span class="c1">// Testing generally </span>
<span class="nx">entity</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Moveable&#39;</span><span class="p">)</span>
</pre></div>
</td></tr></table>

<p>To implement this we must first update the constructor to keep track of the group names as well as the mixin names:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// Create an object which will keep track what mixins we have</span>
    <span class="c1">// attached to this entity based on the name property</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span> <span class="o">=</span> <span class="p">{};</span>
    <span class="c1">// Create a similar object for groups</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixinGroups</span> <span class="o">=</span> <span class="p">{};</span>
    <span class="c1">// Setup the object&#39;s mixins</span>
    <span class="kd">var</span> <span class="nx">mixins</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;mixins&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="p">[];</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">mixins</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Copy over all properties from each mixin as long</span>
        <span class="c1">// as it&#39;s not the name or the init property. We</span>
        <span class="c1">// also make sure not to override a property that</span>
        <span class="c1">// already exists on the entity.</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">])</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">key</span> <span class="o">!=</span> <span class="s1">&#39;init&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">key</span> <span class="o">!=</span> <span class="s1">&#39;name&#39;</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">key</span><span class="p">];</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// Add the name of this mixin to our attached mixins</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span><span class="p">[</span><span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        <span class="c1">// If a group name is present, add it</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">groupName</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixinGroups</span><span class="p">[</span><span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">groupName</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="c1">// Finally call the init function if there is one</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">init</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">init</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">properties</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Finally we need to update the <em>hasMixin</em> function to check the group names as well if we are checking with a string:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">hasMixin</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Allow passing the mixin itself or the name / group name as a string</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">obj</span> <span class="o">===</span> <span class="s1">&#39;object&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span><span class="p">[</span><span class="nx">obj</span><span class="p">.</span><span class="nx">name</span><span class="p">];</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span><span class="p">[</span><span class="nx">obj</span><span class="p">]</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixinGroups</span><span class="p">[</span><span class="nx">obj</span><span class="p">];</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/map.js</h1>
<p>We now need a way to keep track of our entities on the map. All our entities presently on the map are going to be stored in a list. We are also going to be using the <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Engine.html">ROT.Engine</a> and <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Scheduler.html">ROT.Scheduler</a> to manage our entities and make them take turns in the appropriate order. This system will be very important later on when entities start having different speeds so we will put it in the base right away. Let's update the constructor to reflect this:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tiles</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="c1">// create a list which will hold the entities</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="c1">// create the engine and scheduler</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Scheduler</span><span class="p">.</span><span class="nx">Simple</span><span class="p">();</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_engine</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Engine</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span><span class="p">);</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>We now want to provide a way to get the engine as well as all the entities on the map. Finally we'll need to be able to check if there is an entity at a given position.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getEngine</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_engine</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getEntities</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getEntityAt</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">){</span>
    <span class="c1">// Iterate through all entities searching for one with</span>
    <span class="c1">// matching position</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getX</span><span class="p">()</span> <span class="o">==</span> <span class="nx">x</span> <span class="o">&amp;&amp;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">getY</span><span class="p">()</span> <span class="o">==</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Before we can actually add entities to our maps, we need to look at how the scheduler actually works!</p>
<h1>Scheduling and the Game Loop</h1>
<p>The scheduling engine has a queue of all the entities and gives them a turn one by one. We're currently using the <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Scheduler.Simple.html">Simple scheduler</a> which simply gives the entities turns in the order they were added to the queue, and allows us to mark some entities as being re-added into the queue when their turn is complete. In the future we will use a more complicated scheduler which will allow us for some entities to act faster than others.</p>
<p>The <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Engine.html">ROT.Engine</a> object takes care of interacting with the scheduler and is started using <em>start</em>. It extracts the next entity from the scheduler and calls the <em>act</em> function on that entity, so we will need to define this function for all our entities that we want to be dynamic. We are going to do this with our mixin system we developed in the last post! Because of the nature of roguelikes, when it is the player's turn we want to wait until the player presses a key before we process the next turn. However the engine is continually running and so we won't be able to interact with our game if we simply start the engine! So when it is the player's turn we must <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Engine.html#lock">lock</a> the engine in order to wait for a key press, <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Engine.html#unlock">unlocking</a> it when we are done. </p>
<p>Just to clarify, let's consider the game loop. Up until now, our game loop has consisted of rendering the screen once and then waiting for input, processing said input and then re-rendering the screen. Our new game loop will be structured like this:</p>
<ol>
<li>Process all turns until it is the player's turn</li>
<li>Render the screen and lock the engine</li>
<li>Wait for a player to press a key, process it and then unlock the engine</li>
<li>Go back to step 1</li>
</ol>
<h1>assets/game.js</h1>
<p>In order to get set up for our new game loop, there are some things we need to change. First of all, we will make it so that the screen no longer automatically renders after we call the screen's <em>handleInput</em>. This means screens will have to make a call to rerender the screen whenever they want the screen to be updated. Remember that switching screens will automatically render the screen, so we don't have to change anything in the menu screen.</p>
<p>To do this, we have to edit the code for the <em>bindEventToScreen</em> function in <em>Game.init</em>:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="kd">var</span> <span class="nx">bindEventToScreen</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
            <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// When an event is received, send it to the</span>
                <span class="c1">// screen if there is one</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
                    <span class="c1">// Send the event type and data to the screen</span>
                    <span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">handleInput</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">e</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">});</span>
        <span class="p">}</span>
        <span class="c1">// ...</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We are now going to add a helper function called <em>refresh</em> which will clear the screen and render the current screen to our <em>Game</em> namespace.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">refresh</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Clear the screen</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_display</span><span class="p">.</span><span class="nx">clear</span><span class="p">();</span>
        <span class="c1">// Render the screen</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_display</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally we're going to update the code of our <em>switchScreen</em> function to use this refresh helper function to make sure we always go through the same route for re-rendering the screen.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">switchScreen</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">screen</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// If we had a screen before, notify it that we exited</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="c1">// Clear the display</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">getDisplay</span><span class="p">().</span><span class="nx">clear</span><span class="p">();</span>
        <span class="c1">// Update our current screen, notify it we entered</span>
        <span class="c1">// and then render it</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">=</span> <span class="nx">screen</span><span class="p">;</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">enter</span><span class="p">();</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">refresh</span><span class="p">();</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>This now gives us more control over when we re-render the screen, and will allow us to same some rendering calls in the future! If we made it so that the screen would render after each time we handled input, than we would end up re-rendering screen twice - once after handling the input and another time after processing all the turns.</p>
<h1>assets/entities.js</h1>
<p>We will be creating Actor mixins which will have a sole method <em>act</em>. We will use the group name <em>Actor</em> for all our actor mixins to allow us to easily check if a given entity needs to be scheduled. Let's create our player's actor mixin first. As I mentioned before we need to refresh the screen as well as lock the engine when it is the player's turn.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Main player&#39;s actor mixin</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">PlayerActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;PlayerActor&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Actor&#39;</span><span class="p">,</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Re-render the screen</span>
        <span class="nx">Game</span><span class="p">.</span><span class="nx">refresh</span><span class="p">();</span>
        <span class="c1">// Lock the engine and wait asynchronously</span>
        <span class="c1">// for the player to press a key.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">getMap</span><span class="p">().</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">lock</span><span class="p">();</span>        
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we have to add this mixin to our player's template!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span><span class="p">,</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">PlayerActor</span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We will also be creating an Actor mixin for the fungus. Notice that both actor mixins have the same group name!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;FungusActor&#39;</span><span class="p">,</span>
    <span class="nx">groupName</span><span class="o">:</span> <span class="s1">&#39;Actor&#39;</span><span class="p">,</span>
    <span class="nx">act</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We're going to create a template for our fungus entity! They will show us a <span style="color: green">F</span> on the screen, but feel free to play around with the template and make it look however you like! It's your game after all!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">FungusActor</span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally we're going to change our Moveable mixin to make it so that we can't walk through a tile if an entity is present at that tile.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">map</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">tile</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
        <span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getEntityAt</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
        <span class="c1">// If an entity was present at the tile, then we</span>
        <span class="c1">// can&#39;t move there</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
        <span class="c1">// Check if we can walk on the tile</span>
        <span class="c1">// and if so simply walk onto it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isWalkable</span><span class="p">())</span> <span class="p">{</span>        
            <span class="c1">// Update the entity&#39;s position</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">y</span><span class="p">;</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="c1">// Check if the tile is diggable, and</span>
        <span class="c1">// if so try to dig it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isDiggable</span><span class="p">())</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">.</span><span class="nx">dig</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/map.js</h1>
<p>We haven't actually provided a way to add an entity to our map yet! We're going to create a base function which allows us to add an entity to our map. In our function, we check if the entity is an Actor (thanks to our improvement), and if so we add them to the scheduler as well! We'll also want a method which adds an entity at a random position.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">addEntity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">entity</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Make sure the entity&#39;s position is within bounds</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">||</span>
        <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Adding entity out of bounds.&#39;</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// Update the entity&#39;s map</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setMap</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="c1">// Add the entity to the list of entities</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
    <span class="c1">// Check if this entity is an actor, and if so add</span>
    <span class="c1">// them to the scheduler</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">hasMixin</span><span class="p">(</span><span class="s1">&#39;Actor&#39;</span><span class="p">))</span> <span class="p">{</span>
       <span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">entity</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">entity</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">position</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span><span class="p">();</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setX</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">x</span><span class="p">);</span>
    <span class="nx">entity</span><span class="p">.</span><span class="nx">setY</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">y</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">addEntity</span><span class="p">(</span><span class="nx">entity</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We now have a fix to make to our function which generates a random floor position! We need to also check that there is no entity already present at the location we generated!:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Randomly generate a tile which is a floor</span>
    <span class="kd">var</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">;</span>
    <span class="k">do</span> <span class="p">{</span>
        <span class="nx">x</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
        <span class="nx">y</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">while</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">!=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">||</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">getEntityAt</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">));</span>
    <span class="k">return</span> <span class="p">{</span><span class="nx">x</span><span class="o">:</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">y</span><span class="p">};</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>The last part, and arguably the most important part, is that we must add our player entity as well as some fungus to the map! We will do this in the constructor before starting the engine, and in fact will modify the constructor to accept the player entity:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tiles</span><span class="p">,</span> <span class="nx">player</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">;</span>
    <span class="c1">// cache the width and height based</span>
    <span class="c1">// on the length of the dimensions of</span>
    <span class="c1">// the tiles array</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
    <span class="c1">// create a list which will hold the entities</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_entities</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="c1">// create the engine and scheduler</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Scheduler</span><span class="p">.</span><span class="nx">Simple</span><span class="p">();</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_engine</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Engine</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_scheduler</span><span class="p">);</span>
    <span class="c1">// add the player</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span><span class="p">(</span><span class="nx">player</span><span class="p">);</span>
    <span class="c1">// add random fungi</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">1000</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">addEntityAtRandomPosition</span><span class="p">(</span><span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">FungusTemplate</span><span class="p">));</span>
    <span class="p">}</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>We now need to update the <em>enter</em> function of the <em>playScreen</em> to pass our player to the map, as well as to start the engine.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>  
        <span class="c1">// ...</span>
        <span class="c1">// Create our map from the tiles and player</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">);</span>
        <span class="c1">// Start the map&#39;s engine</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">start</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We now need to change our rendering function to render all the map's entities as opposed to just the player. You're going to want to replace the player rendering with this snippet, which renders all visible entities:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>  
        <span class="c1">// ...</span>
        <span class="c1">// Render the entities</span>
        <span class="kd">var</span> <span class="nx">entities</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEntities</span><span class="p">();</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">entities</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="kd">var</span> <span class="nx">entity</span> <span class="o">=</span> <span class="nx">entities</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
            <span class="c1">// Only render the entitiy if they would show up on the screen</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">topLeftX</span> <span class="o">&amp;&amp;</span> <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">topLeftY</span> <span class="o">&amp;&amp;</span>
                <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">&lt;</span> <span class="nx">topLeftX</span> <span class="o">+</span> <span class="nx">screenWidth</span> <span class="o">&amp;&amp;</span>
                <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">&lt;</span> <span class="nx">topLeftY</span> <span class="o">+</span> <span class="nx">screenHeight</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span>
                    <span class="nx">entity</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">-</span> <span class="nx">topLeftX</span><span class="p">,</span> 
                    <span class="nx">entity</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">-</span> <span class="nx">topLeftY</span><span class="p">,</span>    
                    <span class="nx">entity</span><span class="p">.</span><span class="nx">getChar</span><span class="p">(),</span> 
                    <span class="nx">entity</span><span class="p">.</span><span class="nx">getForeground</span><span class="p">(),</span> 
                    <span class="nx">entity</span><span class="p">.</span><span class="nx">getBackground</span><span class="p">()</span>
                <span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>And the last step is to make our <em>handleInput</em> function unlock the map engine!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">inputType</span> <span class="o">===</span> <span class="s1">&#39;keydown&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// If enter is pressed, go to the win screen</span>
            <span class="c1">// If escape is pressed, go to lose screen</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RETURN</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">winScreen</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_ESCAPE</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">loseScreen</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="c1">// Movement</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_LEFT</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RIGHT</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_UP</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_DOWN</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="c1">// Unlock the engine</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getEngine</span><span class="p">().</span><span class="nx">unlock</span><span class="p">();</span>
            <span class="p">}</span>
        <span class="p">}</span>    
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>Our game is now actually starting to ressemble a real game! We can walk around a cave filled with fungi! We are also set up for having many entities on a given map, and our small adjustement to the mixin system has made it much easier to create simple but powerful mixins.</p>
<p>I hope you enjoyed this post and that you'll stick around for the next part! I'm sorry for the length of the last two posts, I will try to keep it down in the future. I'd just hate to finish off a post with something you couldn't use! Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part5a">part 5a tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. Also please feel free to post any comments whether questions, clarifications or criticism!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Next Part</h1>
<p><a href="/2013/04/23/building-a-roguelike-in-javascript-part-5b">Part 5b - Attacking Spreading Fungi</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/Kmlb_EgJTxM" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/22/building-a-roguelike-in-javascript-part-5a</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 4</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/GrLUft6dne8/building-a-roguelike-in-javascript-part-4</link>
      <pubDate>Sat, 20 Apr 2013 22:30:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/20/building-a-roguelike-in-javascript-part-4</guid>
      <description>Building a Roguelike in Javascript - Part 4</description>
      <content:encoded><![CDATA[<p>This is the fifth post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to <a href="http://trystans.blogspot.ca/2011/08/roguelike-tutorial-04-player.html">the fourth part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part4">part 4 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a> for rot.js.</p>
<p>Now that we've got some interesting caves we want a hero so that we can play our game and explore the dark depths of the caves! In this post we'll lay down the foundation for the characters in the game (which we'll call entities) and by the end of it we'll use this system to add our player to the map. If you played around with the demo from the last post you may have noticed that the caves aren't always fully connected. We want our hero to start the game in a random part of the cave every time so we're going to need to make a way so that the player isn't stuck if they can't get to one part of the cave. Our hero will be able to dig through walls in the cave in order to avoid ever getting stuck. Once we add lighting to the game this is going to be a really neat part of the game as we will have to explore and dig through walls without knowing what's on the other side! </p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part4">here</a></p>
<h1>assets/glyph.js</h1>
<p>First things first we have a small bit of refactoring to do! In <a href="/2013/04/05/building-a-roguelike-in-javascript-part-3a/">part 3a</a> we introduced the <em>Glyph</em> type , which had a constructor that accepted 3 arguments (character, foreground and background). However this isn't very flexible and isn't taking advantage of the features in Javascript! We are going to change this so that it accepts a simple Javascript object such as:</p>
<pre><code>{
    character: '@',
    foreground: 'white',
    background: 'black'
}
</code></pre>
<p><br/>
Why is this better? We are going to want to extend the <em>Glyph</em> later on for characters, items, and all sorts of fancy features. By passing a Javascript object to our constructor (and making sure it gets passed to the parent class as well) we can quickly instantiate objects with the right properties while providing defaults if a given property isn't there. This was inspired by a similar method used in <a href="http://ondras.zarovi.cz/games/trw/">The Royal Wedding</a>, a fantastic open-source roguelike written using rot.js which I encourage you to check out. We simply have to update our constructor like so:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Instantiate properties to default if they weren&#39;t passed</span>
    <span class="nx">properties</span> <span class="o">=</span> <span class="nx">properties</span> <span class="o">||</span> <span class="p">{};</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_char</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;character&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39; &#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_foreground</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;foreground&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;white&#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_background</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;background&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;black&#39;</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<h1>assets/tile.js</h1>
<p>As our constructor has changed we have to update the code where we created glyphs for our tiles to use a Javascript object. While we're in the tile file, we're also going to need to add some notion of whether a tile can be walked on as well as whether a tile can be dug through. In order to do this, we're going to make <em>Game.Tile</em> extend <em>Game.Glyph</em> and accept a Javascript object in the constructor as well! This will allow us to define tiles in a much simpler fashion:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">({</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;#&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;goldenrod&#39;</span><span class="p">,</span>
    <span class="nx">isDiggable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">})</span>
</pre></div>
</td></tr></table>

<p>So let's go ahead and update that code:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">properties</span> <span class="o">=</span> <span class="nx">properties</span> <span class="o">||</span> <span class="p">{};</span>
    <span class="c1">// Call the Glyph constructor with our properties</span>
    <span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">properties</span><span class="p">);</span>
    <span class="c1">// Set up the properties. We use false by default.</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_isWalkable</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;isWalkable&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="kc">false</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_isDiggable</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;isDiggable&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">};</span>
<span class="c1">// Make tiles inherit all the functionality from glyphs</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">);</span>

<span class="c1">// Standard getters</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">isWalkable</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_isWalkable</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">isDiggable</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_isDiggable</span><span class="p">;</span>
<span class="p">}</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">({})</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">({</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;.&#39;</span><span class="p">,</span>
    <span class="nx">isWalkable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">({</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;#&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;goldenrod&#39;</span><span class="p">,</span>
    <span class="nx">isDiggable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>

<p>Note that because we removed the <em>getGlyph</em> method (as it directly extends Glyph) we're going to have to fix up the rendering. <strong>This will be done later in the post so have no worries!</strong></p>
<h1>assets/entity.js</h1>
<p>We are now ready to define an <em>entity</em>. In its most basic form, an entity is composed of a glyph as well as a position and a name (used in messages). It will be the base object for nearly everything that can be seen on the screen and can be interacted with. This is similar to Trystan's <em>Creature</em> class however we're going to try avoiding traditional inheritance and instead taking advantage of the powers of Javascript.</p>
<p>Because anything can be an entity, for example the hero, a potion on the ground, or a wildebeest, we're going to need some way of giving certain behaviors to different entities. For this we're going to use something similar to <a href="http://en.wikipedia.org/wiki/Mixin">mixins</a> which are small sets of functions and state that we can add to certain entities to give them certain behaviors. This was inspired by <a href="http://stevelosh.com/blog/2012/07/caves-of-clojure-04/">Steve Losh's Caves of Clojue approach</a>. One example of a mixin defines an entity as moveable, giving it functions for moving and checking valid moves. Another example is defining an entity as a container of other entities. This could be used for an entity representing a chest, but could also be used for more strange things such as a chicken containing egg items. </p>
<p>For now we will first focus on creating a basic entity class which extends a glyph with a position and a name:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">properties</span> <span class="o">=</span> <span class="nx">properties</span> <span class="o">||</span> <span class="p">{};</span>
    <span class="c1">// Call the glyph&#39;s construtor with our set of properties</span>
    <span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">properties</span><span class="p">);</span>
    <span class="c1">// Instantiate any properties from the passed object</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_name</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;y&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Make entities inherit all the functionality from glyphs</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">);</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setName</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setX</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setY</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">y</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getName</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_name</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getX</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_x</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getY</span>   <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_y</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>A mixin will be a simple Javascript object which will be attached to each entity that chooses it. Note that we will set it up so that <strong>this</strong> can be used in the mixin objects to refer to the calling entity. Each mixin can have an <em>init</em> function which is called when we create a new entity and attach that mixin, and it will pass the same Javascript object to the init function that was used to create the entity (like the object used to create a Glyph above). A mixin must also have a <em>name</em> attribute which will be useful when we try to determine if a player has a given mixin. This is going to make our code base a bit more complicated, but I believe it will be very useful for us to easily assign bits and pieces of functionality to different entities. The whole reason we are doing this is so that we avoid rewriting code and to make sure we don't have objects bloated with functions and state they'll never use. Try to bear with me, and if there is anything unclear please post a comment and let me know! I'd be glad to help!</p>
<p>Here is an example of a mixin which would keep track of the number of hits an entity has made, just to give you an idea of how they will work. It will also give an example of adding state to the entity via the <em>init</em> function by storing a simple multiplier. <strong>You do not need to add this code anywhere, it is just an example of how we are going to use the system.</strong></p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">HitCounter</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;HitCounter&#39;</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Add state to the entity and read from the properties</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_multiplier</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;multiplier&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">1</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_hits</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">incrementHit</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Update state</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_hits</span> <span class="o">+=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_multiplier</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="nx">getTotalHits</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hits</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Ideally we would like to specify what mixins an entity has when we create it via the Javascript object we pass. We will add a field called <em>mixins</em> containing an array of mixins which will be automatically attached to the entity. Once we attach a mixin to an entity, all the mixin functions are available directly from our entity! For example to create and use an entity which had the <em>HitCounter</em> mixin:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">e</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">({</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;blue&#39;</span><span class="p">,</span>
    <span class="nx">x</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span>
    <span class="nx">y</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Test Entity&#39;</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">HitCounter</span><span class="p">],</span>
    <span class="nx">multiplier</span><span class="o">:</span> <span class="mi">5</span>
<span class="p">})</span>

<span class="nx">e</span><span class="p">.</span><span class="nx">incrementHit</span><span class="p">();</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">incrementHit</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">getTotalHits</span><span class="p">());</span>
</pre></div>
</td></tr></table>

<p>In order to do this we're going to modify our Entity constructor to process this array of mixins. Note that we will also store the name of each mixin we attached in an object so that we can quickly look up if an Entity has a given set of functionalities (similar to the instanceof keyword). So you're going to want to change the constructor to look like this:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">properties</span> <span class="o">=</span> <span class="nx">properties</span> <span class="o">||</span> <span class="p">{};</span>
    <span class="c1">// Call the glyph&#39;s construtor with our set of properties</span>
    <span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">properties</span><span class="p">);</span>
    <span class="c1">// Instantiate any properties from the passed object</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_name</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;y&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
    <span class="c1">// Create an object which will keep track what mixins we have</span>
    <span class="c1">// attached to this entity based on the name property</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span> <span class="o">=</span> <span class="p">{};</span>
    <span class="c1">// Setup the object&#39;s mixins</span>
    <span class="kd">var</span> <span class="nx">mixins</span> <span class="o">=</span> <span class="nx">properties</span><span class="p">[</span><span class="s1">&#39;mixins&#39;</span><span class="p">]</span> <span class="o">||</span> <span class="p">[];</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">mixins</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Copy over all properties from each mixin as long</span>
        <span class="c1">// as it&#39;s not the name or the init property. We</span>
        <span class="c1">// also make sure not to override a property that</span>
        <span class="c1">// already exists on the entity.</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">])</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">key</span> <span class="o">!=</span> <span class="s1">&#39;init&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">key</span> <span class="o">!=</span> <span class="s1">&#39;name&#39;</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">key</span><span class="p">];</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// Add the name of this mixin to our attached mixins</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span><span class="p">[</span><span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        <span class="c1">// Finally call the init function if there is one</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">init</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">mixins</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">init</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">properties</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally we're going to add a method to the Entity class which allows us to check if a given entity has a given mixin. We're going to make it so we can either pass the mixin itself or just the name, and it'll check the <em>_attachedMixins</em> object in the entity:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">hasMixin</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Allow passing the mixin itself or the name as a string</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">obj</span> <span class="o">===</span> <span class="s1">&#39;object&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span><span class="p">[</span><span class="nx">obj</span><span class="p">.</span><span class="nx">name</span><span class="p">];</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_attachedMixins</span><span class="p">[</span><span class="nx">name</span><span class="p">];</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now that we've got our entity system all set up, we're ready to create our player! The only problem right now is that we have no functions in the <em>Game.Map</em> object for checking whether we can move and dig through a given tile. Let's go ahead and create that first!</p>
<h1>assets/map.js</h1>
<p>We simply want to add a function that digs at a given tile. We have to check that the tile is actually diggable, and if so we then convert it to a floor tile!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">dig</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// If the tile is diggable, update it to a floor</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">).</span><span class="nx">isDiggable</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>As our player will start in a random position in the cave, we're going to add in a function which will generate a random position which has a floor tile:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Randomly generate a tile which is a floor</span>
    <span class="kd">var</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">;</span>
    <span class="k">do</span> <span class="p">{</span>
        <span class="nx">x</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
        <span class="nx">y</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">while</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">!=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">);</span>
    <span class="k">return</span> <span class="p">{</span><span class="nx">x</span><span class="o">:</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">y</span><span class="p">};</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/entities.js</h1>
<p>We are now ready to create our player and it's related mixins! The first thing we are going to do is create a mixin for moving. This mixin will simply have a <em>tryMove</em> function which accepts a position as well as the current map and tries to move in a given direction. If the entity cannot move through a tile but can dig, it will dig the tile instead. Finally the function will return true if there was a succesful action (moving or digging).</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Create our Mixins namespace</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span> <span class="o">=</span> <span class="p">{};</span>

<span class="c1">// Define our Moveable mixin</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Moveable&#39;</span><span class="p">,</span>
    <span class="nx">tryMove</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">map</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">tile</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
        <span class="c1">// Check if we can walk on the tile</span>
        <span class="c1">// and if so simply walk onto it</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isWalkable</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// Update the entity&#39;s position</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_x</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_y</span> <span class="o">=</span> <span class="nx">y</span><span class="p">;</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="c1">// Check if the tile is diggable, and</span>
        <span class="c1">// if so try to dig it</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tile</span><span class="p">.</span><span class="nx">isDiggable</span><span class="p">())</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">.</span><span class="nx">dig</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
            <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We are now ready to define our player entity! For now we will simply make the Javascript object that is used to create the player a variable in the <em>Game</em> namespace but this will be refactored in a future entry as soon as we want to have multiple entities. This will also show how the raw Javascript objects can act as templates for entities that can be reused:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Player template</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">character</span><span class="o">:</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span>
    <span class="nx">foreground</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
    <span class="nx">background</span><span class="o">:</span> <span class="s1">&#39;black&#39;</span><span class="p">,</span>
    <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Mixins</span><span class="p">.</span><span class="nx">Moveable</span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>We are now ready to change our screen to work with our new Player! The first things we are going to do is <strong>remove the centerX/centerY properties and add a player property</strong> to the <em>PlayScreen</em>:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">_map</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">_player</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> 
        <span class="c1">// ...</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now at the end of our <em>enter</em> function, after we create the map, we want to create our player based on our template and then position the hero inside the cave!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> 
        <span class="c1">// ...</span>
        <span class="c1">// Create our map from the tiles</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>
        <span class="c1">// Create our player and set the position</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Entity</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">PlayerTemplate</span><span class="p">);</span>
        <span class="kd">var</span> <span class="nx">position</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getRandomFloorPosition</span><span class="p">();</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">setX</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">x</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">setY</span><span class="p">(</span><span class="nx">position</span><span class="p">.</span><span class="nx">y</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we have to update our <em>render</em> function for two reasons. First we no longer need <em>centerX/centerY</em> and instead should use the player's position for determining the camera offsets as well as rendering the player! Secondly we have to change how tiles are rendered as tiles now extend glyphs!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
   <span class="c1">// ...</span>
   <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">screenWidth</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getScreenWidth</span><span class="p">();</span>
        <span class="kd">var</span> <span class="nx">screenHeight</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getScreenHeight</span><span class="p">();</span>
        <span class="c1">// Make sure the x-axis doesn&#39;t go to the left of the left bound</span>
        <span class="kd">var</span> <span class="nx">topLeftX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">-</span> <span class="p">(</span><span class="nx">screenWidth</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
        <span class="c1">// Make sure we still have enough space to fit an entire game screen</span>
        <span class="nx">topLeftX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">topLeftX</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getWidth</span><span class="p">()</span> <span class="o">-</span> <span class="nx">screenWidth</span><span class="p">);</span>
        <span class="c1">// Make sure the y-axis doesn&#39;t above the top bound</span>
        <span class="kd">var</span> <span class="nx">topLeftY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">-</span> <span class="p">(</span><span class="nx">screenHeight</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
        <span class="c1">// Make sure we still have enough space to fit an entire game screen</span>
        <span class="nx">topLeftY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">topLeftY</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getHeight</span><span class="p">()</span> <span class="o">-</span> <span class="nx">screenHeight</span><span class="p">);</span>
        <span class="c1">// Iterate through all visible map cells</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="nx">topLeftX</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">topLeftX</span> <span class="o">+</span> <span class="nx">screenWidth</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="nx">topLeftY</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">topLeftY</span> <span class="o">+</span> <span class="nx">screenHeight</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Fetch the glyph for the tile and render it to the screen</span>
                <span class="c1">// at the offset position.</span>
                <span class="kd">var</span> <span class="nx">tile</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
                <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span>
                    <span class="nx">x</span> <span class="o">-</span> <span class="nx">topLeftX</span><span class="p">,</span>
                    <span class="nx">y</span> <span class="o">-</span> <span class="nx">topLeftY</span><span class="p">,</span>
                    <span class="nx">tile</span><span class="p">.</span><span class="nx">getChar</span><span class="p">(),</span> 
                    <span class="nx">tile</span><span class="p">.</span><span class="nx">getForeground</span><span class="p">(),</span> 
                    <span class="nx">tile</span><span class="p">.</span><span class="nx">getBackground</span><span class="p">())</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// Render the player</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">-</span> <span class="nx">topLeftX</span><span class="p">,</span> 
            <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">-</span> <span class="nx">topLeftY</span><span class="p">,</span>    
            <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getChar</span><span class="p">(),</span> 
            <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getForeground</span><span class="p">(),</span> 
            <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getBackground</span><span class="p">()</span>
        <span class="p">);</span>
    <span class="p">},</span>
    <span class="c1">// ... </span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>1
Our last step is to change the <em>move</em> function to interact with our new entity and it's Moveable mixin! Recall that the <em>move</em> function accepts an offset in the x and y direction and so we should recalculate the new position based on these offsets and then call the tryMove method! Also note that the screen automatically re-renders when we handle input, so we don't have to worry about calling it ourselves!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">move</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dX</span><span class="p">,</span> <span class="nx">dY</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">newX</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getX</span><span class="p">()</span> <span class="o">+</span> <span class="nx">dX</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">newY</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">getY</span><span class="p">()</span> <span class="o">+</span> <span class="nx">dY</span><span class="p">;</span>
        <span class="c1">// Try to move to the new cell</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_player</span><span class="p">.</span><span class="nx">tryMove</span><span class="p">(</span><span class="nx">newX</span><span class="p">,</span> <span class="nx">newY</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>index.html</h1>
<p>We are almost done! We just have to add our new scripts!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="pygments_murphy"><pre>    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/entity.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/entities.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>We've now done a huge step! We now have a player who can dig around and move around the caves! We've also done something much more important though - we set up a general framework for pretty much every interactive entity on the screen! I'm hoping that this combination of mixins and Javascript objects will turn out to be very practical and I hope it also showed you just how neat Javascript can be. The system can easily be extended to do things such as allow mixin inheritance (for example having a Mixin which extends another Mixin), but for the sake of simplicity and shortness I will try to avoid overcomplicating it.</p>
<p>I hope you enjoyed this post and that you'll stick around for the next part! It's going to get very interesting, I promise you! Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part4">part 4 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. Also please feel free to post any comments whether questions, clarifications or criticism!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Next Part</h1>
<p><a href="/2013/04/22/building-a-roguelike-in-javascript-part-5a/">Part 5a - Populating the Cave</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/GrLUft6dne8" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/20/building-a-roguelike-in-javascript-part-4</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 3b</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/I5ZtMKhhN7M/building-a-roguelike-in-javascript-part-3b</link>
      <pubDate>Sun, 07 Apr 2013 13:00:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/07/building-a-roguelike-in-javascript-part-3b</guid>
      <description>Building a Roguelike in Javascript - Part 3b</description>
      <content:encoded><![CDATA[<p>This is the fourth post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to the map scrolling segment of <a href="http://trystans.blogspot.ca/2011/08/roguelike-tutorial-03-scrolling-through.html">the third part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part3b">part 3b tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a> for rot.js.</p>
<p>Just to quickly recap <a href="/2013/04/05/building-a-roguelike-in-javascript-part-3a/">last post</a> we created a cave and made it show up in our Play screen. This works really nicely and makes random caves every time we refresh the game, but we'd like to be able to have levels that are bigger than the screen! This is usually done by centering the screen on our player and only showing the nearby area! We don't have the notion of a player yet, and that will only be really implemented in the next post, but for now we'll want to center the screen at a given x and y position which can be moved around using the keys! By the end of this post we'll be generating huge caves and we'll be able to move around them and explore them!</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part3b">here</a></p>
<h1>assets/game.js</h1>
<p>Before we start, we're going to do a small bit of refactoring. Rather than hardcoding our screen size, we're going to store it as variables in the <em>Game</em> namespace which can be accessed globally. We're going to keep track of how wide and tall our screen is in cells:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span>  <span class="p">{</span>
    <span class="nx">_display</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">_currentScreen</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">_screenWidth</span><span class="o">:</span> <span class="mi">80</span><span class="p">,</span>
    <span class="nx">_screenHeight</span><span class="o">:</span> <span class="mi">24</span><span class="p">,</span>
    <span class="c1">//...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we have to modify our <em>init</em> function to use these variables rather than the hardcoded values:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Any necessary initialization will go here.</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenWidth</span><span class="p">,</span>
                                     <span class="nx">height</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenHeight</span><span class="p">});</span>
    <span class="c1">// Create a helper function for binding to an event</span>
    <span class="c1">// and making it send it to the screen</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally, we want to create globally accessible functions, similar to <em>getDisplay</em>, which will allow other files (eg. inside our Screen objects) to get the width and height:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">getDisplay</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_display</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">getScreenWidth</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenWidth</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">getScreenHeight</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenHeight</span><span class="p">;</span>
<span class="p">},</span>
</pre></div>
</td></tr></table>

<p>This is a great little change to put in place early, and if we are consistent in using these functions elsewhere in our code, will allow us to change our screen size (think mobile!) without any headaches.</p>
<h1>assets/screens.js</h1>
<p>The first thing we want to do is create big maps! Let's change our map generating code in the <em>PlayScreen</em>'s <em>enter</em> function so that we generate maps that are 500 cells wide and 500 cells tall:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">_map</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>  
        <span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="p">[];</span>
        <span class="c1">// Create a map based on our size parameters</span>
        <span class="kd">var</span> <span class="nx">mapWidth</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">mapHeight</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">mapWidth</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Create the nested array for the y values</span>
            <span class="nx">map</span><span class="p">.</span><span class="nx">push</span><span class="p">([]);</span>
            <span class="c1">// Add all the tiles</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">mapHeight</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// Setup the map generator</span>
        <span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">Cellular</span><span class="p">(</span><span class="nx">mapWidth</span><span class="p">,</span> <span class="nx">mapHeight</span><span class="p">);</span>
        <span class="nx">generator</span><span class="p">.</span><span class="nx">randomize</span><span class="p">(</span><span class="mf">0.5</span><span class="p">);</span>
        <span class="kd">var</span> <span class="nx">totalIterations</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
        <span class="c1">// Iteratively smoothen the map</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">totalIterations</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="c1">// Smoothen it one last time and then update our map</span>
        <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">,</span><span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">});</span>
        <span class="c1">// Create our map from the tiles</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="c1">//...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>This will now generate big maps for us! However we can't render it all because it's bigger than the screen, so we're going to make it so that we only see part of the screen at once. As I mentioned above, we will keep track of where our cursor currently is on the screen using x and y coordinates, so we must add these as variables of the screen. Initially we are going to start at the top left corner of the map:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">_map</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">_centerX</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
    <span class="nx">_centerY</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we'll want to be able to move our player in any direction. So for now, to keep things simple, we'll create a function allowing us to move in the x and y direction by a certain amount of cells. For example, if we want to move down by 2, it would be <em>move(0, 2)</em>. If we want to move left by 1, it would be <em>move(-1, 0)</em>. We also want to make sure the player stays in the bounds of the map, so we use <em>Math.min</em> and <em>Math.max</em> to make sure it says between 0 and the map width / height. Note that we have to subtract 1 from the map's width and height to get the real index of the last cell as arrays are 0-based.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">move</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dX</span><span class="p">,</span> <span class="nx">dY</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Positive dX means movement right</span>
        <span class="c1">// negative means movement left</span>
        <span class="c1">// 0 means none</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_centerX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span>
            <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getWidth</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_centerX</span> <span class="o">+</span> <span class="nx">dX</span><span class="p">));</span>
        <span class="c1">// Positive dY means movement down</span>
        <span class="c1">// negative means movement up</span>
        <span class="c1">// 0 means none</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_centerY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span>
            <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getHeight</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_centerY</span> <span class="o">+</span> <span class="nx">dY</span><span class="p">));</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we're going to update our <em>handleInput</em> function so that we can actually move our player around using the arrow keys! As a small challenge, you should try to re-do this code so that it uses your preferred method of movement (WASD, HJKL, using the numpad, etc.). Remember that you can see all the key constants <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.html">here</a> (they all start with <strong>VK_</strong>). </p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">inputType</span> <span class="o">===</span> <span class="s1">&#39;keydown&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// If enter is pressed, go to the win screen</span>
            <span class="c1">// If escape is pressed, go to lose screen</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RETURN</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">winScreen</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_ESCAPE</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">loseScreen</span><span class="p">);</span>
            <span class="p">}</span>
            <span class="c1">// Movement</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_LEFT</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RIGHT</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_UP</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_DOWN</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>    
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>So now we have a cursor that can move around the screen! Great! But we haven't changed our rendering yet, so nothing actually looks different! We're going to rewrite our render function so that it matches our new scrolling system! The first thing we have to do is determine what cells to render. We already know how many cells wide and tall we need to render thanks to our refactoring we did at the beginning, but what cell will go in the left corner? A pretty common strategy for this is to center the screen based on where the player is. So we want our top corner to be one half of a screen's width to the left and one half of a screen's height up from our center x and y. There's also an extra consideration - what do we do when the player is less than half a screen's width away from the bound, for example if they are at x = 5 and the screen's width is 80? What we're going to do is stop scrolling if we can't fit half a screen on all sides of the player. So for the left and top bound, we want to make sure our top left corner is at a position of at least x = 0 and y = 0 (can't have negative positions!). For our right and bottom bound, we want to make sure our top left corner can still fit the entire screen. So let's write some code for determining the top left corner first! Note that because we are working with halfs of a screen, it's generally a good idea to <em>make your screen width and height even numbers</em>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">screenWidth</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getScreenWidth</span><span class="p">();</span>
        <span class="kd">var</span> <span class="nx">screenHeight</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getScreenHeight</span><span class="p">();</span>
        <span class="c1">// Make sure the x-axis doesn&#39;t go to the left of the left bound</span>
        <span class="kd">var</span> <span class="nx">topLeftX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_centerX</span> <span class="o">-</span> <span class="p">(</span><span class="nx">screenWidth</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
        <span class="c1">// Make sure we still have enough space to fit an entire game screen</span>
        <span class="nx">topLeftX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">topLeftX</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getWidth</span><span class="p">()</span> <span class="o">-</span> <span class="nx">screenWidth</span><span class="p">);</span>
        <span class="c1">// Make sure the y-axis doesn&#39;t above the top bound</span>
        <span class="kd">var</span> <span class="nx">topLeftY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_centerY</span> <span class="o">-</span> <span class="p">(</span><span class="nx">screenHeight</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
        <span class="c1">// Make sure we still have enough space to fit an entire game screen</span>
        <span class="nx">topLeftY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">topLeftY</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getHeight</span><span class="p">()</span> <span class="o">-</span> <span class="nx">screenHeight</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now that we've figured out our top left cell, we can render the cells like we were doing before! We have to change the bounds of our for nested for loops which traverse the map so that we start at our top left cell and render one screen. We also have to make it so that when we draw a tile, we draw it relative to the top left cell (ie. render it at x - topLeftX rather than x).</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Iterate through all visible map cells</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="nx">topLeftX</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">topLeftX</span> <span class="o">+</span> <span class="nx">screenWidth</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="nx">topLeftY</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">topLeftY</span> <span class="o">+</span> <span class="nx">screenHeight</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Fetch the glyph for the tile and render it to the screen</span>
        <span class="c1">// at the offset position.</span>
        <span class="kd">var</span> <span class="nx">glyph</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">).</span><span class="nx">getGlyph</span><span class="p">();</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span>
            <span class="nx">x</span> <span class="o">-</span> <span class="nx">topLeftX</span><span class="p">,</span>
            <span class="nx">y</span> <span class="o">-</span> <span class="nx">topLeftY</span><span class="p">,</span>
            <span class="nx">glyph</span><span class="p">.</span><span class="nx">getChar</span><span class="p">(),</span> 
            <span class="nx">glyph</span><span class="p">.</span><span class="nx">getForeground</span><span class="p">(),</span> 
            <span class="nx">glyph</span><span class="p">.</span><span class="nx">getBackground</span><span class="p">());</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally we can scroll around our map! However while we're modifying our rendering function, let's add a call after we render the map to render our cursor (represented by @). We have to offset the rendering position as we want to know where to render our cursor relative to the top left cell and not the 0,0 cell! Our render function should know look like:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">screenWidth</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getScreenWidth</span><span class="p">();</span>
        <span class="kd">var</span> <span class="nx">screenHeight</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">getScreenHeight</span><span class="p">();</span>
        <span class="c1">// Make sure the x-axis doesn&#39;t go to the left of the left bound</span>
        <span class="kd">var</span> <span class="nx">topLeftX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_centerX</span> <span class="o">-</span> <span class="p">(</span><span class="nx">screenWidth</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
        <span class="c1">// Make sure we still have enough space to fit an entire game screen</span>
        <span class="nx">topLeftX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">topLeftX</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getWidth</span><span class="p">()</span> <span class="o">-</span> <span class="nx">screenWidth</span><span class="p">);</span>
        <span class="c1">// Make sure the y-axis doesn&#39;t above the top bound</span>
        <span class="kd">var</span> <span class="nx">topLeftY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_centerY</span> <span class="o">-</span> <span class="p">(</span><span class="nx">screenHeight</span> <span class="o">/</span> <span class="mi">2</span><span class="p">));</span>
        <span class="c1">// Make sure we still have enough space to fit an entire game screen</span>
        <span class="nx">topLeftY</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">topLeftY</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getHeight</span><span class="p">()</span> <span class="o">-</span> <span class="nx">screenHeight</span><span class="p">);</span>
        <span class="c1">// Iterate through all visible map cells</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="nx">topLeftX</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">topLeftX</span> <span class="o">+</span> <span class="nx">screenWidth</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="nx">topLeftY</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">topLeftY</span> <span class="o">+</span> <span class="nx">screenHeight</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Fetch the glyph for the tile and render it to the screen</span>
                <span class="c1">// at the offset position.</span>
                <span class="kd">var</span> <span class="nx">glyph</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">).</span><span class="nx">getGlyph</span><span class="p">();</span>
                <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span>
                    <span class="nx">x</span> <span class="o">-</span> <span class="nx">topLeftX</span><span class="p">,</span>
                    <span class="nx">y</span> <span class="o">-</span> <span class="nx">topLeftY</span><span class="p">,</span>
                    <span class="nx">glyph</span><span class="p">.</span><span class="nx">getChar</span><span class="p">(),</span> 
                    <span class="nx">glyph</span><span class="p">.</span><span class="nx">getForeground</span><span class="p">(),</span> 
                    <span class="nx">glyph</span><span class="p">.</span><span class="nx">getBackground</span><span class="p">());</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="c1">// Render the cursor</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">_centerX</span> <span class="o">-</span> <span class="nx">topLeftX</span><span class="p">,</span> 
            <span class="k">this</span><span class="p">.</span><span class="nx">_centerY</span> <span class="o">-</span> <span class="nx">topLeftY</span><span class="p">,</span>
            <span class="s1">&#39;@&#39;</span><span class="p">,</span>
            <span class="s1">&#39;white&#39;</span><span class="p">,</span>
            <span class="s1">&#39;black&#39;</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now let's refresh our page! Look at that, there's our cursor in the top left! Now le's try to move it around... uh oh! It's not moving!</p>
<h1>assets/game.js</h1>
<p>You may recall from the <a href="/2013/04/03/building-a-roguelike-in-javascript-part-2/">Screen Management entry</a> that the <em>handleInput</em> function gets called whenever an input event is received. However after we handle input, we don't actually re-render the screen! So even though our cursor is moving we don't actually see it moving! Let's rewrite our <em>Game.init</em> function to make sure we call render after we handle the input. Note that I've also commented out the <em>keyup</em> and <em>keypress</em> handlers for now as we're not using them. </p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// ...</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Any necessary initialization will go here.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenWidth</span><span class="p">,</span>
                                         <span class="nx">height</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_screenHeight</span><span class="p">});</span>
        <span class="c1">// Create a helper function for binding to an event</span>
        <span class="c1">// and making it send it to the screen</span>
        <span class="kd">var</span> <span class="nx">game</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span> <span class="c1">// So that we don&#39;t lose this</span>
        <span class="kd">var</span> <span class="nx">bindEventToScreen</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
            <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// When an event is received, send it to the</span>
                <span class="c1">// screen if there is one</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
                    <span class="c1">// Send the event type and data to the screen</span>
                    <span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">handleInput</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">e</span><span class="p">);</span>
                    <span class="c1">// Clear the screen</span>
                    <span class="nx">game</span><span class="p">.</span><span class="nx">_display</span><span class="p">.</span><span class="nx">clear</span><span class="p">();</span>
                    <span class="c1">// Render the screen</span>
                    <span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">game</span><span class="p">.</span><span class="nx">_display</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">});</span>
        <span class="p">}</span>
        <span class="c1">// Bind keyboard input events</span>
        <span class="nx">bindEventToScreen</span><span class="p">(</span><span class="s1">&#39;keydown&#39;</span><span class="p">);</span>
        <span class="c1">//bindEventToScreen(&#39;keyup&#39;);</span>
        <span class="c1">//bindEventToScreen(&#39;keypress&#39;);</span>
    <span class="p">},</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Note that we may refactor this code at some point in the future to only re-render the screen when it's required, but for now this will do!</p>
<h1>Conclusion</h1>
<p>We now have a cursor that lets us explore the caves! The next post will focus on converting this cursor to an actual player, and will be a big step up for our game. Play around with it, generating random caves and resizing the map as well.</p>
<p>Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part3b">part 3b tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. I hope you enjoyed this post and that you'll stick around for the next part!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Extra</h1>
<p>In the last post, I mentioned there were a variety of map generators provided in rot.js. I just tought I would give you an example of using a different one if you wanted to play around with it. This little extra section will be changing the map generator to use <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Map.Uniform.html">ROT.Map.Uniform</a> which generate maps more similar to games like Nethack. Note that for now the actual posts will be using the <a href="http://ondras.github.io/rot.js/doc/symbols/ROT.Map.Cellular.html">ROT.Map.Cellular</a> generator. This is simply for fun!</p>
<p>In our <strong>assets/screens.js</strong> file in the <em>enter</em> function we used to generate our map like so:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Create a map based on our size parameters</span>
    <span class="kd">var</span> <span class="nx">mapWidth</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">mapHeight</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
    <span class="c1">// ...</span>
    <span class="c1">// Setup the map generator</span>
    <span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">Cellular</span><span class="p">(</span><span class="nx">mapWidth</span><span class="p">,</span> <span class="nx">mapHeight</span><span class="p">);</span>
    <span class="nx">generator</span><span class="p">.</span><span class="nx">randomize</span><span class="p">(</span><span class="mf">0.5</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">totalIterations</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="c1">// Iteratively smoothen the map</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">totalIterations</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="c1">// Smoothen it one last time and then update our map</span>
    <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">,</span><span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">});</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We're now going to change this code! The first thing we are going to do is make the map smaller, as the generation tends to take much longer:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="pygments_murphy"><pre>    <span class="kd">var</span> <span class="nx">mapWidth</span> <span class="o">=</span> <span class="mi">250</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">mapHeight</span> <span class="o">=</span> <span class="mi">250</span><span class="p">;</span>
</pre></div>
</td></tr></table>

<p>The <em>ROT.Map.Uniform</em> generator is much simpler to use and only requires 1 iteration of create! We also pass a time limit in the options, as by default if the generation takes more than 1000 milliseconds it will simply generate null, so we increase it to 5000 milliseconds. Another change is that with this generator, 1 represents a wall and 0 represents a floor. We can then modify our generator code:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Setup the map generator</span>
<span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">Uniform</span><span class="p">(</span><span class="nx">mapWidth</span><span class="p">,</span> <span class="nx">mapHeight</span><span class="p">,</span> 
    <span class="p">{</span><span class="nx">timeLimit</span><span class="o">:</span> <span class="mi">5000</span><span class="p">});</span>
<span class="c1">// Smoothen it one last time and then update our map</span>
<span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">,</span><span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>

<p>And there you have it! The map now looks more like a traditional roguelike:
<div class="image_container"><a href="/assets/rogue/3bextra.png"><img class="image" src="/assets/rogue/3bextra.png" height="99" width="200"/></a></div></p>
<p>Note that the code for this extra is not up on the Github, but if you have any questions feel free to post in the comments!</p>
<h1>Next Part</h1>
<p><a href="/2013/04/20/building-a-roguelike-in-javascript-part-4/">Part 4 - A Hero Appears!</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/I5ZtMKhhN7M" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/07/building-a-roguelike-in-javascript-part-3b</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 3a</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/WKb45e3k1Wk/building-a-roguelike-in-javascript-part-3a</link>
      <pubDate>Fri, 05 Apr 2013 21:25:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/05/building-a-roguelike-in-javascript-part-3a</guid>
      <description>Building a Roguelike in Javascript - Part 3a</description>
      <content:encoded><![CDATA[<p>This is the third post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a> unless you've been following along. This part corresponds to the map generation segment of <a href="http://trystans.blogspot.ca/2011/08/roguelike-tutorial-03-scrolling-through.html">the third part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part3a">part 3a tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I have <strong>updated the rot.js version</strong> to the <a href="https://github.com/ondras/rot.js/commit/d4ea2abb55432929aee1ed81cac10cebdda5aebb">d4ea2ab commit</a>, although there are no breaking changes in terms of what we've done.</p>
<p>Today we'll start working on our actual game! Roguelike games traditionally took place in a dark, monster-filled, multi-level dungeon, but we can let our imagination run free and build all sorts of environments! The great thing about using ASCII graphics is that you aren't limited by your graphical abilitites! No matter what you want to add, whether it be a tree, a dragon or a jetpack, all you have to do is decide what character and colors will represent it! For example <span style="color: green;">&spades;</span> may be a pine tree just like <span style="color: brown;">%</span> may be a deadly two-headed dog. This is your game... have fun with it! If you want some inspiration and examples of how different games can look check out the <a href="http://www.bay12games.com/dwarves/">background of the Dwarf Fortress page</a>, these <a href="http://crawl.develz.org/wordpress/screenshots">Dungeon Crawl screenshots</a> and this screenshot of <a href="/assets/rogue/rogue.png">Rogue</a>, the game that started it all.</p>
<p>To keep things simple and make sure we've got everything running properly we'll be keeping our environment simple in this post. We're going to build some nice caves for our hero to explore, plunder, and possibly stay in forever! For now our cave will be fairly simple and consist of walls, represented by <span style="color: goldenrod;">#</span>, and a simple floor, represented by a period. In this post we'll focus simply on building a map and drawing it on the screen, and in the next post we'll make it so we can scroll around the screen. Here's a small screenshot of what we'll have at the end of this post:
<div class="image_container"><a href="/assets/rogue/caves.png"><img class="image" src="/assets/rogue/caves.png" height="98" width="200"/></a></div></p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part3a">here</a></p>
<h1>assets/glyph.js</h1>
<p>Almost everything in our game will be represented by some kind of glyph. If you are wondering what a glyph is, it is simply a combination of a character with a foreground and background color. Before we can do any kind of graphical work, we'll need to create a small class representing a glyph:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">chr</span><span class="p">,</span> <span class="nx">foreground</span><span class="p">,</span> <span class="nx">background</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Instantiate properties to default if they weren&#39;t passed</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_char</span> <span class="o">=</span> <span class="nx">chr</span> <span class="o">||</span> <span class="s1">&#39; &#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_foreground</span> <span class="o">=</span> <span class="nx">foreground</span> <span class="o">||</span> <span class="s1">&#39;white&#39;</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_background</span> <span class="o">=</span> <span class="nx">background</span> <span class="o">||</span> <span class="s1">&#39;black&#39;</span><span class="p">;</span>
<span class="p">};</span>

<span class="c1">// Create standard getters for glyphs</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getChar</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span> 
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_char</span><span class="p">;</span> 
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getBackground</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_background</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getForeground</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span> 
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_foreground</span><span class="p">;</span> 
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>As you can see a glyph simply wraps around a character, a foreground color, and a background color (with default values for all 3 properties). The properties can be fetched using getter methods.</p>
<h1>assets/tile.js</h1>
<p>Levels in ASCII games are usually described in terms of cells or tiles, where each character (for example our walls) represents a given cell. Each of these cells occupies the same width and height visually. A simple way to refer to the cells on a screen is to use 2D cartesian coordinates (x and y). In our case, we use the top left corner as the origin (x=0 and y=0). Therefore a given game level will contain a 2D array of tiles (with the first dimension representing the x and the second dimension representing the y). So what exactly is a <em>tile</em>? For now a tile simply contains a glyph, but in the future it will keep all sorts of useful information such as whether characters can walk on this tile and it will also describe how players can interact with the tile.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">glyph</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_glyph</span> <span class="o">=</span> <span class="nx">glyph</span><span class="p">;</span>
<span class="p">};</span>

<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getGlyph</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_glyph</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>Now we want to create different tiles for walls and floors. However because there is no differentiating between a wall in one cell and a wall in another, we can simply have a single instance of both tile types and pass that around! Note that we're also going to create a nullTile which will be returned whenever we try to access an out of bounds tiles. This will be useful as it will prevent us from having to do null checks all the time, and as mentioned by Trystan, follows the <a href="http://en.wikipedia.org/wiki/Null_Object_pattern">Null Object pattern</a>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">(</span><span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">());</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">(</span><span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">));</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">(</span><span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Glyph</span><span class="p">(</span><span class="s1">&#39;#&#39;</span><span class="p">,</span> <span class="s1">&#39;goldenrod&#39;</span><span class="p">));</span>
</pre></div>
</td></tr></table>

<h1>assets/map.js</h1>
<p>Now that we have the notion of a tile, we're ready to create our map! As mentioned before, our Map will simply contain a 2D array of tiles, and we use their index in the first and second dimension to represent the x and y coordinate respectively.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tiles</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">;</span>
    <span class="c1">// cache the width and height based</span>
    <span class="c1">// on the length of the dimensions of</span>
    <span class="c1">// the tiles array</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_height</span> <span class="o">=</span> <span class="nx">tiles</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
<span class="p">};</span>

<span class="c1">// Standard getters</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getWidth</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span><span class="p">;</span>
<span class="p">};</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getHeight</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">;</span>
<span class="p">};</span>

<span class="c1">// Gets the tile for a given coordinate set</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getTile</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Make sure we are inside the bounds. If we aren&#39;t, return</span>
    <span class="c1">// null tile.</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">x</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_width</span> <span class="o">||</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">y</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_height</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_tiles</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">||</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>We're now ready to display our map! The map will get drawn when we are currently on the <em>Play</em> screen. It's a good idea to keep all the screen logic and data in the screen's class, so we will contain our map in the Play screen. To do this, we must add the <em>_map</em> property to <strong>PlayScreen</strong>:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">_map</span> <span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>For now let's make it so that a map is randomly generated whenever we <em>enter</em> the screen. There are many algorithms for generating a variety of random maps, such as caves, dungeons, wilderness, etc. A great source of algorithms for this is the <a href="roguebasin.roguelikedevelopment.org/index.php?title=Articles#Map">RogueBasin articles section</a> and the <a href="http://pcg.wikidot.com/">Procedural Content Wiki</a>. RogueBasin is a great resource overall and I highly recommend you check it out. I've also written <a href="/2012/08/07/procedurally-generating-dungeons/">a post on generating random dungeons</a> which I encourage you to check out if you are interested! Conveniently, the rot.js library provides a plethora of map generating algorithms in the <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Map.html">ROT.Map</a> namespace. They usually return an array of 1s and 0s which can then be mapped to a tile type.</p>
<p>To generate caves as shown in the picture above, we're going to use the <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Map.Cellular.html">ROT.Map.Cellular</a> generator. It uses a strategy called <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels">cellular automata</a> to carve out realistic looking caves! The first thing we're going to do is create our empty array of tiles. For now we will make our map the same size as the screen, although this will be refactored in the next part when we introduce scrolling maps. So let's update our <em>enter</em> function:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="mi">80</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Create the nested array for the y values</span>
        <span class="nx">map</span><span class="p">.</span><span class="nx">push</span><span class="p">([]);</span>
        <span class="c1">// Add all the tiles</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="mi">24</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now we're ready to generate our map! The first thing we have to do is create our instance of <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Map.Cellular.html">ROT.Map.Cellular</a> and instantiate it with random values. The <em>randomize</em> function accepts the probability of a given cell starting out as a 1, so we use 0.5 to make it split equally:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">Cellular</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="mi">24</span><span class="p">);</span>
<span class="nx">generator</span><span class="p">.</span><span class="nx">randomize</span><span class="p">(</span><span class="mf">0.5</span><span class="p">);</span>
</pre></div>
</td></tr></table>

<p>Once we've randomized our map, we want to actually apply the map generation method. Because of the way the algorithm works, re-applying it will generate smoother and smoother maps. By smoother I mean the caves are larger, more consistently shaped and generally more connected. In order to iterate, we have to use the <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Map.Cellular.html#create">ROT.Map.Cellular.create</a> method. Note that in order to update our own map, we have to pass a callback to the <em>create</em> function which accepts an x, y, and either a 1 or a 0 depending on the value that is generated. We only need to to pass this callback on our last application though as that is the only time we actually want to update our map. When updating our map, we will consider a value of 1 to be a floor and a value of 0 to be a wall in order to determine which tile type to use. Here is our completed <em>enter</em> function:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>  
    <span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="mi">80</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Create the nested array for the y values</span>
        <span class="nx">map</span><span class="p">.</span><span class="nx">push</span><span class="p">([]);</span>
        <span class="c1">// Add all the tiles</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="mi">24</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">nullTile</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">// Setup the map generator</span>
    <span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Map</span><span class="p">.</span><span class="nx">Cellular</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="mi">24</span><span class="p">);</span>
    <span class="nx">generator</span><span class="p">.</span><span class="nx">randomize</span><span class="p">(</span><span class="mf">0.5</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">totalIterations</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="c1">// Iteratively smoothen the map</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">totalIterations</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="c1">// Smoothen it one last time and then update our map</span>
    <span class="nx">generator</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">,</span><span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">floorTile</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nx">map</span><span class="p">[</span><span class="nx">x</span><span class="p">][</span><span class="nx">y</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Tile</span><span class="p">.</span><span class="nx">wallTile</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">});</span>
    <span class="c1">// Create our map from the tiles</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>
<span class="p">},</span>
</pre></div>
</td></tr></table>

<p>All that's left to do is actually render our map! Can you guess what function we'll modify next? Because of how we set up our system, all we have to do is iterate through our map tiles and render the glyph!</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Iterate through all map cells</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getWidth</span><span class="p">();</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getHeight</span><span class="p">();</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Fetch the glyph for the tile and render it to the screen</span>
            <span class="kd">var</span> <span class="nx">glyph</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_map</span><span class="p">.</span><span class="nx">getTile</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">).</span><span class="nx">getGlyph</span><span class="p">();</span>
            <span class="nx">display</span><span class="p">.</span><span class="nx">draw</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span>
                <span class="nx">glyph</span><span class="p">.</span><span class="nx">getChar</span><span class="p">(),</span> 
                <span class="nx">glyph</span><span class="p">.</span><span class="nx">getForeground</span><span class="p">(),</span> 
                <span class="nx">glyph</span><span class="p">.</span><span class="nx">getBackground</span><span class="p">());</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">},</span>
</pre></div>
</td></tr></table>

<h1>index.html</h1>
<p>We're all done! Now we can actually see our caves getting rendered, and each time we refresh our game it'll be a brand new cave. All we have to do is <strong>update our scripts</strong>:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/rot.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/game.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/screens.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/glyph.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/tile.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/map.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>Go ahead and load up your game and enjoy your hard work so far! Our next post will make it so that we can actually make maps larger than the screen and scroll around!</p>
<p>Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part3a">part 3a tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. I hope you enjoyed this post and that you'll stick around for the next part!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Next Part</h1>
<p><a href="/2013/04/07/building-a-roguelike-in-javascript-part-3b/">Part 3b - Exploring Caves</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/WKb45e3k1Wk" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/05/building-a-roguelike-in-javascript-part-3a</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 2</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/YnRy5hcCxFk/building-a-roguelike-in-javascript-part-2</link>
      <pubDate>Wed, 03 Apr 2013 18:00:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/03/building-a-roguelike-in-javascript-part-2</guid>
      <description>Building a Roguelike in Javascript - Part 2</description>
      <content:encoded><![CDATA[<p>This is the second post in the <em>Building a Roguelike in Javascript</em> series. I recommend you <a href="/2013/04/01/building-a-roguelike-in-javascript-part-1/">start at the beginning</a>. As I mentioned in the first post, I will try to match each post to a post in <a href="http://trystans.blogspot.ca/2011/08/roguelike-tutorial-what-and-why.html">Trystan's series</a> on creating a roguelike in Java. This part corresponds to <a href="http://trystans.blogspot.ca/2011/08/roguelike-tutorial-02-input-output.html">the second part</a> in Trystan's series. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part2">part 2 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. At the time of writing, I am still using the <a href="https://github.com/ondras/rot.js/commit/81a8eb0d6c12b1979f778302a8a1d1f800bdb6b5">81a8eb0d6c commit</a> of rot.js.</p>
<p>Before we get started, I just want to mention that I updated <em>index.html</em> to refer to a local copy of rot.js as opposed to the copy on Github in the case the breaking changes are implemented in the future. All you have to do is download <a href="https://github.com/ondras/rot.js/blob/master/rot.min.js">rot.min.js</a>, put it in your assets folder, and update the line:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;https://raw.github.com/ondras/rot.js/master/rot.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<p>to</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/rot.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<p>In this post we will be introducing the notion of a screen to our game. A screen will represent the current state of the application, for example telling us if we are in the character creation menu or in the main game view. We want to be able to switch easily between screens, and each screen should be responsible for its own rendering and input processing. In order to do this, we will make a master Game object which will take care of containing the game's <em>display</em> as well as the current screen.</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part2">here</a></p>
<h1>assets/game.js</h1>
<p>The first thing we wil want to do here is create a <em>Game</em> object which will wrap around a <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Display.html">ROT.Display</a> object:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span>  <span class="p">{</span>
    <span class="nx">_display</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Any necessary initialization will go here.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span> <span class="mi">80</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="mi">24</span><span class="p">});</span>
    <span class="p">},</span>
    <span class="nx">getDisplay</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_display</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We can now rewrite our window.onload function to simply invoke the <em>init</em> function to setup the game and then we can use <em>getDisplay</em> to add our display to the screen. With this in mind, we can now rewrite our <strong>assets/game.js</strong> like so:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span>  <span class="p">{</span>
    <span class="nx">_display</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Any necessary initialization will go here.</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span> <span class="mi">80</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="mi">24</span><span class="p">});</span>
    <span class="p">},</span>
    <span class="nx">getDisplay</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_display</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">window</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Check if rot.js can work on this browser</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ROT</span><span class="p">.</span><span class="nx">isSupported</span><span class="p">())</span> <span class="p">{</span>
        <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;The rot.js library isn&#39;t supported by your browser.&quot;</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="c1">// Initialize the game</span>
        <span class="nx">Game</span><span class="p">.</span><span class="nx">init</span><span class="p">();</span>
        <span class="c1">// Add the container to our HTML page</span>
        <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">getDisplay</span><span class="p">().</span><span class="nx">getContainer</span><span class="p">());</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/screens.js</h1>
<p>First we have to create this file! We're going to want to include this script in our <strong>index.html</strong> page:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/rot.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/game.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/screens.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</pre></div>
</td></tr></table>

<p>This file will contain the code for the majority of our game screens. As I mentioned above, we want each screen to be in charge of its own rendering and input processing, so we're going to have to define a pretty standard interface for our screens. As we want to be able to switch screens, we may also want to do some processing when we enter or exit a given screen. This gives us the following rough interface:</p>
<pre><code>enter : function()
exit : function()
render : function(display)
handleInput : function(inputType, inputData)
</code></pre>
<p><br/>
The handleInput function will take as an argument a string (being the type of input event, such as 'keydown' or 'keyup') as well as the key event. The render function will accept a <em>ROT.Display</em> object to render onto. Before we go ahead and create our screens, let's go ahead and add screen functionality to the Game object to make the connections more clear.</p>
<h1>assets/game.js</h1>
<p>The first thing we need to do is keep track of the current screen:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">_display</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">_currentScreen</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span> 
</pre></div>
</td></tr></table>

<p>Now we want to allow switching between screens. Essentialy when we switch screens, we want to call notify the old screen that we exited (if there was one) and then notify the new screen that we are entering it and render it. So we're going to add this function to our <em>Game</em> object:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">switchScreen</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">screen</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// If we had a screen before, notify it that we exited</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="c1">// Clear the display</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">getDisplay</span><span class="p">().</span><span class="nx">clear</span><span class="p">();</span>
    <span class="c1">// Update our current screen, notify it we entered</span>
    <span class="c1">// and then render it</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">=</span> <span class="nx">screen</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">enter</span><span class="p">();</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_display</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Finally, we want to dispatch all input events to the screen's <em>handleInput</em> function. As the logic is similar for <em>keydown</em>, <em>keypress</em> and <em>keyup</em> events, I'll create a small helper function just to facilitate this. We'll put this code in the <em>Game.init</em> function as we should bind to the events as soon as possible:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Any necessary initialization will go here.</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">_display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span> <span class="mi">80</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="mi">24</span><span class="p">});</span>
    <span class="c1">// Create a helper function for binding to an event</span>
    <span class="c1">// and making it send it to the screen</span>
    <span class="kd">var</span> <span class="nx">game</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span> <span class="c1">// So that we don&#39;t lose this</span>
    <span class="kd">var</span> <span class="nx">bindEventToScreen</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// When an event is received, send it to the</span>
            <span class="c1">// screen if there is one</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Send the event type and data to the screen</span>
                <span class="nx">game</span><span class="p">.</span><span class="nx">_currentScreen</span><span class="p">.</span><span class="nx">handleInput</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">e</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">});</span>
    <span class="p">}</span>
    <span class="c1">// Bind keyboard input events</span>
    <span class="nx">bindEventToScreen</span><span class="p">(</span><span class="s1">&#39;keydown&#39;</span><span class="p">);</span>
    <span class="nx">bindEventToScreen</span><span class="p">(</span><span class="s1">&#39;keyup&#39;</span><span class="p">);</span>
    <span class="nx">bindEventToScreen</span><span class="p">(</span><span class="s1">&#39;keypress&#39;</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Our Game object now fully supports screens!</p>
<h1>assets/screens.js</h1>
<p>We're now going to define our screens. To keep the spirit of Trystan's tutorial, we'll start with a Start screen which will prompt the user to press Enter. Once we've hit Enter, we're going to switch to a Play Screen. The Play screen will then prompt us to either hit Enter or Escape, bringing us to the Win or Lose screen respectively. In order to prevent polluting the global scope, we will create a Screen namespace under Game, and our screens will be accessible from there. Before we define the screens, I encourage you to check out <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.html">the VK constants</a> which correspond to a key obtainable from the <em>keyCode</em> member of our input data.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span> <span class="o">=</span> <span class="p">{};</span>

<span class="c1">// Define our initial start screen</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">startScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Entered start screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">exit</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Exited start screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Render our prompt to the screen</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;%c{yellow}Javascript Roguelike&quot;</span><span class="p">);</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span> <span class="s2">&quot;Press [Enter] to start!&quot;</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// When [Enter] is pressed, go to the play screen</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">inputType</span> <span class="o">===</span> <span class="s1">&#39;keydown&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RETURN</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Define our playing screen</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">playScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Entered play screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">exit</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Exited play screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span> <span class="s2">&quot;%c{red}%b{white}This game is so much fun!&quot;</span><span class="p">);</span>
        <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span> <span class="s2">&quot;Press [Enter] to win, or [Esc] to lose!&quot;</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">inputType</span> <span class="o">===</span> <span class="s1">&#39;keydown&#39;</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// If enter is pressed, go to the win screen</span>
            <span class="c1">// If escape is pressed, go to lose screen</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_RETURN</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">winScreen</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">inputData</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">===</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">VK_ESCAPE</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">loseScreen</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>    
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Define our winning screen</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">winScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Entered win screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">exit</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Exited win screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Render our prompt to the screen</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">22</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Generate random background colors</span>
            <span class="kd">var</span> <span class="nx">r</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">255</span><span class="p">);</span>
            <span class="kd">var</span> <span class="nx">g</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">255</span><span class="p">);</span>
            <span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">255</span><span class="p">);</span>
            <span class="kd">var</span> <span class="nx">background</span> <span class="o">=</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Color</span><span class="p">.</span><span class="nx">toRGB</span><span class="p">([</span><span class="nx">r</span><span class="p">,</span> <span class="nx">g</span><span class="p">,</span> <span class="nx">b</span><span class="p">]);</span>
            <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;%b{&quot;</span> <span class="o">+</span> <span class="nx">background</span> <span class="o">+</span> <span class="s2">&quot;}You win!&quot;</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">},</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Nothing to do here      </span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Define our winning screen</span>
<span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">loseScreen</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">enter</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Entered lose screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">exit</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Exited lose screen.&quot;</span><span class="p">);</span> <span class="p">},</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Render our prompt to the screen</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">22</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;%b{red}You lose! :(&quot;</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">},</span>
    <span class="nx">handleInput</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inputType</span><span class="p">,</span> <span class="nx">inputData</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Nothing to do here      </span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>assets/game.js</h1>
<p>We're almost done! The only thing we haven't done is define the screen we actually start on! All we have to do is call <em>Game.switchScreen</em> after we call <em>Game.init</em> to make sure we don't try to load the screen before our initialization is done:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nb">window</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Check if rot.js can work on this browser</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ROT</span><span class="p">.</span><span class="nx">isSupported</span><span class="p">())</span> <span class="p">{</span>
        <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;The rot.js library isn&#39;t supported by your browser.&quot;</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="c1">// Initialize the game</span>
        <span class="nx">Game</span><span class="p">.</span><span class="nx">init</span><span class="p">();</span>
        <span class="c1">// Add the container to our HTML page</span>
        <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">getDisplay</span><span class="p">().</span><span class="nx">getContainer</span><span class="p">());</span>
        <span class="c1">// Load the start screen</span>
        <span class="nx">Game</span><span class="p">.</span><span class="nx">switchScreen</span><span class="p">(</span><span class="nx">Game</span><span class="p">.</span><span class="nx">Screen</span><span class="p">.</span><span class="nx">startScreen</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>Everything should now be working fine! If you load up index.html, you should be able to play the game we've made so far and see a colorful win screen and depressing losing screen. The next few posts will be more exciting as we're actually going to start display game maps and characters on the screen, but this post was an important step towards structuring our game.</p>
<p>Remember that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part2">part 2 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. I hope you enjoyed this post and that you'll stick around for the next part!</p>
<p>Thanks for reading,</p>
<p>Dominic</p>
<h1>Next Part</h1>
<p><a href="/2013/04/05/building-a-roguelike-in-javascript-part-3a/">Part 3a - Carving Caves</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/YnRy5hcCxFk" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/03/building-a-roguelike-in-javascript-part-2</feedburner:origLink></item>
    <item>
      <title>Building a Roguelike in Javascript - Part 1</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/1gCtq3HQJMg/building-a-roguelike-in-javascript-part-1</link>
      <pubDate>Mon, 01 Apr 2013 20:00:00 EDT</pubDate>
      <category><![CDATA[Roguelikes]]></category>
      <category><![CDATA[Javascript]]></category>
      <category><![CDATA[Gamedev]]></category>
      <category><![CDATA[Build a RL]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/04/01/building-a-roguelike-in-javascript-part-1</guid>
      <description>Building a Roguelike in Javascript - Part 1</description>
      <content:encoded><![CDATA[<p>As I've <a href="/2012/08/07/procedurally-generating-dungeons/">mentioned in the past</a>, I've always enjoyed playing <a href="http://en.wikipedia.org/wiki/Roguelike">roguelike</a> games such as <a href="http://www.nethack.org/">NetHack</a>, <a href="http://crawl.develz.org/wordpress/">Dungeon Crawl Stone Soup</a> and <a href="http://www.ancardia.com/">ADOM</a>. If you've never played these games before I highly encourage you to check them out. The ASCII graphics may not be for everyone but the incredibly deep gameplay more than makes up for it.</p>
<p>I've tinkered on a few home-grown roguelikes in the past and it's always proved to be great fun. Inspired by the most recent <a href="http://7drl.org/">7DRLC</a>, a competition where participants must make a roguelike in 7 days, I went on a search for blog posts regarding developing roguelikes. I found <a href="http://trystans.blogspot.ca/2011/08/roguelike-tutorial-01-java-eclipse.html">Trystan Spangler's great set of posts on creating a roguelike in Java</a> and then a <a href="http://stevelosh.com/blog/2012/07/caves-of-clojure-01/">corresponding set of posts for Clojure by Steve Losh</a> and decided to try my hand at making a set of posts for making one in Javascript. I hope to get through at least a good part of Trystan's series and will try my best to make each post match content-wise.</p>
<p>I will be using <a href="http://ondras.github.com/rot.js/hp/">rot.js library</a> developed by <a href="http://ondras.zarovi.cz/">Ondrej Zara</a>. At the moment of writing, the <em>master</em> branch is ponting to the <a href="https://github.com/ondras/rot.js/commit/81a8eb0d6c12b1979f778302a8a1d1f800bdb6b5">81a8eb0d6c commit</a> of the library. If there is any breaking changes in future blog posts, I'll make sure to let you know! The most important file in this project is the <strong>rot.min.js</strong> file.</p>
<p>Just to make sure everything is up and running, this first post will consist of getting a Hello, World up and running! We will start with a very basic game structure. We'll create an HTML page called <strong>index.html</strong> and our code will be in a Javascript file under <strong>assets/game.js</strong>. Note that all the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part1">part 1 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>.</p>
<h1>Demo Link</h1>
<p>The results after this post can be seen <a href="/demo/rl_part1">here</a></p>
<h1>index.html</h1>
<p>This file will be our HTML skeleton and simply includes the <strong>rot.min.js</strong> from the master branch and the <strong>assets/game.js</strong>.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="nt">&lt;html&gt;</span>
  <span class="nt">&lt;head&gt;</span>
    <span class="nt">&lt;title&gt;</span>Javascript Roguelike<span class="nt">&lt;/title&gt;</span>
  <span class="nt">&lt;/head&gt;</span>
  <span class="nt">&lt;body&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;https://raw.github.com/ondras/rot.js/master/rot.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;assets/game.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
  <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</pre></div>
</td></tr></table>

<h1>assets/game.js</h1>
<p>The first thing we'll want to do is make sure our browser supports the rot.js library. We do this when the page is done loading by using the <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.html#.isSupported">isSupported</a> function like so:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Check if rot.js can work on this browser</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ROT</span><span class="p">.</span><span class="nx">isSupported</span><span class="p">())</span> <span class="p">{</span>
    <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;The rot.js library isn&#39;t supported by your browser.&quot;</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="c1">// Good to go!</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>If our browser has all the necessary functionality for rot.js to function, we're good to go! For this first blog post I just want to get everything set up by getting a canvas up on the screen and using the library to print out <em>Hello, world</em> in a variety of colors. In later posts we will make our game more structured, but for now this will do. All the following code will go in the else branch. We first have to <a href="http://ondras.github.com/rot.js/manual/#display">create a display</a>, which will be 80 characters wide and 20 characters tall. Once we've created this display object, we must add it to our HTML page.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Create a display 80 characters wide and 20 characters tall</span>
<span class="kd">var</span> <span class="nx">display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span><span class="mi">80</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span><span class="mi">20</span><span class="p">});</span>
<span class="kd">var</span> <span class="nx">container</span> <span class="o">=</span> <span class="nx">display</span><span class="p">.</span><span class="nx">getContainer</span><span class="p">();</span>
<span class="c1">// Add the container to our HTML page</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">container</span><span class="p">);</span>
</pre></div>
</td></tr></table>

<p>We've now got our display up and running! We will use the <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Display.html#drawText">display.drawText</a> function which accepts x and y coordinates as well as a string to print (and an optional width for wrapping). When printing using <em>drawText</em>, we add in color formatting strings to specify the foreground color of the text (using <em>%c{name}%</em>) and background color of the text (using <em>%b{name}%}</em>). In the <em>name</em> of the color we can put any valid CSS color. We will be using the <a href="http://ondras.github.com/rot.js/doc/symbols/ROT.Color.html">Color library object</a> to convert a color to an RGB specifier via the <em>toRGB</em> function. We're going to print 'Hello, world!' 15 times with the foreground getting lighter while the background gets darker. We put this code right after creating our display:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">var</span> <span class="nx">foreground</span><span class="p">,</span> <span class="nx">background</span><span class="p">,</span> <span class="nx">colors</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Calculate the foreground color, getting progressively darker</span>
    <span class="c1">// and the background color, getting progressively lighter.</span>
    <span class="nx">foreground</span> <span class="o">=</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Color</span><span class="p">.</span><span class="nx">toRGB</span><span class="p">([</span><span class="mi">255</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">),</span>
                                  <span class="mi">255</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">),</span>
                                  <span class="mi">255</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">)]);</span>
    <span class="nx">background</span> <span class="o">=</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Color</span><span class="p">.</span><span class="nx">toRGB</span><span class="p">([</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">,</span> <span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">,</span> <span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">]);</span>
    <span class="c1">// Create the color format specifier.</span>
    <span class="nx">colors</span> <span class="o">=</span> <span class="s2">&quot;%c{&quot;</span> <span class="o">+</span> <span class="nx">foreground</span> <span class="o">+</span> <span class="s2">&quot;}%b{&quot;</span> <span class="o">+</span> <span class="nx">background</span> <span class="o">+</span> <span class="s2">&quot;}&quot;</span><span class="p">;</span>
    <span class="c1">// Draw the text at col 2 and row i</span>
    <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">colors</span> <span class="o">+</span> <span class="s2">&quot;Hello, world!&quot;</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>If worked, you should see the following when you open <em>index.html</em>:
<div class="image_container"><a href="/assets/rogue/hello.png"><img class="image" src="/assets/rogue/hello.png" height="83" width="200"/></a></div></p>
<p>So the final code for <strong>game.js</strong> is:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nb">window</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Check if rot.js can work on this browser</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ROT</span><span class="p">.</span><span class="nx">isSupported</span><span class="p">())</span> <span class="p">{</span>
        <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;The rot.js library isn&#39;t supported by your browser.&quot;</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="c1">// Create a display 80 characters wide and 20 characters tall</span>
        <span class="kd">var</span> <span class="nx">display</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Display</span><span class="p">({</span><span class="nx">width</span><span class="o">:</span><span class="mi">80</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span><span class="mi">20</span><span class="p">});</span>
        <span class="kd">var</span> <span class="nx">container</span> <span class="o">=</span> <span class="nx">display</span><span class="p">.</span><span class="nx">getContainer</span><span class="p">();</span>
        <span class="c1">// Add the container to our HTML page</span>
        <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">container</span><span class="p">);</span>
        <span class="kd">var</span> <span class="nx">foreground</span><span class="p">,</span> <span class="nx">background</span><span class="p">,</span> <span class="nx">colors</span><span class="p">;</span>
        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Calculate the foreground color, getting progressively darker</span>
            <span class="c1">// and the background color, getting progressively lighter.</span>
            <span class="nx">foreground</span> <span class="o">=</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Color</span><span class="p">.</span><span class="nx">toRGB</span><span class="p">([</span><span class="mi">255</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">),</span>
                                          <span class="mi">255</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">),</span>
                                          <span class="mi">255</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">)]);</span>
            <span class="nx">background</span> <span class="o">=</span> <span class="nx">ROT</span><span class="p">.</span><span class="nx">Color</span><span class="p">.</span><span class="nx">toRGB</span><span class="p">([</span><span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">,</span> <span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">,</span> <span class="nx">i</span><span class="o">*</span><span class="mi">20</span><span class="p">]);</span>
            <span class="c1">// Create the color format specifier.</span>
            <span class="nx">colors</span> <span class="o">=</span> <span class="s2">&quot;%c{&quot;</span> <span class="o">+</span> <span class="nx">foreground</span> <span class="o">+</span> <span class="s2">&quot;}%b{&quot;</span> <span class="o">+</span> <span class="nx">background</span> <span class="o">+</span> <span class="s2">&quot;}&quot;</span><span class="p">;</span>
            <span class="c1">// Draw the text two columns in and at the row specified</span>
            <span class="c1">// by i</span>
            <span class="nx">display</span><span class="p">.</span><span class="nx">drawText</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">colors</span> <span class="o">+</span> <span class="s2">&quot;Hello, world!&quot;</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<h1>Conclusion</h1>
<p>We've now got a small test application up and running with the rot.js library. All the code for this part can be found at the <a href="https://github.com/jokeofweek/jsrogue/tree/part1">part 1 tag</a> of the <a href="https://github.com/jokeofweek/jsrogue">jsrogue repository</a>. I hope you enjoyed this post and that you'll stick around for the next part!</p>
<p>Thanks for reading, Dominic.</p>
<h1>Next Part</h1>
<p><a href="/2013/04/03/building-a-roguelike-in-javascript-part-2/">Part 2 - Screen Management</a></p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/1gCtq3HQJMg" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/04/01/building-a-roguelike-in-javascript-part-1</feedburner:origLink></item>
    <item>
      <title>Consuming JSON APIs With Go</title>
      <link>http://feedproxy.google.com/~r/codingcookies/~3/Ts897Zr2x70/consuming-json-apis-with-go</link>
      <pubDate>Thu, 21 Mar 2013 22:30:00 EDT</pubDate>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Go]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[HTTP]]></category>
      <guid isPermaLink="false">http://www.codingcookies.com/2013/03/21/consuming-json-apis-with-go</guid>
      <description>Consuming JSON APIs With Go</description>
      <content:encoded><![CDATA[<p>I've been wanting to play around with the <a href="http://golang.org/">Go programming language</a> for a while now so I figured a blog post would be a great opportunity to do so. Today we'll be building Go functions which will interact with the JSON API for the <a href="http://www.hostip.info/">HostIP service</a>. This simple service offers location information for an IP address. The API documentation is located <a href="http://www.hostip.info/use.html">here</a>. The complete code for this post is located <a href="https://gist.github.com/jokeofweek/5218490">as a gist on my Github</a>. For the sake of simplicity, I will be requesting location data encoded in JSON. Here is a sample request and response:</p>
<pre><code>Request: GET http://api.hostip.info/get_json.php?position=true&amp;ip=198.252.206.16

Response:
{
    "country_name": "UNITED STATES",
    "country_code": "US",
    "city": "Cambridge, MA",
    "ip": "198.252.206.16",
    "lat": "42.3758",
    "lng": "-71.1187"
}
</code></pre>
<p><br/>
<em>Note:</em> The lat and lang field can sometimes return <em>null</em>, so we will have to take this into consideration when working with the data.</p>
<p>The first thing we will be doing is creating a generic function which sends a HTTP GET request and receives a response. For larger API clients you'd want to generalize this for any type of HTTP request but for the sake of simplicity and shortness we will stick to GETs. We will be using the <a href="http://golang.org/pkg/net/http/">net/http</a> and the <a href="http://golang.org/pkg/io/ioutil/">io/ioutil</a> packages for sending HTTP requests and reading byte arrays respectively. We begin with these imports:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kn">import</span> <span class="p">(</span>
    <span class="s">&quot;io/ioutil&quot;</span>
    <span class="s">&quot;net/http&quot;</span>
<span class="p">)</span>
</pre></div>
</td></tr></table>

<p>Our function will accept a URL as a string, create a HTTP client, send the request, and return the response (or any errors that may have occured along the way). Thus our function returns a pair (byte[], error). So our function shell will look like:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">func</span> <span class="nx">getContent</span><span class="p">(</span><span class="nx">url</span> <span class="kt">string</span><span class="p">)</span> <span class="p">([]</span><span class="kt">byte</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// magic</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>First thing we will do is build a new request using the <a href="http://golang.org/pkg/net/http/#NewRequest">NewRequest</a> function. If we encounter any error, we simply exit out of our function returning <em>nil</em> as our byte array and the error itself. We then make a new HTTP client and send off the request using <a href="http://golang.org/pkg/net/http/#Client.Do">Client.Do</a>. The good thing about the <em>Do</em> function is that it can be generalized to any type of HTTP method.</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// Build the request</span>
<span class="nx">req</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nx">NewRequest</span><span class="p">(</span><span class="s">&quot;GET&quot;</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
<span class="p">}</span>

<span class="c1">// Send the request via a client</span>
<span class="nx">client</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">http</span><span class="p">.</span><span class="nx">Client</span><span class="p">{}</span>
<span class="nx">resp</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">client</span><span class="p">.</span><span class="nx">Do</span><span class="p">(</span><span class="nx">req</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>Now that we've actualy sent off our request we want to get our received content. Note that the HTTP Request type wraps the body in a <a href="http://golang.org/pkg/io/#ReadCloser">ReadCloser</a>, so once we've obtained our content it's important to close the body. To make sure we don't forget to do so, we defer a call to the close function right way by using the <em><a href="http://golang.org/ref/spec#Defer_statements">defer</a></em> keyword. This special keyword allows us to delay the execution of the statement until we return from the function. That way we can defer our call right away to make sure we don't forget about it and then do all the processing we need within the function while knowing our stream will safely be closed afterwards. Once that's done, we simply read from the body into a byte array using <a href="http://golang.org/pkg/io/ioutil/#ReadAll">ReadAll</a>, which takes in a reader and reads until we hit an EOF (or an error). We finish off our method like so:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// This function fetch the content of a URL will return it as an</span>
<span class="c1">// array of bytes if retrieved successfully.</span>
<span class="kd">func</span> <span class="nx">getContent</span><span class="p">(</span><span class="nx">url</span> <span class="kt">string</span><span class="p">)</span> <span class="p">([]</span><span class="kt">byte</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Build the request</span>
    <span class="nx">req</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">http</span><span class="p">.</span><span class="nx">NewRequest</span><span class="p">(</span><span class="s">&quot;GET&quot;</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
    <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
      <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
    <span class="p">}</span>
    <span class="c1">// Send the request via a client</span>
    <span class="nx">client</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">http</span><span class="p">.</span><span class="nx">Client</span><span class="p">{}</span>
    <span class="nx">resp</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">client</span><span class="p">.</span><span class="nx">Do</span><span class="p">(</span><span class="nx">req</span><span class="p">)</span>
    <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
      <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
    <span class="p">}</span>
    <span class="c1">// Defer the closing of the body</span>
    <span class="k">defer</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span>
    <span class="c1">// Read the content into a byte array</span>
    <span class="nx">body</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nx">ReadAll</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">Body</span><span class="p">)</span>
    <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
      <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
    <span class="p">}</span>
    <span class="c1">// At this point we&#39;re done - simply return the bytes</span>
    <span class="k">return</span> <span class="nx">body</span><span class="p">,</span> <span class="kc">nil</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>We now have an easy way to get the content from a webpage. If you want to test this out you can convert a byte array to a string like so:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="nx">content</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">getContent</span><span class="p">(</span><span class="s">&quot;http://www.codingcookies.com/&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
    <span class="c1">// Uh-oh! </span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="c1">// Note that this will require you add fmt to your list of imports.</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">content</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>At this point we're ready to convert our JSON into someting useful! We'll be creating an <em>IpRecord</em> type which will be loaded with all our data received. The <a href="http://golang.org/pkg/encoding/json">encoding/json</a> package makes this extremely easy so go ahead and add that to your imports:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kn">import</span> <span class="p">(</span>
    <span class="s">&quot;encoding/json&quot;</span>
    <span class="s">&quot;io/ioutil&quot;</span>
    <span class="s">&quot;net/http&quot;</span>
<span class="p">)</span>
</pre></div>
</td></tr></table>

<p>We now want to define our structure. We will be using the <a href="http://golang.org/pkg/encoding/json/#Unmarshal">Unmarshal</a> function to transform our JSON bytes into the appropriate structure. This function is extremely handy and takes care of mapping the fields in JSON objects to the corresponding named field in the structure. Note that the function first searches for fields in the structure with the exact same name (case sensitive) followed by fields with the same name but varying in case, so we aren't restricted by case. We can also tag a field in the stucture to map to a different named field in the JSON object. An example of this is the <em>country_name</em> JSON field, which we will map to a field in the structure named <em>CountryName</em>. So our basic structure will look like this:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="kd">type</span> <span class="nx">IpRecord</span> <span class="kd">struct</span> <span class="p">{</span>
    <span class="c1">// These two fields use the json: tag to specify which field they map to</span>
    <span class="nx">CountryName</span> <span class="kt">string</span> <span class="s">`json:&quot;country_name&quot;`</span>
    <span class="nx">CountryCode</span> <span class="kt">string</span> <span class="s">`json:&quot;country_code&quot;`</span>
    <span class="c1">// These fields are mapped directly by name (note the different case)</span>
    <span class="nx">City</span> <span class="kt">string</span>
    <span class="nx">Ip</span>   <span class="kt">string</span>
    <span class="c1">// As these fields can be nullable, we use a pointer </span>
    <span class="c1">// to a string rather than a string</span>
    <span class="nx">Lat</span> <span class="o">*</span><span class="kt">string</span>
    <span class="nx">Lng</span> <span class="o">*</span><span class="kt">string</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>As you can see, the structure matches the JSON object quite closely. The <a href="http://golang.org/pkg/encoding/json/#Unmarshal">Unmarshal</a> function accepts a byte array and a reference to the object which shall be filled with the JSON data (this is simplifying, it actually accepts an <a href="http://golang.org/doc/effective_go.html#interfaces_and_types">interface</a>). Note that this function will return either <em>nil</em> if successful, else an error. We can combine this with our <em>getContent</em> function to make a function which accepts an IP in a string and will return the IpRecord for it:</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21</pre></div></td><td class="code"><div class="pygments_murphy"><pre><span class="c1">// This function will attempt to get the IP record for</span>
<span class="c1">// a given IP. If no errors occur, it will return a pair</span>
<span class="c1">// of the record and nil. If it was not successful, it will</span>
<span class="c1">// return a pair of nil and the error.</span>
<span class="kd">func</span> <span class="nx">GetIpRecord</span><span class="p">(</span><span class="nx">ip</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">IpRecord</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Fetch the JSON content for that given IP</span>
    <span class="nx">content</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">getContent</span><span class="p">(</span>
      <span class="nx">fmt</span><span class="p">.</span><span class="nx">Sprintf</span><span class="p">(</span><span class="s">&quot;http://api.hostip.info/get_json.php?position=true&amp;ip=%s&quot;</span><span class="p">,</span> <span class="nx">ip</span><span class="p">))</span>
    <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
        <span class="c1">// An error occurred while fetching the JSON</span>
        <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
    <span class="p">}</span>
    <span class="c1">// Fill the record with the data from the JSON</span>
    <span class="kd">var</span> <span class="nx">record</span> <span class="nx">IpRecord</span>
    <span class="nx">err</span> <span class="p">=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Unmarshal</span><span class="p">(</span><span class="nx">content</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">record</span><span class="p">)</span>
    <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
        <span class="c1">// An error occurred while converting our JSON to an object</span>
        <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">err</span>
    <span class="p">}</span>
<span class="k">return</span> <span class="o">&amp;</span><span class="nx">record</span><span class="p">,</span> <span class="nx">err</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

<p>And with this we are done! Feel free to play around it with it! Here's some example output (note that the memory address gets printed for latitude and longitude):</p>
<table class="pygments_murphytable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="pygments_murphy"><pre>    <span class="c1">// Note this example requires fmt in the list of imports</span>
    <span class="nx">record</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">GetIpRecord</span><span class="p">(</span><span class="s">&quot;72.21.194.212&quot;</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">&quot;amazon.com information:\n%v\n&quot;</span><span class="p">,</span> <span class="nx">record</span><span class="p">)</span>
    <span class="nx">record</span><span class="p">,</span> <span class="nx">_</span>  <span class="p">=</span> <span class="nx">GetIpRecord</span><span class="p">(</span><span class="s">&quot;74.125.131.141&quot;</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">&quot;golang.org information:\n%v\n&quot;</span><span class="p">,</span> <span class="nx">record</span><span class="p">)</span>
    <span class="nx">record</span><span class="p">,</span> <span class="nx">_</span>  <span class="p">=</span> <span class="nx">GetIpRecord</span><span class="p">(</span><span class="s">&quot;108.162.195.222&quot;</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">&quot;codingcookies.com information:\n%v\n&quot;</span><span class="p">,</span> <span class="nx">record</span><span class="p">)</span>
</pre></div>
</td></tr></table>

<p>This will output:</p>
<pre><code>stackoverflow.com information:
&amp;{UNITED STATES US Cambridge, MA 198.252.206.16 0x122b0888 0x122b08d0}
hostip.info information:
&amp;{NETHERLANDS NL Enschede 184.72.186.1 0x122b0b20 0x122b0b68}
codingcookies.com information:
&amp;{(Unknown Country?) XX (Unknown City?) 108.162.195.222 &lt;nil&gt; &lt;nil&gt;}
</code></pre>
<p><br/></p>
<p>As a challenge to your self, modify the <em>GetIpRecord</em> function to work so that when an empty string (or a null string) is passed, it will fetch your own IP information (hint: check the <a href="http://www.hostip.info/use.html">API documentation</a>). Again all the code from this post is located on <a href="https://gist.github.com/jokeofweek/5218490">this gist</a>. </p>
<p>I hope you enjoyed this post, thanks for reading!</p>
<p>Dominic</p><img src="http://feeds.feedburner.com/~r/codingcookies/~4/Ts897Zr2x70" height="1" width="1"/>]]></content:encoded>
    <feedburner:origLink>http://www.codingcookies.com/2013/03/21/consuming-json-apis-with-go</feedburner:origLink></item>
  </channel>
</rss>
