1SDL::Tutorial::LunarLanUdseerr(3C)ontributed Perl DocumeSnDtLa:t:iTountorial::LunarLander(3)
2
3
4

NAME

6       SDL::Tutorial::LunarLander - a small tutorial on Perl SDL
7
8   CATEGORY
9       Tutorials
10

INTRODUCTION

12       This is a quick introduction to Games, Perl, and  SDL (Simple
13       DirectMedia Layer, a cross-platform multimedia programming library).
14       We'll write a small game -- Lunar Lander -- in 100 lines of code, or
15       less.
16
17       CREATING A DEMO
18
19       You can see the final version of the demo code by doing:
20
21          perl -MSDL::Tutorial::LunarLander=lander.pl -e1
22
23       this will create all three files used in the tutorial.
24
25   FIRST VERSION
26       We'll start with a text version of the game.
27
28       "What?", you may ask. "I thought it was a SDL tutorial".
29
30       Yes, it is -- thank you for reminding me. But we'll leave the SDL part
31       for later. We must build the game logic first!
32
33       One of the traps of game programming is focusing too much on the
34       interface.  If we start with a simpler simulation, we can worry with
35       the presentation later.
36
37       So, here's the initial code:
38
39           #!/usr/bin/perl
40
41           use strict;
42           use warnings;
43
44           my $height   = 1000; # m
45           my $velocity = 0;    # m/s
46           my $gravity  = 1;    # m/s^2
47
48           my $t = 0;
49
50           while ( $height > 0 ) {
51               print "at $t s height = $height m, velocity = $velocity m/s\n";
52
53               $height   = $height - $velocity;
54               $velocity = $velocity + $gravity;
55               $t        = $t + 1;
56           }
57
58           if ( $velocity > 10 ) {
59               print "CRASH!!!\n";
60           } else {
61               print "You landed on the surface safely! :-D\n";
62           }
63
64       Run the code and you'll see something like this:
65
66           at 0 s height = 1000 m, velocity = 0 m/s
67           at 1 s height = 1000 m, velocity = 1 m/s
68           at 2 s height = 999 m, velocity = 2 m/s
69           at 3 s height = 997 m, velocity = 3 m/s
70           at 4 s height = 994 m, velocity = 4 m/s
71           at 5 s height = 990 m, velocity = 5 m/s
72           ...
73           at 43 s height = 97 m, velocity = 43 m/s
74           at 44 s height = 54 m, velocity = 44 m/s
75           at 45 s height = 10 m, velocity = 45 m/s
76
77           CRASH!!!
78
79       "What happened? How do I control the ship???"
80
81   CONTROLLING THE SHIP
82       The problem with our first spaceship is that it had no controls!
83
84       So, let's fix this problem, making the spaceship scriptable. (We could
85       write some code to handle keyboard and joysticks now, but an scriptable
86       spaceship will be easier to start. Remember, focus on the game logic!)
87
88       So, create add this simple script to the end of your file:
89
90           __DATA__
91           at 41s, accelerate 10 m/s^2 up
92           at 43s, 10 m/s^2
93           at 45s, 10
94           at 47s, 10
95           at 49s, 10
96
97       The script is straightforward: it simply states a time when we will
98       push the spaceship up with a given acceleration. It accepts free text:
99       any two numbers you type will work.
100
101       We can parse the script using this regular expression:
102
103           my $script_re = qr/(\d+) \D+ (\d+)/x;
104
105       And we can build a hash of ( time => acceleration ) with:
106
107           my %up = map { $_ =~ $script_re } <DATA>;
108
109       So the middle section of the program will become:
110
111           my $script_re = qr/(\d+) \D+ (\d+)/x;
112           my %up = map { $_ =~ $script_re } <DATA>;
113
114           while ( $height > 0 ) {
115               print "at $t s height = $height m, velocity = $velocity m/s\n";
116
117               if ( $up{$t} ) {
118                   my $a = $up{$t};
119                   print "(accelerating $a m/s^2)\n";
120                   $velocity = $velocity - $a;
121               }
122
123               $height   = $height - $velocity;
124               $velocity = $velocity + $gravity;
125               $t        = $t + 1;
126           }
127
128       That's it!
129
130       Try to run the program, and the ship should land safely:
131
132           ./lunar.pl autopilot.txt
133           at 0 s height = 1000 m, velocity = 0 m/s
134           at 1 s height = 1000 m, velocity = 1 m/s
135           at 2 s height = 999 m, velocity = 2 m/s
136           at 3 s height = 997 m, velocity = 3 m/s
137           at 4 s height = 994 m, velocity = 4 m/s
138           at 5 s height = 990 m, velocity = 5 m/s
139           ...
140           at 54 s height = 19 m, velocity = 4 m/s
141           at 55 s height = 15 m, velocity = 5 m/s
142           at 56 s height = 10 m, velocity = 6 m/s
143           at 57 s height = 4 m, velocity = 7 m/s
144
145           You landed on the surface safely! :-D
146
147       Cool, but...
148
149   HOW ABOUT THE GRAPHICS?
150       Okay, okay... now that we have a working prototype, we can work on the
151       graphics. But, first of all, we'll need...
152
153       THE GRAPHICS
154
155       Yes, the graphics.
156
157       We won't use anything fancy here, just two images: a large one, for the
158       background, and a smaller one for the spaceship.
159
160       Create the images using the Gimp, or use the images provided by this
161       tutorial; Save these images in a subdirectory called "images":
162       (""images/background.jpg"" and ""images/ship.png"").
163
164   USING SDL
165       First step: use the required libraries:
166
167               use SDL; #needed to get all constants
168               use SDL::Video;
169               use SDLx::App;
170               use SDL::Surface;
171               use SDL::Rect;
172               use SDL::Image;
173
174       Second step: initialize "SDLx::App":
175
176           my $app = SDLx::App->new(
177               title  => "Lunar Lander",
178               width  => 800,
179               height => 600,
180               depth  => 32,
181           );
182
183       Third step: load the images and create the necessary "rectangles":
184
185               my $background = SDL::Image::load('images/background.jpg');
186               my $ship       = SDL::Image::load('images/ship.jpg');
187
188               my $background_rect = SDL::Rect->new(0,0,
189                   $background->w,
190                   $background->h,
191               );
192
193               my $ship_rect = SDL::Rect->new(0,0,
194                   $ship->w,
195                   $ship->h,
196               );
197
198       Fourth step: create a sub to draw the spaceship and background:
199
200               sub draw {
201                   my ( $x, $y ) = @_; # spaceship position
202
203                   # fix $y for screen resolution
204                   $y = 450 * ( 1000 - $y ) / 1000;
205
206                   # background
207                   SDL::Video::blit_surface($background, $background_rect, $app, $background_rect );
208
209                   # ship
210                   my $ship_dest_rect = SDL::Rect->new(
211                       $x, $y, $ship->w, $ship->h,
212                   );
213
214                   SDL::Video::blit_surface($ship, $ship_rect, $app, $ship_dest_rect );
215
216                   SDL::Video::update_rects($app, $background_rect);
217               }
218
219       Note that this sub first combines all the bitmaps, using a blit ("Block
220       Image Transfer") operation -- which is quite fast, but does not update
221       the display.
222
223       The combined image is displayed in the last line. This process of
224       combining first, and displaying later, avoids that annoying fading
225       between cycles ("flickering").
226
227       Finally, add the following lines to the end of the main loop, so that
228       we call the "draw()" function with the correct spaceship coordinates:
229
230           while ( $height > 0 ) {
231
232               # ...
233
234               draw( 100, $height );
235               $app->delay(10);
236           }
237
238       That's it!
239
240       Run the program and watch the spaceship landing safely on the surface
241       of the moon.
242
244       Copyright 2009 Nelson Ferraz, all rights reserved.
245
246       Updated and maintained by the SDL Perl project. See "AUTHORS" in SDL.
247
248       This program is free software; you can redistribute it and/or modify it
249       under the same terms as Perl itself.
250
251
252
253perl v5.36.0                      2022-07-22     SDL::Tutorial::LunarLander(3)
Impressum