update
[sdlgit/SDL-Site.git] / pages / SDL-Tutorial-LunarLander.html-inc
1 <div class="pod">
2 <!-- INDEX START -->
3 <h3 id="TOP">Index</h3>
4
5 <ul><li><a href="#NAME">NAME</a>
6 <ul><li><a href="#CATEGORY">CATEGORY</a></li>
7 </ul>
8 </li>
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">
31 <p>SDL::Tutorial::LunarLander - a small tutorial on Perl SDL</p>
32
33 </div>
34 <h2 id="CATEGORY">CATEGORY</h2>
35 <div id="CATEGORY_CONTENT">
36 <p>Tutorials</p>
37
38 </div>
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 
42 DirectMedia Layer, a cross-platform multimedia programming 
43 library). We'll write a small game -- Lunar Lander -- in 100 
44 lines 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>
50 <pre>
51
52
53
54
55
56    perl -MSDL::Tutorial::LunarLander=lander.pl -e1
57
58
59
60
61
62
63
64 </pre>
65 <p>this will create all three files used in the tutorial.</p>
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
77 later. We must build the game logic first!</p>
78 <p>One of the traps of game programming is focusing too much on the interface.
79 If we start with a simpler simulation, we can worry with the presentation
80 later.</p>
81 <p>So, here's the initial code:</p>
82 <pre>
83
84
85
86
87
88     #!/usr/bin/perl
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
113
114
115
116
117
118
119 </pre>
120 <p>Run the code and you'll see something like this:</p>
121 <pre>
122
123
124
125
126
127     at 0 s height = 1000 m, velocity = 0 m/s
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
140
141
142
143
144
145
146 </pre>
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 
154 could write some code to handle keyboard and joysticks now, but 
155 an scriptable spaceship will be easier to start. Remember, focus
156 on the game logic!)</p>
157 <p>So, create add this simple script to the end of your file:</p>
158 <pre>
159
160
161
162
163
164     __DATA__
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
171
172
173
174
175
176
177 </pre>
178 <p>The script is straightforward: it simply states a time when we
179 will push the spaceship up with a given acceleration. It accepts
180 free text: any two numbers you type will work.</p>
181 <p>We can parse the script using this regular expression:</p>
182 <pre>
183
184
185
186
187
188     my $script_re = qr/(\d+) \D+ (\d+)/x;
189
190
191
192
193
194
195
196 </pre>
197 <p>And we can build a hash of ( time =&gt; acceleration ) with:</p>
198 <pre>
199
200
201
202
203
204     my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
205
206
207
208
209
210
211
212 </pre>
213 <p>So the middle section of the program will become:</p>
214 <pre>
215
216
217
218
219
220     my $script_re = qr/(\d+) \D+ (\d+)/x;
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
237
238
239
240
241
242
243 </pre>
244 <p>That's it!</p>
245 <p>Try to run the program, and the ship should land safely:</p>
246 <pre>
247
248
249
250
251
252     ./lunar.pl autopilot.txt 
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
267
268
269
270
271
272
273 </pre>
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
280 the 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
287 the background, and a smaller one for the spaceship.</p>
288 <p>Create the images using the Gimp, or use the images provided by
289 this 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>
296 <pre>
297
298
299
300
301
302         use SDL; #needed to get all constants
303         use SDL::Video;
304         use SDLx::App;
305         use SDL::Surface;
306         use SDL::Rect;
307         use SDL::Image;
308
309
310
311
312
313
314
315 </pre>
316 <p>Second step: initialize <code>SDLx::App</code>:</p>
317 <pre>
318
319
320
321
322
323     my $app = SDLx::App-&gt;new(
324         title  =&gt; &quot;Lunar Lander&quot;,
325         width  =&gt; 800,
326         height =&gt; 600,
327         depth  =&gt; 32,
328     );
329
330
331
332
333
334
335
336 </pre>
337 <p>Third step: load the images and create the necessary &quot;rectangles&quot;:</p>
338 <pre>
339
340
341
342
343
344         my $background = SDL::Image::load('images/background.jpg');
345         my $ship       = SDL::Image::load('images/ship.jpg');
346
347         my $background_rect = SDL::Rect-&gt;new(0,0,
348             $background-&gt;w,
349             $background-&gt;h,
350         );
351
352         my $ship_rect = SDL::Rect-&gt;new(0,0,
353             $ship-&gt;w,
354             $ship-&gt;h,
355         );
356
357
358
359
360
361
362
363 </pre>
364 <p>Fourth step: create a sub to draw the spaceship and background:</p>
365 <pre>
366
367
368
369
370
371         sub draw {
372             my ( $x, $y ) = @_; # spaceship position
373
374             # fix $y for screen resolution
375             $y = 450 * ( 1000 - $y ) / 1000;
376
377             # background
378             SDL::Video::blit_surface($background, $background_rect, $app, $background_rect );
379
380             # ship
381             my $ship_dest_rect = SDL::Rect-&gt;new(
382                 $x, $y, $ship-&gt;w, $ship-&gt;h,
383             );
384
385             SDL::Video::blit_surface($ship, $ship_rect, $app, $ship_dest_rect );
386
387             SDL::Video::update_rects($app, $background_rect);
388         }
389
390
391
392
393
394
395
396 </pre>
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
399 not update the display.</p>
400 <p>The combined image is displayed in the last line. This process of
401 combining first, and displaying later, avoids that annoying fading
402 between cycles (&quot;flickering&quot;).</p>
403 <p>Finally, add the following lines to the end of the main loop, so that
404 we call the <code>draw()</code> function with the correct spaceship
405 coordinates:</p>
406 <pre>
407
408
409
410
411
412     while ( $height &gt; 0 ) {
413
414         # ...
415
416         draw( 100, $height );
417         $app-&gt;delay(10);
418     }
419
420
421
422
423
424
425
426 </pre>
427 <p>That's it!</p>
428 <p>Run the program and watch the spaceship landing safely on the surface
429 of 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>
435 <p>This program is free software; you can redistribute it and/or modify it
436 under the same terms as Perl itself.</p>
437
438 </div>
439 </div>