Merge branch 'master' of git.shadowcat.co.uk:SDL-Site
[sdlgit/SDL-Site.git] / pages / SDL-Tutorial-LunarLander.html-inc
CommitLineData
b3ef54ec 1<div class="pod">
2<!-- INDEX START -->
3<h3 id="TOP">Index</h3>
4
60f74f6f 5<ul><li><a href="#NAME">NAME</a>
6<ul><li><a href="#CATEGORY">CATEGORY</a></li>
7</ul>
8</li>
b3ef54ec 9<li><a href="#INTRODUCTION">INTRODUCTION</a>
10<ul>
11<li>
12<ul><li><a href="#CREATING_A_DEMO">CREATING A DEMO</a></li>
13</ul>
14</li>
15<li><a href="#FIRST_VERSION">FIRST VERSION</a></li>
16<li><a href="#CONTROLLING_THE_SHIP">CONTROLLING THE SHIP</a></li>
17<li><a href="#HOW_ABOUT_THE_GRAPHICS">HOW ABOUT THE GRAPHICS?</a>
18<ul><li><a href="#THE_GRAPHICS">THE GRAPHICS</a></li>
19</ul>
20</li>
21<li><a href="#USING_SDL">USING SDL</a></li>
22</ul>
23</li>
24<li><a href="#COPYRIGHT_amp_LICENSE">COPYRIGHT &amp; LICENSE</a>
25</li>
26</ul><hr />
27<!-- INDEX END -->
28
29<h1 id="NAME">NAME</h1><p><a href="#TOP" class="toplink">Top</a></p>
30<div id="NAME_CONTENT">
56d4907c 31<p>SDL::Tutorial::LunarLander - a small tutorial on Perl SDL</p>
b3ef54ec 32
33</div>
60f74f6f 34<h2 id="CATEGORY">CATEGORY</h2>
35<div id="CATEGORY_CONTENT">
36<p>Tutorials</p>
37
38</div>
b3ef54ec 39<h1 id="INTRODUCTION">INTRODUCTION</h1><p><a href="#TOP" class="toplink">Top</a></p>
40<div id="INTRODUCTION_CONTENT">
41<p>This is a quick introduction to Games, Perl, and SDL (Simple
42DirectMedia Layer, a cross-platform multimedia programming
43library). We'll write a small game -- Lunar Lander -- in 100
44lines of code, or less.</p>
45
46</div>
47<h3 id="CREATING_A_DEMO">CREATING A DEMO</h3>
48<div id="CREATING_A_DEMO_CONTENT">
49<p>You can see the final version of the demo code by doing:</p>
56d4907c 50<pre>
51
52
53
54
55
56 perl -MSDL::Tutorial::LunarLander=lander.pl -e1
57
58
59
60
61
62
b3ef54ec 63
64</pre>
56d4907c 65<p>this will create all three files used in the tutorial.</p>
b3ef54ec 66
67
68
69
70
71</div>
72<h2 id="FIRST_VERSION">FIRST VERSION</h2>
73<div id="FIRST_VERSION_CONTENT">
74<p>We'll start with a text version of the game.</p>
75<p>&quot;What?&quot;, you may ask. &quot;I thought it was a SDL tutorial&quot;.</p>
76<p>Yes, it is -- thank you for reminding me. But we'll leave the SDL part for
77later. We must build the game logic first!</p>
78<p>One of the traps of game programming is focusing too much on the interface.
79If we start with a simpler simulation, we can worry with the presentation
80later.</p>
81<p>So, here's the initial code:</p>
56d4907c 82<pre>
83
84
85
86
87
88 #!/usr/bin/perl
b3ef54ec 89
90 use strict;
91 use warnings;
92
93 my $height = 1000; # m
94 my $velocity = 0; # m/s
95 my $gravity = 1; # m/s^2
96
97 my $t = 0;
98
99 while ( $height &gt; 0 ) {
100 print &quot;at $t s height = $height m, velocity = $velocity m/s\n&quot;;
101
102 $height = $height - $velocity;
103 $velocity = $velocity + $gravity;
104 $t = $t + 1;
105 }
106
107 if ( $velocity &gt; 10 ) {
108 print &quot;CRASH!!!\n&quot;;
109 } else {
110 print &quot;You landed on the surface safely! :-D\n&quot;;
111 }
112
56d4907c 113
114
115
116
117
118
b3ef54ec 119</pre>
b3ef54ec 120<p>Run the code and you'll see something like this:</p>
56d4907c 121<pre>
122
123
124
125
126
127 at 0 s height = 1000 m, velocity = 0 m/s
b3ef54ec 128 at 1 s height = 1000 m, velocity = 1 m/s
129 at 2 s height = 999 m, velocity = 2 m/s
130 at 3 s height = 997 m, velocity = 3 m/s
131 at 4 s height = 994 m, velocity = 4 m/s
132 at 5 s height = 990 m, velocity = 5 m/s
133 ...
134 at 43 s height = 97 m, velocity = 43 m/s
135 at 44 s height = 54 m, velocity = 44 m/s
136 at 45 s height = 10 m, velocity = 45 m/s
137
138 CRASH!!!
139
56d4907c 140
141
142
143
144
145
b3ef54ec 146</pre>
b3ef54ec 147<p>&quot;What happened? How do I control the ship???&quot;</p>
148
149</div>
150<h2 id="CONTROLLING_THE_SHIP">CONTROLLING THE SHIP</h2>
151<div id="CONTROLLING_THE_SHIP_CONTENT">
152<p>The problem with our first spaceship is that it had no controls!</p>
153<p>So, let's fix this problem, making the spaceship scriptable. (We
154could write some code to handle keyboard and joysticks now, but
155an scriptable spaceship will be easier to start. Remember, focus
156on the game logic!)</p>
157<p>So, create add this simple script to the end of your file:</p>
56d4907c 158<pre>
159
160
161
162
163
164 __DATA__
b3ef54ec 165 at 41s, accelerate 10 m/s^2 up
166 at 43s, 10 m/s^2
167 at 45s, 10
168 at 47s, 10
169 at 49s, 10
170
56d4907c 171
172
173
174
175
176
b3ef54ec 177</pre>
b3ef54ec 178<p>The script is straightforward: it simply states a time when we
179will push the spaceship up with a given acceleration. It accepts
180free text: any two numbers you type will work.</p>
181<p>We can parse the script using this regular expression:</p>
56d4907c 182<pre>
183
184
185
186
187
188 my $script_re = qr/(\d+) \D+ (\d+)/x;
189
190
191
192
193
194
b3ef54ec 195
196</pre>
b3ef54ec 197<p>And we can build a hash of ( time =&gt; acceleration ) with:</p>
56d4907c 198<pre>
199
200
201
202
203
204 my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
205
206
207
208
209
210
b3ef54ec 211
212</pre>
b3ef54ec 213<p>So the middle section of the program will become:</p>
56d4907c 214<pre>
215
216
217
218
219
220 my $script_re = qr/(\d+) \D+ (\d+)/x;
b3ef54ec 221 my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
222
223 while ( $height &gt; 0 ) {
224 print &quot;at $t s height = $height m, velocity = $velocity m/s\n&quot;;
225
226 if ( $up{$t} ) {
227 my $a = $up{$t};
228 print &quot;(accellerating $a m/s^2)\n&quot;;
229 $velocity = $velocity - $a;
230 }
231
232 $height = $height - $velocity;
233 $velocity = $velocity + $gravity;
234 $t = $t + 1;
235 }
236
56d4907c 237
238
239
240
241
242
b3ef54ec 243</pre>
b3ef54ec 244<p>That's it!</p>
245<p>Try to run the program, and the ship should land safely:</p>
56d4907c 246<pre>
247
248
249
250
251
252 ./lunar.pl autopilot.txt
b3ef54ec 253 at 0 s height = 1000 m, velocity = 0 m/s
254 at 1 s height = 1000 m, velocity = 1 m/s
255 at 2 s height = 999 m, velocity = 2 m/s
256 at 3 s height = 997 m, velocity = 3 m/s
257 at 4 s height = 994 m, velocity = 4 m/s
258 at 5 s height = 990 m, velocity = 5 m/s
259 ...
260 at 54 s height = 19 m, velocity = 4 m/s
261 at 55 s height = 15 m, velocity = 5 m/s
262 at 56 s height = 10 m, velocity = 6 m/s
263 at 57 s height = 4 m, velocity = 7 m/s
264
265 You landed on the surface safely! :-D
266
56d4907c 267
268
269
270
271
272
b3ef54ec 273</pre>
b3ef54ec 274<p>Cool, but...</p>
275
276</div>
277<h2 id="HOW_ABOUT_THE_GRAPHICS">HOW ABOUT THE GRAPHICS?</h2>
278<div id="HOW_ABOUT_THE_GRAPHICS_CONTENT">
279<p>Okay, okay... now that we have a working prototype, we can work on
280the graphics. But, first of all, we'll need...</p>
281
282</div>
283<h3 id="THE_GRAPHICS">THE GRAPHICS</h3>
284<div id="THE_GRAPHICS_CONTENT">
285<p>Yes, the graphics.</p>
286<p>We won't use anything fancy here, just two images: a large one, for
287the background, and a smaller one for the spaceship.</p>
288<p>Create the images using the Gimp, or use the images provided by
289this tutorial; Save these images in a subdirectory called &quot;images&quot;:
290(&quot;<code>images/background.jpg</code>&quot; and &quot;<code>images/ship.png</code>&quot;).</p>
291
292</div>
293<h2 id="USING_SDL">USING SDL</h2>
294<div id="USING_SDL_CONTENT">
295<p>First step: use the required libraries:</p>
56d4907c 296<pre>
297
298
299
300
301
302 use SDL; #needed to get all constants
1f5d8082 303 use SDL::Video;
ca0a3441 304 use SDLx::App;
1f5d8082 305 use SDL::Surface;
306 use SDL::Rect;
307 use SDL::Image;
b3ef54ec 308
56d4907c 309
310
311
312
313
314
b3ef54ec 315</pre>
ca0a3441 316<p>Second step: initialize <code>SDLx::App</code>:</p>
56d4907c 317<pre>
318
319
320
321
322
ca0a3441 323 my $app = SDLx::App-&gt;new(
505f308d 324 title =&gt; &quot;Lunar Lander&quot;,
325 width =&gt; 800,
326 height =&gt; 600,
327 depth =&gt; 32,
b3ef54ec 328 );
329
56d4907c 330
331
332
333
334
335
b3ef54ec 336</pre>
b3ef54ec 337<p>Third step: load the images and create the necessary &quot;rectangles&quot;:</p>
56d4907c 338<pre>
339
340
341
342
343
344 my $background = SDL::Image::load('images/background.jpg');
1f5d8082 345 my $ship = SDL::Image::load('images/ship.jpg');
b3ef54ec 346
1f5d8082 347 my $background_rect = SDL::Rect-&gt;new(0,0,
348 $background-&gt;w,
349 $background-&gt;h,
350 );
b3ef54ec 351
1f5d8082 352 my $ship_rect = SDL::Rect-&gt;new(0,0,
353 $ship-&gt;w,
354 $ship-&gt;h,
355 );
b3ef54ec 356
56d4907c 357
358
359
360
361
362
b3ef54ec 363</pre>
b3ef54ec 364<p>Fourth step: create a sub to draw the spaceship and background:</p>
56d4907c 365<pre>
366
367
368
369
370
371 sub draw {
1f5d8082 372 my ( $x, $y ) = @_; # spaceship position
b3ef54ec 373
1f5d8082 374 # fix $y for screen resolution
375 $y = 450 * ( 1000 - $y ) / 1000;
b3ef54ec 376
1f5d8082 377 # background
378 SDL::Video::blit_surface($background, $background_rect, $app, $background_rect );
b3ef54ec 379
1f5d8082 380 # ship
381 my $ship_dest_rect = SDL::Rect-&gt;new(
382 $x, $y, $ship-&gt;w, $ship-&gt;h,
383 );
b3ef54ec 384
1f5d8082 385 SDL::Video::blit_surface($ship, $ship_rect, $app, $ship_dest_rect );
b3ef54ec 386
1f5d8082 387 SDL::Video::update_rects($app, $background_rect);
388 }
b3ef54ec 389
56d4907c 390
391
392
393
394
395
b3ef54ec 396</pre>
b3ef54ec 397<p>Note that this sub first combines all the bitmaps, using a blit
398(&quot;Block Image Transfer&quot;) operation -- which is quite fast, but does
399not update the display.</p>
400<p>The combined image is displayed in the last line. This process of
401combining first, and displaying later, avoids that annoying fading
402between cycles (&quot;flickering&quot;).</p>
403<p>Finally, add the following lines to the end of the main loop, so that
404we call the <code>draw()</code> function with the correct spaceship
405coordinates:</p>
56d4907c 406<pre>
407
408
409
410
411
412 while ( $height &gt; 0 ) {
b3ef54ec 413
414 # ...
415
416 draw( 100, $height );
417 $app-&gt;delay(10);
418 }
419
56d4907c 420
421
422
423
424
425
b3ef54ec 426</pre>
b3ef54ec 427<p>That's it!</p>
428<p>Run the program and watch the spaceship landing safely on the surface
429of the moon.</p>
430
431</div>
432<h1 id="COPYRIGHT_amp_LICENSE">COPYRIGHT &amp; LICENSE</h1><p><a href="#TOP" class="toplink">Top</a></p>
433<div id="COPYRIGHT_amp_LICENSE_CONTENT">
434<p>Copyright 2009 Nelson Ferraz, all rights reserved.</p>
1dbe1697 435<p>Updated and maintained by the SDL Perl project. See <a href="/SDL.html#AUTHORS">/SDL.html#AUTHORS</a>.</p>
b3ef54ec 436<p>This program is free software; you can redistribute it and/or modify it
437under the same terms as Perl itself.</p>
438
439</div>
440</div>