1SDL::Tutorial::LunarLanUdseerr(3C)ontributed Perl DocumeSnDtLa:t:iTountorial::LunarLander(3)
2
3
4
6 SDL::Tutorial::LunarLander - a small tutorial on Perl SDL
7
8 CATEGORY
9 Tutorials
10
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)