updated old docs
[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">
31<p>Lunar Lander - a small tutorial on Perl SDL</p>
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>
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
67later. We must build the game logic first!</p>
68<p>One of the traps of game programming is focusing too much on the interface.
69If we start with a simpler simulation, we can worry with the presentation
70later.</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
124could write some code to handle keyboard and joysticks now, but
125an scriptable spaceship will be easier to start. Remember, focus
126on 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
139will push the spaceship up with a given acceleration. It accepts
140free 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
200the 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
207the background, and a smaller one for the spaceship.</p>
208<p>Create the images using the Gimp, or use the images provided by
209this 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>
1f5d8082 217<pre> use SDL; #needed to get all constants
218 use SDL::Video;
219 use SDL::App;
220 use SDL::Surface;
221 use SDL::Rect;
222 use SDL::Image;
b3ef54ec 223
224</pre>
225<p>&nbsp;</p>
226<p>Second step: initialize <code>SDL::App</code>:</p>
227<p>&nbsp;</p>
228<pre> my $app = SDL::App-&gt;new(
229 -title =&gt; &quot;Lunar Lander&quot;,
230 -width =&gt; 800,
231 -height =&gt; 600,
232 -depth =&gt; 32,
233 );
234
235</pre>
236<p>&nbsp;</p>
237<p>Third step: load the images and create the necessary &quot;rectangles&quot;:</p>
238<p>&nbsp;</p>
1f5d8082 239<pre> my $background = SDL::Image::load('images/background.jpg');
240 my $ship = SDL::Image::load('images/ship.jpg');
b3ef54ec 241
1f5d8082 242 my $background_rect = SDL::Rect-&gt;new(0,0,
243 $background-&gt;w,
244 $background-&gt;h,
245 );
b3ef54ec 246
1f5d8082 247 my $ship_rect = SDL::Rect-&gt;new(0,0,
248 $ship-&gt;w,
249 $ship-&gt;h,
250 );
b3ef54ec 251
252</pre>
253<p>&nbsp;</p>
254<p>Fourth step: create a sub to draw the spaceship and background:</p>
255<p>&nbsp;</p>
1f5d8082 256<pre> sub draw {
257 my ( $x, $y ) = @_; # spaceship position
b3ef54ec 258
1f5d8082 259 # fix $y for screen resolution
260 $y = 450 * ( 1000 - $y ) / 1000;
b3ef54ec 261
1f5d8082 262 # background
263 SDL::Video::blit_surface($background, $background_rect, $app, $background_rect );
b3ef54ec 264
1f5d8082 265 # ship
266 my $ship_dest_rect = SDL::Rect-&gt;new(
267 $x, $y, $ship-&gt;w, $ship-&gt;h,
268 );
b3ef54ec 269
1f5d8082 270 SDL::Video::blit_surface($ship, $ship_rect, $app, $ship_dest_rect );
b3ef54ec 271
1f5d8082 272 SDL::Video::update_rects($app, $background_rect);
273 }
b3ef54ec 274
275</pre>
276<p>&nbsp;</p>
277<p>Note that this sub first combines all the bitmaps, using a blit
278(&quot;Block Image Transfer&quot;) operation -- which is quite fast, but does
279not update the display.</p>
280<p>The combined image is displayed in the last line. This process of
281combining first, and displaying later, avoids that annoying fading
282between cycles (&quot;flickering&quot;).</p>
283<p>Finally, add the following lines to the end of the main loop, so that
284we call the <code>draw()</code> function with the correct spaceship
285coordinates:</p>
286<p>&nbsp;</p>
287<pre> while ( $height &gt; 0 ) {
288
289 # ...
290
291 draw( 100, $height );
292 $app-&gt;delay(10);
293 }
294
295</pre>
296<p>&nbsp;</p>
297<p>That's it!</p>
298<p>Run the program and watch the spaceship landing safely on the surface
299of the moon.</p>
300
301</div>
302<h1 id="COPYRIGHT_amp_LICENSE">COPYRIGHT &amp; LICENSE</h1><p><a href="#TOP" class="toplink">Top</a></p>
303<div id="COPYRIGHT_amp_LICENSE_CONTENT">
304<p>Copyright 2009 Nelson Ferraz, all rights reserved.</p>
305<p>This program is free software; you can redistribute it and/or modify it
306under the same terms as Perl itself.</p>
307
308</div>
309</div>