3 <h3 id="TOP">Index</h3>
5 <ul><li><a href="#NAME">NAME</a>
6 <ul><li><a href="#CATEGORY">CATEGORY</a></li>
9 <li><a href="#INTRODUCTION">INTRODUCTION</a>
12 <ul><li><a href="#CREATING_A_DEMO">CREATING A DEMO</a></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>
21 <li><a href="#USING_SDL">USING SDL</a></li>
24 <li><a href="#COPYRIGHT_amp_LICENSE">COPYRIGHT & LICENSE</a>
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>
34 <h2 id="CATEGORY">CATEGORY</h2>
35 <div id="CATEGORY_CONTENT">
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>
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>
56 perl -MSDL::Tutorial::LunarLander=lander.pl -e1
65 <p>this will create all three files used in the tutorial.</p>
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>"What?", you may ask. "I thought it was a SDL tutorial".</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
81 <p>So, here's the initial code:</p>
93 my $height = 1000; # m
94 my $velocity = 0; # m/s
95 my $gravity = 1; # m/s^2
99 while ( $height > 0 ) {
100 print "at $t s height = $height m, velocity = $velocity m/s\n";
102 $height = $height - $velocity;
103 $velocity = $velocity + $gravity;
107 if ( $velocity > 10 ) {
108 print "CRASH!!!\n";
110 print "You landed on the surface safely! :-D\n";
120 <p>Run the code and you'll see something like this:</p>
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
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
147 <p>"What happened? How do I control the ship???"</p>
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>
165 at 41s, accelerate 10 m/s^2 up
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>
188 my $script_re = qr/(\d+) \D+ (\d+)/x;
197 <p>And we can build a hash of ( time => acceleration ) with:</p>
204 my %up = map { $_ =~ $script_re } <DATA>;
213 <p>So the middle section of the program will become:</p>
220 my $script_re = qr/(\d+) \D+ (\d+)/x;
221 my %up = map { $_ =~ $script_re } <DATA>;
223 while ( $height > 0 ) {
224 print "at $t s height = $height m, velocity = $velocity m/s\n";
228 print "(accellerating $a m/s^2)\n";
229 $velocity = $velocity - $a;
232 $height = $height - $velocity;
233 $velocity = $velocity + $gravity;
245 <p>Try to run the program, and the ship should land safely:</p>
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
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
265 You landed on the surface safely! :-D
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>
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 "images":
290 ("<code>images/background.jpg</code>" and "<code>images/ship.png</code>").</p>
293 <h2 id="USING_SDL">USING SDL</h2>
294 <div id="USING_SDL_CONTENT">
295 <p>First step: use the required libraries:</p>
302 use SDL; #needed to get all constants
316 <p>Second step: initialize <code>SDLx::App</code>:</p>
323 my $app = SDLx::App->new(
324 title => "Lunar Lander",
337 <p>Third step: load the images and create the necessary "rectangles":</p>
344 my $background = SDL::Image::load('images/background.jpg');
345 my $ship = SDL::Image::load('images/ship.jpg');
347 my $background_rect = SDL::Rect->new(0,0,
352 my $ship_rect = SDL::Rect->new(0,0,
364 <p>Fourth step: create a sub to draw the spaceship and background:</p>
372 my ( $x, $y ) = @_; # spaceship position
374 # fix $y for screen resolution
375 $y = 450 * ( 1000 - $y ) / 1000;
378 SDL::Video::blit_surface($background, $background_rect, $app, $background_rect );
381 my $ship_dest_rect = SDL::Rect->new(
382 $x, $y, $ship->w, $ship->h,
385 SDL::Video::blit_surface($ship, $ship_rect, $app, $ship_dest_rect );
387 SDL::Video::update_rects($app, $background_rect);
397 <p>Note that this sub first combines all the bitmaps, using a blit
398 ("Block Image Transfer") 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 ("flickering").</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
412 while ( $height > 0 ) {
416 draw( 100, $height );
428 <p>Run the program and watch the spaceship landing safely on the surface
432 <h1 id="COPYRIGHT_amp_LICENSE">COPYRIGHT & 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>Updated and maintained by the SDL Perl project. See <a href="/SDL.html#AUTHORS">/SDL.html#AUTHORS</a>.</p>
436 <p>This program is free software; you can redistribute it and/or modify it
437 under the same terms as Perl itself.</p>