a20a1fda0e7998bf598602cc172fcb9031f558ae
[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>Lunar Lander - 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 <p>&nbsp;</p>
51 <pre>   perl -MSDL::Tutorial::LunarLander=lander.pl -e1
52
53 </pre>
54 <p>&nbsp;</p>
55 <p>this will create all three files used in the tutorial:</p>
56
57
58
59
60
61 </div>
62 <h2 id="FIRST_VERSION">FIRST VERSION</h2>
63 <div id="FIRST_VERSION_CONTENT">
64 <p>We'll start with a text version of the game.</p>
65 <p>&quot;What?&quot;, you may ask. &quot;I thought it was a SDL tutorial&quot;.</p>
66 <p>Yes, it is -- thank you for reminding me. But we'll leave the SDL part for
67 later. We must build the game logic first!</p>
68 <p>One of the traps of game programming is focusing too much on the interface.
69 If we start with a simpler simulation, we can worry with the presentation
70 later.</p>
71 <p>So, here's the initial code:</p>
72 <p>&nbsp;</p>
73 <pre>    #!/usr/bin/perl
74
75     use strict;
76     use warnings;
77
78     my $height   = 1000; # m
79     my $velocity = 0;    # m/s
80     my $gravity  = 1;    # m/s^2
81
82     my $t = 0;
83
84     while ( $height &gt; 0 ) {
85         print &quot;at $t s height = $height m, velocity = $velocity m/s\n&quot;;
86
87         $height   = $height - $velocity;
88         $velocity = $velocity + $gravity;
89         $t        = $t + 1;
90     }
91
92     if ( $velocity &gt; 10 ) {
93         print &quot;CRASH!!!\n&quot;;
94     } else {
95         print &quot;You landed on the surface safely! :-D\n&quot;;
96     }
97
98 </pre>
99 <p>&nbsp;</p>
100 <p>Run the code and you'll see something like this:</p>
101 <p>&nbsp;</p>
102 <pre>    at 0 s height = 1000 m, velocity = 0 m/s
103     at 1 s height = 1000 m, velocity = 1 m/s
104     at 2 s height = 999 m, velocity = 2 m/s
105     at 3 s height = 997 m, velocity = 3 m/s
106     at 4 s height = 994 m, velocity = 4 m/s
107     at 5 s height = 990 m, velocity = 5 m/s
108     ...
109     at 43 s height = 97 m, velocity = 43 m/s
110     at 44 s height = 54 m, velocity = 44 m/s
111     at 45 s height = 10 m, velocity = 45 m/s
112
113     CRASH!!!
114
115 </pre>
116 <p>&nbsp;</p>
117 <p>&quot;What happened? How do I control the ship???&quot;</p>
118
119 </div>
120 <h2 id="CONTROLLING_THE_SHIP">CONTROLLING THE SHIP</h2>
121 <div id="CONTROLLING_THE_SHIP_CONTENT">
122 <p>The problem with our first spaceship is that it had no controls!</p>
123 <p>So, let's fix this problem, making the spaceship scriptable. (We 
124 could write some code to handle keyboard and joysticks now, but 
125 an scriptable spaceship will be easier to start. Remember, focus
126 on the game logic!)</p>
127 <p>So, create add this simple script to the end of your file:</p>
128 <p>&nbsp;</p>
129 <pre>    __DATA__
130     at 41s, accelerate 10 m/s^2 up
131     at 43s, 10 m/s^2
132     at 45s, 10
133     at 47s, 10
134     at 49s, 10
135
136 </pre>
137 <p>&nbsp;</p>
138 <p>The script is straightforward: it simply states a time when we
139 will push the spaceship up with a given acceleration. It accepts
140 free text: any two numbers you type will work.</p>
141 <p>We can parse the script using this regular expression:</p>
142 <p>&nbsp;</p>
143 <pre>    my $script_re = qr/(\d+) \D+ (\d+)/x;
144
145 </pre>
146 <p>&nbsp;</p>
147 <p>And we can build a hash of ( time =&gt; acceleration ) with:</p>
148 <p>&nbsp;</p>
149 <pre>    my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
150
151 </pre>
152 <p>&nbsp;</p>
153 <p>So the middle section of the program will become:</p>
154 <p>&nbsp;</p>
155 <pre>    my $script_re = qr/(\d+) \D+ (\d+)/x;
156     my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
157
158     while ( $height &gt; 0 ) {
159         print &quot;at $t s height = $height m, velocity = $velocity m/s\n&quot;;
160
161         if ( $up{$t} ) {
162             my $a = $up{$t};
163             print &quot;(accellerating $a m/s^2)\n&quot;;
164             $velocity = $velocity - $a;
165         }
166
167         $height   = $height - $velocity;
168         $velocity = $velocity + $gravity;
169         $t        = $t + 1;
170     }
171
172 </pre>
173 <p>&nbsp;</p>
174 <p>That's it!</p>
175 <p>Try to run the program, and the ship should land safely:</p>
176 <p>&nbsp;</p>
177 <pre>    ./lunar.pl autopilot.txt 
178     at 0 s height = 1000 m, velocity = 0 m/s
179     at 1 s height = 1000 m, velocity = 1 m/s
180     at 2 s height = 999 m, velocity = 2 m/s
181     at 3 s height = 997 m, velocity = 3 m/s
182     at 4 s height = 994 m, velocity = 4 m/s
183     at 5 s height = 990 m, velocity = 5 m/s
184     ...
185     at 54 s height = 19 m, velocity = 4 m/s
186     at 55 s height = 15 m, velocity = 5 m/s
187     at 56 s height = 10 m, velocity = 6 m/s
188     at 57 s height = 4 m, velocity = 7 m/s
189
190     You landed on the surface safely! :-D
191
192 </pre>
193 <p>&nbsp;</p>
194 <p>Cool, but...</p>
195
196 </div>
197 <h2 id="HOW_ABOUT_THE_GRAPHICS">HOW ABOUT THE GRAPHICS?</h2>
198 <div id="HOW_ABOUT_THE_GRAPHICS_CONTENT">
199 <p>Okay, okay... now that we have a working prototype, we can work on
200 the graphics. But, first of all, we'll need...</p>
201
202 </div>
203 <h3 id="THE_GRAPHICS">THE GRAPHICS</h3>
204 <div id="THE_GRAPHICS_CONTENT">
205 <p>Yes, the graphics.</p>
206 <p>We won't use anything fancy here, just two images: a large one, for
207 the background, and a smaller one for the spaceship.</p>
208 <p>Create the images using the Gimp, or use the images provided by
209 this tutorial; Save these images in a subdirectory called &quot;images&quot;:
210 (&quot;<code>images/background.jpg</code>&quot; and &quot;<code>images/ship.png</code>&quot;).</p>
211
212 </div>
213 <h2 id="USING_SDL">USING SDL</h2>
214 <div id="USING_SDL_CONTENT">
215 <p>First step: use the required libraries:</p>
216 <p>&nbsp;</p>
217 <pre>    use SDL; #needed to get all constants
218     use SDL::App;
219     use SDL::Surface;
220     use SDL::Rect;
221
222 </pre>
223 <p>&nbsp;</p>
224 <p>Second step: initialize <code>SDL::App</code>:</p>
225 <p>&nbsp;</p>
226 <pre>    my $app = SDL::App-&gt;new(
227         -title  =&gt; &quot;Lunar Lander&quot;,
228         -width  =&gt; 800,
229         -height =&gt; 600,
230         -depth  =&gt; 32,
231     );
232
233 </pre>
234 <p>&nbsp;</p>
235 <p>Third step: load the images and create the necessary &quot;rectangles&quot;:</p>
236 <p>&nbsp;</p>
237 <pre>    my $background = SDL::Surface-&gt;new( -name =&gt; 'images/background.jpg', );
238     my $ship       = SDL::Surface-&gt;new( -name =&gt; 'images/ship.png', );
239
240     my $background_rect = SDL::Rect-&gt;new(
241         -height =&gt; $background-&gt;height(),
242         -width  =&gt; $background-&gt;width(),
243     );
244
245     my $ship_rect = SDL::Rect-&gt;new(
246         -height =&gt; $ship-&gt;height(),
247         -width  =&gt; $ship-&gt;width(),
248     );
249
250 </pre>
251 <p>&nbsp;</p>
252 <p>Fourth step: create a sub to draw the spaceship and background:</p>
253 <p>&nbsp;</p>
254 <pre>    sub draw {
255         my ( $x, $y ) = @_; # spaceship position
256
257         # fix $y for screen resolution
258         $y = 450 * ( 1000 - $y ) / 1000;
259
260         # background
261         $background-&gt;blit( $background_rect, $app, $background_rect );
262
263         # ship
264         my $ship_dest_rect = SDL::Rect-&gt;new(
265             -height =&gt; $ship-&gt;height(),
266             -width  =&gt; $ship-&gt;width(),
267             -x      =&gt; $x,
268             -y      =&gt; $y,
269         );
270
271         $ship-&gt;blit( $ship_rect, $app, $ship_dest_rect );
272
273         $app-&gt;update($background_rect);
274     }
275
276 </pre>
277 <p>&nbsp;</p>
278 <p>Note that this sub first combines all the bitmaps, using a blit
279 (&quot;Block Image Transfer&quot;) operation -- which is quite fast, but does
280 not update the display.</p>
281 <p>The combined image is displayed in the last line. This process of
282 combining first, and displaying later, avoids that annoying fading
283 between cycles (&quot;flickering&quot;).</p>
284 <p>Finally, add the following lines to the end of the main loop, so that
285 we call the <code>draw()</code> function with the correct spaceship
286 coordinates:</p>
287 <p>&nbsp;</p>
288 <pre>    while ( $height &gt; 0 ) {
289
290         # ...
291
292         draw( 100, $height );
293         $app-&gt;delay(10);
294     }
295
296 </pre>
297 <p>&nbsp;</p>
298 <p>That's it!</p>
299 <p>Run the program and watch the spaceship landing safely on the surface
300 of the moon.</p>
301
302 </div>
303 <h1 id="COPYRIGHT_amp_LICENSE">COPYRIGHT &amp; LICENSE</h1><p><a href="#TOP" class="toplink">Top</a></p>
304 <div id="COPYRIGHT_amp_LICENSE_CONTENT">
305 <p>Copyright 2009 Nelson Ferraz, all rights reserved.</p>
306 <p>This program is free software; you can redistribute it and/or modify it
307 under the same terms as Perl itself.</p>
308
309 </div>
310 </div>