-
Notifications
You must be signed in to change notification settings - Fork 22
/
index.html
208 lines (192 loc) · 53.9 KB
/
index.html
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<!DOCTYPE html> <html> <head> <title>gibdo.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="resources/docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> gibdo.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> <p><img src="resources/game.png" alt="Screenshot" title="" /></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <p><a href="https://github.com/john-griffin/gibdo">Gibdo</a> is a starting point for creating HTML5 Canvas games in a
top-down 2D style. It is written in <a href="http://coffeescript.org/">CoffeeScript</a>
and provides the following features,</p>
<ul>
<li>A scrolling view window that tracks the player across the game world.</li>
<li>View limit detection to allow the player to move off the centre
of the screen as edges are reached.</li>
<li>Collision detection.</li>
<li>Keyboard input.</li>
<li>Sprite animation.</li>
</ul>
<p>Try it out <a href="http://john-griffin.github.com/gibdo/public/index.html">here</a>.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</a> </div> <p><a href="http://zeptojs.com/">Zepto.js</a> is used for event handling</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">$ = </span><span class="nx">Zepto</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</a> </div> <p>Helper for animating efficiently using request animation frame when available</p> </td> <td class="code"> <div class="highlight"><pre><span class="nb">window</span><span class="p">.</span><span class="nv">requestAnimFrame = </span><span class="p">(</span><span class="o">-></span>
<span class="nb">window</span><span class="p">.</span><span class="nx">requestAnimationFrame</span> <span class="o">or</span> <span class="nb">window</span><span class="p">.</span><span class="nx">webkitRequestAnimationFrame</span> <span class="o">or</span> <span class="nb">window</span><span class="p">.</span><span class="nx">mozRequestAnimationFrame</span> <span class="o">or</span> <span class="nb">window</span><span class="p">.</span><span class="nx">oRequestAnimationFrame</span> <span class="o">or</span> <span class="nb">window</span><span class="p">.</span><span class="nx">msRequestAnimationFrame</span> <span class="o">or</span> <span class="nf">(callback, element) -></span>
<span class="nb">window</span><span class="p">.</span><span class="nx">setTimeout</span> <span class="nx">callback</span><span class="p">,</span> <span class="mi">1000</span> <span class="o">/</span> <span class="mi">60</span>
<span class="p">)()</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</a> </div> <p>Create a new instance of the game and get it running.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">$</span> <span class="o">-></span>
<span class="nv">game = </span><span class="k">new</span> <span class="nx">Game</span>
<span class="nx">game</span><span class="p">.</span><span class="nx">run</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</a> </div> <h2>Game</h2>
<p>The game class handles top level game loop and initialisation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Game</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</a> </div> <p>Start the game in a default state and initiate the game loop.
It attempts to run the loop every 1 millisecond but in reality
the loop is just running as fast as it can. </p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">run: </span><span class="o">-></span>
<span class="nx">@setup</span><span class="p">()</span>
<span class="nx">@reset</span><span class="p">()</span>
<span class="vi">@then = </span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span>
<span class="nx">@animate</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">¶</a> </div> <p>Animate the game</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">animate: </span><span class="o">=></span>
<span class="nx">requestAnimFrame</span><span class="p">(</span><span class="nx">@animate</span><span class="p">)</span>
<span class="nx">@main</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">¶</a> </div> <p>Create a new game world and keyboard input handler</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">setup: </span><span class="o">-></span>
<span class="vi">@world = </span><span class="k">new</span> <span class="nx">World</span>
<span class="vi">@inputHandler = </span><span class="k">new</span> <span class="nx">InputHandler</span><span class="p">(</span><span class="nx">@world</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">¶</a> </div> <p>Nothing is reset at this level so just ask the world to reset itself.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">reset: </span><span class="o">-></span> <span class="nx">@world</span><span class="p">.</span><span class="nx">reset</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">¶</a> </div> <p>The main game loop. Establish the time since the loop last ran
in seconds and pass that through to the update method for recalculating
sprite positions. After recalculation positions, render the sprites.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">main: </span><span class="o">=></span>
<span class="nv">now = </span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span>
<span class="nv">delta = </span><span class="nx">now</span> <span class="o">-</span> <span class="nx">@lastUpdate</span>
<span class="vi">@lastUpdate = </span><span class="nx">now</span>
<span class="vi">@lastElapsed = </span><span class="nx">delta</span>
<span class="nx">@update</span><span class="p">(</span><span class="nx">delta</span> <span class="err">/ 1000)</span>
<span class="nx">@render</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">¶</a> </div> <p>Updates are handled by the input handler.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">update: </span><span class="nf">(modifier) -></span> <span class="nx">@inputHandler</span><span class="p">.</span><span class="nx">update</span><span class="p">(</span><span class="nx">modifier</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">¶</a> </div> <p>Tell the world to rerender itself.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">render: </span><span class="o">-></span> <span class="nx">@world</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">@lastUpdate</span><span class="p">,</span> <span class="nx">@lastElapsed</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">¶</a> </div> <h2>World</h2>
<p>The World class manages the game world and what can be seen
by the player.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">World</span>
<span class="nv">width: </span><span class="mi">512</span>
<span class="nv">height: </span><span class="mi">480</span>
<span class="nv">viewWidth: </span><span class="mi">400</span>
<span class="nv">viewHeight: </span><span class="mi">300</span>
<span class="nv">sprites: </span><span class="p">[]</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</a> </div> <p>When the world is created it adds a canvas to the page and
inserts all the sprites that are needed into the sprite array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="o">-></span>
<span class="vi">@ctx = </span><span class="nx">@createCanvas</span><span class="p">()</span>
<span class="vi">@hero = </span><span class="k">new</span> <span class="nx">Hero</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
<span class="vi">@column = </span><span class="k">new</span> <span class="nx">Column</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
<span class="nx">@sprites</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">Background</span><span class="p">(</span><span class="k">this</span><span class="p">))</span>
<span class="nx">@sprites</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">Monster</span><span class="p">(</span><span class="k">this</span><span class="p">))</span>
<span class="nx">@sprites</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">@column</span><span class="p">)</span>
<span class="nx">@sprites</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">@hero</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</a> </div> <p>Create an HTML5 canvas element and append it to the document</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">createCanvas: </span><span class="o">-></span>
<span class="nv">canvas = </span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">"canvas"</span><span class="p">)</span>
<span class="nv">canvas.width = </span><span class="nx">@viewWidth</span>
<span class="nv">canvas.height = </span><span class="nx">@viewHeight</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">".container .game"</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">canvas</span><span class="p">)</span>
<span class="nx">canvas</span><span class="p">.</span><span class="nx">getContext</span><span class="p">(</span><span class="s2">"2d"</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">¶</a> </div> <p>Only the hero (player character) needs to be reset.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">reset: </span><span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">reset</span><span class="p">(</span><span class="nx">@width</span><span class="p">,</span> <span class="nx">@height</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">¶</a> </div> <p>The co-ordinates the hero occupies in the centre of the view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">heroViewOffsetX: </span><span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">viewOffsetX</span><span class="p">(</span><span class="nx">@viewWidth</span><span class="p">)</span>
<span class="nv">heroViewOffsetY: </span><span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">viewOffsetY</span><span class="p">(</span><span class="nx">@viewHeight</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">¶</a> </div> <p>The maximum co-ordinates the view can scroll to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">viewWidthLimit: </span> <span class="o">-></span> <span class="nx">@width</span> <span class="o">-</span> <span class="nx">@viewWidth</span>
<span class="nv">viewHeightLimit: </span><span class="o">-></span> <span class="nx">@height</span> <span class="o">-</span> <span class="nx">@viewHeight</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">¶</a> </div> <p>Check to see if the hero is at the limits of the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">atViewLimitLeft: </span> <span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">x</span> <span class="o"><</span> <span class="nx">@heroViewOffsetX</span><span class="p">()</span>
<span class="nv">atViewLimitTop: </span> <span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">y</span> <span class="o"><</span> <span class="nx">@heroViewOffsetY</span><span class="p">()</span>
<span class="nv">atViewLimitRight: </span> <span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">x</span> <span class="o">></span> <span class="nx">@viewWidthLimit</span><span class="p">()</span> <span class="o">+</span> <span class="nx">@heroViewOffsetX</span><span class="p">()</span>
<span class="nv">atViewLimitBottom: </span><span class="o">-></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">y</span> <span class="o">></span> <span class="nx">@viewHeightLimit</span><span class="p">()</span> <span class="o">+</span> <span class="nx">@heroViewOffsetY</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">¶</a> </div> <p>Tell all the sprites to render.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">render: </span><span class="nf">(lastUpdate, lastElapsed) -></span>
<span class="nx">sprite</span><span class="p">.</span><span class="nx">draw</span><span class="p">()</span> <span class="k">for</span> <span class="nx">sprite</span> <span class="k">in</span> <span class="nx">@sprites</span>
<span class="nx">@renderDebugOverlay</span><span class="p">(</span><span class="nx">lastElapsed</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">¶</a> </div> <p>Show the frames per second at the top of the view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">renderDebugOverlay: </span><span class="nf">(lastElapsed) -></span>
<span class="nx">@ctx</span><span class="p">.</span><span class="nx">save</span><span class="p">()</span>
<span class="vi">@ctx.fillStyle = </span><span class="s2">"rgb(241, 241, 242)"</span>
<span class="vi">@ctx.font = </span><span class="s2">"Bold 20px Monospace"</span>
<span class="nx">@ctx</span><span class="p">.</span><span class="nx">fillText</span><span class="p">(</span><span class="s2">"#{Math.round(1e3 / lastElapsed)} FPS"</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
<span class="nx">@ctx</span><span class="p">.</span><span class="nx">restore</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">¶</a> </div> <p>Pass any keyboard events that come in from the input
handler off to the hero.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">up: </span> <span class="nf">(mod) -></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">up</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span>
<span class="nv">down: </span> <span class="nf">(mod) -></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">down</span><span class="p">(</span><span class="nx">mod</span><span class="p">,</span> <span class="nx">@height</span><span class="p">)</span>
<span class="nv">left: </span> <span class="nf">(mod) -></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">left</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span>
<span class="nv">right: </span><span class="nf">(mod) -></span> <span class="nx">@hero</span><span class="p">.</span><span class="nx">right</span><span class="p">(</span><span class="nx">mod</span><span class="p">,</span> <span class="nx">@width</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">¶</a> </div> <p>Find the sprites that have collision detection enabled.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">collidableSprites: </span><span class="o">-></span> <span class="nx">sprite</span> <span class="k">for</span> <span class="nx">sprite</span> <span class="k">in</span> <span class="nx">@sprites</span> <span class="k">when</span> <span class="nx">sprite</span><span class="p">.</span><span class="nx">collidable</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">¶</a> </div> <h2>InputHandler</h2>
<p>Responsible for dealing with keyboard input.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">InputHandler</span>
<span class="nv">keysDown: </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">¶</a> </div> <p>Listen for keys being presses and being released. As this happens
add and remove them from the key store.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="nf">(@world) -></span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"body"</span><span class="p">).</span><span class="nx">keydown</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=></span> <span class="nx">@keysDown</span><span class="p">[</span><span class="nx">e</span><span class="p">.</span><span class="nx">keyCode</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"body"</span><span class="p">).</span><span class="nx">keyup</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=></span> <span class="k">delete</span> <span class="nx">@keysDown</span><span class="p">[</span><span class="nx">e</span><span class="p">.</span><span class="nx">keyCode</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">¶</a> </div> <p>Every time update is called from the game loop act on the currently
pressed keys by passing the events on to the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">update: </span><span class="nf">(modifier) -></span>
<span class="nx">@world</span><span class="p">.</span><span class="nx">up</span><span class="p">(</span><span class="nx">modifier</span><span class="p">)</span> <span class="k">if</span> <span class="mi">38</span> <span class="k">of</span> <span class="nx">@keysDown</span>
<span class="nx">@world</span><span class="p">.</span><span class="nx">down</span><span class="p">(</span><span class="nx">modifier</span><span class="p">)</span> <span class="k">if</span> <span class="mi">40</span> <span class="k">of</span> <span class="nx">@keysDown</span>
<span class="nx">@world</span><span class="p">.</span><span class="nx">left</span><span class="p">(</span><span class="nx">modifier</span><span class="p">)</span> <span class="k">if</span> <span class="mi">37</span> <span class="k">of</span> <span class="nx">@keysDown</span>
<span class="nx">@world</span><span class="p">.</span><span class="nx">right</span><span class="p">(</span><span class="nx">modifier</span><span class="p">)</span> <span class="k">if</span> <span class="mi">39</span> <span class="k">of</span> <span class="nx">@keysDown</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">¶</a> </div> <h2>SpriteImage</h2>
<p>Wraps sprite loading.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">SpriteImage</span>
<span class="nv">ready: </span><span class="kc">false</span>
<span class="nv">url: </span><span class="s2">"images/sheet.png"</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">¶</a> </div> <p>Create a new image based on the sprite file and set
ready to true when loaded.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="o">-></span>
<span class="nv">image = </span><span class="k">new</span> <span class="nx">Image</span>
<span class="nv">image.src = </span><span class="nx">@url</span>
<span class="nv">image.onload = </span><span class="o">=></span> <span class="vi">@ready = </span><span class="kc">true</span>
<span class="vi">@image = </span><span class="nx">image</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">¶</a> </div> <h2>Sprite</h2> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Sprite</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">¶</a> </div> <p>The base class from which all sprites get their draw function
and default values from.</p>
<p>Configure sane defaults for sprite positions and dimensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">sx: </span><span class="mi">0</span> <span class="c1"># Source x position</span>
<span class="nv">sy: </span><span class="mi">0</span> <span class="c1"># Source y position</span>
<span class="nv">sw: </span><span class="mi">0</span> <span class="c1"># Source width</span>
<span class="nv">sh: </span><span class="mi">0</span> <span class="c1"># Source height</span>
<span class="nv">dx: </span><span class="mi">0</span> <span class="c1"># Destination x position</span>
<span class="nv">dy: </span><span class="mi">0</span> <span class="c1"># Destination y position</span>
<span class="nv">dw: </span><span class="mi">0</span> <span class="c1"># Destination width</span>
<span class="nv">dh: </span><span class="mi">0</span> <span class="c1"># Destination height</span>
<span class="nv">x: </span> <span class="mi">0</span> <span class="c1"># Position x in the world</span>
<span class="nv">y: </span> <span class="mi">0</span> <span class="c1"># Position y in the world</span>
<span class="nv">image: </span><span class="k">new</span> <span class="nx">SpriteImage</span>
<span class="nv">collidable: </span><span class="kc">false</span>
<span class="nv">constructor: </span><span class="nf">(@world) -></span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">¶</a> </div> <p>If the image is loaded then draw the sprite on to the canvas.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">drawImage: </span><span class="nf">(sx, sy, dx, dy) -></span>
<span class="k">if</span> <span class="nx">@image</span><span class="p">.</span><span class="nx">ready</span>
<span class="nx">@world</span><span class="p">.</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">drawImage</span><span class="p">(</span><span class="nx">@image</span><span class="p">.</span><span class="nx">image</span><span class="p">,</span> <span class="nx">sx</span><span class="p">,</span> <span class="nx">sy</span><span class="p">,</span> <span class="nx">@sw</span><span class="p">,</span> <span class="nx">@sh</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">@dw</span><span class="p">,</span> <span class="nx">@dh</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">¶</a> </div> <h2>Background</h2>
<p>The sprite that represents the floor or level on which the other sprites
walk around on.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Background</span> <span class="k">extends</span> <span class="nx">Sprite</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">¶</a> </div> <p>As the background represents the entire world it's source image
has the same dimensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="nf">(world) -></span>
<span class="vi">@dw = </span><span class="nx">world</span><span class="p">.</span><span class="nx">viewWidth</span>
<span class="vi">@dh = </span><span class="nx">world</span><span class="p">.</span><span class="nx">viewHeight</span>
<span class="vi">@sw = </span><span class="nx">world</span><span class="p">.</span><span class="nx">viewWidth</span>
<span class="vi">@sh = </span><span class="nx">world</span><span class="p">.</span><span class="nx">viewHeight</span>
<span class="k">super</span><span class="p">(</span><span class="nx">world</span><span class="p">)</span>
<span class="nv">draw: </span><span class="o">-></span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">¶</a> </div> <p>The background moves as the hero does.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">x = </span><span class="nx">@world</span><span class="p">.</span><span class="nx">hero</span><span class="p">.</span><span class="nx">x</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetX</span><span class="p">()</span>
<span class="nv">y = </span><span class="nx">@world</span><span class="p">.</span><span class="nx">hero</span><span class="p">.</span><span class="nx">y</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetY</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">¶</a> </div> <p>Prevent the background from scrolling at the start of the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">x = </span><span class="mi">0</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitLeft</span><span class="p">()</span>
<span class="nv">y = </span><span class="mi">0</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitTop</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">¶</a> </div> <p>Prevent the background from scrolling at the end of the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">x = </span><span class="nx">@world</span><span class="p">.</span><span class="nx">viewWidthLimit</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitRight</span><span class="p">()</span>
<span class="nv">y = </span><span class="nx">@world</span><span class="p">.</span><span class="nx">viewHeightLimit</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitBottom</span><span class="p">()</span>
<span class="nx">@drawImage</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">@dx</span><span class="p">,</span> <span class="nx">@dy</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">¶</a> </div> <h2>Entity</h2>
<p>Entities are non-background sprites that share a common draw
function as they need to be offset from the player differently.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Entity</span> <span class="k">extends</span> <span class="nx">Sprite</span>
<span class="nv">draw: </span><span class="o">-></span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">¶</a> </div> <p>When the view is at the start of the world the sprites can be
drawn at their full world co-ordinates.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@dx = </span><span class="nx">@x</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitLeft</span><span class="p">()</span>
<span class="vi">@dy = </span><span class="nx">@y</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitTop</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">¶</a> </div> <p>When the view is at the end of the world the sprites are drawn
as an offset from the edge of the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@dx = </span><span class="nx">@x</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">viewWidthLimit</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitRight</span><span class="p">()</span>
<span class="vi">@dy = </span><span class="nx">@y</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">viewHeightLimit</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">atViewLimitBottom</span><span class="p">()</span>
<span class="nx">@drawImage</span><span class="p">(</span><span class="nx">@sx</span><span class="p">,</span> <span class="nx">@sy</span><span class="p">,</span> <span class="nx">@dx</span><span class="p">,</span> <span class="nx">@dy</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">¶</a> </div> <h2>Monster</h2>
<p>An example collidable stationary sprite.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Monster</span> <span class="k">extends</span> <span class="nx">Entity</span>
<span class="nv">x: </span> <span class="mi">400</span>
<span class="nv">y: </span> <span class="mi">400</span>
<span class="nv">sw: </span><span class="mi">30</span>
<span class="nv">sh: </span><span class="mi">32</span>
<span class="nv">dw: </span><span class="mi">30</span>
<span class="nv">dh: </span><span class="mi">32</span>
<span class="nv">sy: </span><span class="mi">480</span>
<span class="nv">collidable: </span><span class="kc">true</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">¶</a> </div> <p>Offset the view co-ordinates from the player.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">draw: </span><span class="o">-></span>
<span class="vi">@dx = </span><span class="nx">@x</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">hero</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetX</span><span class="p">()</span>
<span class="vi">@dy = </span><span class="nx">@y</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">hero</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetY</span><span class="p">()</span>
<span class="k">super</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">¶</a> </div> <h2>Column</h2>
<p>Another example of a collidable stationary sprite.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Column</span> <span class="k">extends</span> <span class="nx">Entity</span>
<span class="nv">x: </span> <span class="mi">300</span>
<span class="nv">y: </span> <span class="mi">300</span>
<span class="nv">sw: </span><span class="mi">32</span>
<span class="nv">sh: </span><span class="mi">32</span>
<span class="nv">dw: </span><span class="mi">32</span>
<span class="nv">dh: </span><span class="mi">32</span>
<span class="nv">sy: </span><span class="mi">544</span>
<span class="nv">collidable: </span><span class="kc">true</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">¶</a> </div> <p>Offset the view co-ordinates from the player.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">draw: </span><span class="o">-></span>
<span class="vi">@dx = </span><span class="nx">@x</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">hero</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetX</span><span class="p">()</span>
<span class="vi">@dy = </span><span class="nx">@y</span> <span class="o">-</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">hero</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetY</span><span class="p">()</span>
<span class="k">super</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">¶</a> </div> <h2>Hero</h2> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Hero</span> <span class="k">extends</span> <span class="nx">Entity</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">¶</a> </div> <p>The sprite that represents the player and can be controlled and
moved through the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">sw: </span> <span class="mi">32</span>
<span class="nv">sh: </span> <span class="mi">30</span>
<span class="nv">dw: </span> <span class="mi">32</span>
<span class="nv">dh: </span> <span class="mi">30</span>
<span class="nv">speed: </span><span class="mi">256</span>
<span class="nv">sy: </span> <span class="mi">513</span>
<span class="nv">direction: </span><span class="mi">0</span>
<span class="nv">draw: </span><span class="o">-></span> </pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">¶</a> </div> <p>By default the hero is drawn to the centre of the view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@dx = </span><span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetX</span><span class="p">()</span>
<span class="vi">@dy = </span><span class="nx">@world</span><span class="p">.</span><span class="nx">heroViewOffsetY</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">¶</a> </div> <p>Alternate sprite frames as the player's position changes to
create an animation effect.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@sx = </span><span class="k">if</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nx">@x</span><span class="o">+</span><span class="nx">@y</span><span class="p">)</span><span class="o">%</span><span class="mi">64</span> <span class="o"><</span> <span class="mi">32</span> <span class="k">then</span> <span class="nx">@direction</span> <span class="k">else</span> <span class="nx">@direction</span> <span class="o">+</span> <span class="mi">32</span>
<span class="k">super</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">¶</a> </div> <p>The player's velocity is the default speed multiplied by the
current time difference.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">velocity: </span><span class="nf">(mod) -></span> <span class="nx">@speed</span> <span class="o">*</span> <span class="nx">mod</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">¶</a> </div> <p>Detect a collision between the proposed new player co-ordinates
and the collidable objects in the world. If the player's co-ordinates
fall within their bounds then it has collided.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">collision: </span><span class="nf">(x, y) -></span>
<span class="k">for</span> <span class="nx">o</span> <span class="k">in</span> <span class="nx">@world</span><span class="p">.</span><span class="nx">collidableSprites</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">y</span> <span class="o">></span> <span class="nx">o</span><span class="p">.</span><span class="nx">y</span> <span class="o">-</span> <span class="nx">@dh</span> <span class="o">and</span> <span class="nx">y</span> <span class="o"><</span> <span class="nx">o</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">o</span><span class="p">.</span><span class="nx">dh</span> <span class="o">and</span> <span class="nx">x</span> <span class="o">></span> <span class="nx">o</span><span class="p">.</span><span class="nx">x</span> <span class="o">-</span> <span class="nx">@dw</span> <span class="o">and</span> <span class="nx">x</span> <span class="o"><</span> <span class="nx">o</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">o</span><span class="p">.</span><span class="nx">dw</span>
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">¶</a> </div> <p>Handle keyboard input. By changing the <code>@direction</code> value in each
function the player's sprite changes and produces the effect that
makes the hero look in the direction he is travelling.</p>
<p>The player's position is modified in the direction of the key
press if still inside the world and no collisions are detected.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">up: </span><span class="nf">(mod) -></span>
<span class="vi">@direction = </span><span class="mi">64</span>
<span class="nv">y = </span><span class="nx">@y</span> <span class="o">-</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span>
<span class="nx">@y</span> <span class="o">-=</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span> <span class="k">if</span> <span class="nx">y</span> <span class="o">></span> <span class="mi">0</span> <span class="o">and</span> <span class="o">!</span><span class="nx">@collision</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="nv">down: </span><span class="nf">(mod, height) -></span>
<span class="vi">@direction = </span><span class="mi">0</span>
<span class="nv">y = </span><span class="nx">@y</span> <span class="o">+</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span>
<span class="nx">@y</span> <span class="o">+=</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span> <span class="k">if</span> <span class="nx">y</span> <span class="o"><</span> <span class="nx">height</span> <span class="o">-</span> <span class="nx">@dh</span> <span class="o">and</span> <span class="o">!</span><span class="nx">@collision</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="nv">left: </span><span class="nf">(mod) -></span>
<span class="vi">@direction = </span><span class="mi">128</span>
<span class="nv">x = </span><span class="nx">@x</span> <span class="o">-</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span>
<span class="nx">@x</span> <span class="o">-=</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span> <span class="k">if</span> <span class="nx">x</span> <span class="o">></span> <span class="mi">0</span> <span class="o">and</span> <span class="o">!</span><span class="nx">@collision</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="nv">right: </span><span class="nf">(mod, width) -></span>
<span class="vi">@direction = </span><span class="mi">192</span>
<span class="nv">x = </span><span class="nx">@x</span> <span class="o">+</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span>
<span class="nx">@x</span> <span class="o">+=</span> <span class="nx">@velocity</span><span class="p">(</span><span class="nx">mod</span><span class="p">)</span> <span class="k">if</span> <span class="nx">x</span> <span class="o"><</span> <span class="nx">width</span> <span class="o">-</span> <span class="nx">@dw</span> <span class="o">and</span> <span class="o">!</span><span class="nx">@collision</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">@y</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">¶</a> </div> <p>Helpers that the world uses to calculate the centre position of the
hero.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">viewOffsetX: </span><span class="nf">(width) -></span> <span class="p">(</span><span class="nx">width</span> <span class="sr">/ 2) - (@dw /</span> <span class="mi">2</span><span class="p">)</span>
<span class="nv">viewOffsetY: </span><span class="nf">(height) -></span> <span class="p">(</span><span class="nx">height</span> <span class="sr">/ 2) - (@dh /</span> <span class="mi">2</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">¶</a> </div> <p>The hero starts the game in the centre of the world.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">reset: </span><span class="nf">(width, height) -></span>
<span class="vi">@x = </span><span class="nx">@viewOffsetX</span><span class="p">(</span><span class="nx">width</span><span class="p">)</span>
<span class="vi">@y = </span><span class="nx">@viewOffsetY</span><span class="p">(</span><span class="nx">height</span><span class="p">)</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>