X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pages%2FSDL-Tutorial-LunarLander.html-inc;h=182132c501952ff70b671b9b254c7ed2b6dddcc7;hb=505f308d8b092747da8b2f5e9781475a1f06dfe8;hp=a20a1fda0e7998bf598602cc172fcb9031f558ae;hpb=60f74f6f8f641636a03bd789ede09bebe208108b;p=sdlgit%2FSDL-Site.git diff --git a/pages/SDL-Tutorial-LunarLander.html-inc b/pages/SDL-Tutorial-LunarLander.html-inc index a20a1fd..182132c 100644 --- a/pages/SDL-Tutorial-LunarLander.html-inc +++ b/pages/SDL-Tutorial-LunarLander.html-inc @@ -28,7 +28,7 @@

NAME

Top

-

Lunar Lander - a small tutorial on Perl SDL

+

SDL::Tutorial::LunarLander - a small tutorial on Perl SDL

CATEGORY

@@ -47,12 +47,22 @@ lines of code, or less.

CREATING A DEMO

You can see the final version of the demo code by doing:

-

 

-
   perl -MSDL::Tutorial::LunarLander=lander.pl -e1
+
+
+
+
+
+
+   perl -MSDL::Tutorial::LunarLander=lander.pl -e1
+
+
+
+
+
+
 
 
-

 

-

this will create all three files used in the tutorial:

+

this will create all three files used in the tutorial.

@@ -69,8 +79,13 @@ later. We must build the game logic first!

If we start with a simpler simulation, we can worry with the presentation later.

So, here's the initial code:

-

 

-
    #!/usr/bin/perl
+
+
+
+
+
+
+    #!/usr/bin/perl
 
     use strict;
     use warnings;
@@ -95,11 +110,21 @@ later.

print "You landed on the surface safely! :-D\n"; } + + + + + +
-

 

Run the code and you'll see something like this:

-

 

-
    at 0 s height = 1000 m, velocity = 0 m/s
+
+
+
+
+
+
+    at 0 s height = 1000 m, velocity = 0 m/s
     at 1 s height = 1000 m, velocity = 1 m/s
     at 2 s height = 999 m, velocity = 2 m/s
     at 3 s height = 997 m, velocity = 3 m/s
@@ -112,8 +137,13 @@ later.

CRASH!!! + + + + + +
-

 

"What happened? How do I control the ship???"

@@ -125,34 +155,69 @@ could write some code to handle keyboard and joysticks now, but an scriptable spaceship will be easier to start. Remember, focus on the game logic!)

So, create add this simple script to the end of your file:

-

 

-
    __DATA__
+
+
+
+
+
+
+    __DATA__
     at 41s, accelerate 10 m/s^2 up
     at 43s, 10 m/s^2
     at 45s, 10
     at 47s, 10
     at 49s, 10
 
+
+
+
+
+
+
 
-

 

The script is straightforward: it simply states a time when we will push the spaceship up with a given acceleration. It accepts free text: any two numbers you type will work.

We can parse the script using this regular expression:

-

 

-
    my $script_re = qr/(\d+) \D+ (\d+)/x;
+
+
+
+
+
+
+    my $script_re = qr/(\d+) \D+ (\d+)/x;
+
+
+
+
+
+
 
 
-

 

And we can build a hash of ( time => acceleration ) with:

-

 

-
    my %up = map { $_ =~ $script_re } <DATA>;
+
+
+
+
+
+
+    my %up = map { $_ =~ $script_re } <DATA>;
+
+
+
+
+
+
 
 
-

 

So the middle section of the program will become:

-

 

-
    my $script_re = qr/(\d+) \D+ (\d+)/x;
+
+
+
+
+
+
+    my $script_re = qr/(\d+) \D+ (\d+)/x;
     my %up = map { $_ =~ $script_re } <DATA>;
 
     while ( $height > 0 ) {
@@ -169,12 +234,22 @@ free text: any two numbers you type will work.

$t = $t + 1; } + + + + + +
-

 

That's it!

Try to run the program, and the ship should land safely:

-

 

-
    ./lunar.pl autopilot.txt 
+
+
+
+
+
+
+    ./lunar.pl autopilot.txt 
     at 0 s height = 1000 m, velocity = 0 m/s
     at 1 s height = 1000 m, velocity = 1 m/s
     at 2 s height = 999 m, velocity = 2 m/s
@@ -189,8 +264,13 @@ free text: any two numbers you type will work.

You landed on the surface safely! :-D + + + + + +
-

 

Cool, but...

@@ -213,68 +293,107 @@ this tutorial; Save these images in a subdirectory called "images":

USING SDL

First step: use the required libraries:

-

 

-
    use SDL; #needed to get all constants
-    use SDL::App;
-    use SDL::Surface;
-    use SDL::Rect;
+
+
+
+
+
+
+	use SDL; #needed to get all constants
+	use SDL::Video;
+	use SDLx::App;
+	use SDL::Surface;
+	use SDL::Rect;
+	use SDL::Image;
+
+
+
+
+
+
 
 
-

 

-

Second step: initialize SDL::App:

-

 

-
    my $app = SDL::App->new(
-        -title  => "Lunar Lander",
-        -width  => 800,
-        -height => 600,
-        -depth  => 32,
+

Second step: initialize SDLx::App:

+
+
+
+
+
+
+    my $app = SDLx::App->new(
+        title  => "Lunar Lander",
+        width  => 800,
+        height => 600,
+        depth  => 32,
     );
 
+
+
+
+
+
+
 
-

 

Third step: load the images and create the necessary "rectangles":

-

 

-
    my $background = SDL::Surface->new( -name => 'images/background.jpg', );
-    my $ship       = SDL::Surface->new( -name => 'images/ship.png', );
+
+
+
+
+
+
+	my $background = SDL::Image::load('images/background.jpg');
+	my $ship       = SDL::Image::load('images/ship.jpg');
+
+	my $background_rect = SDL::Rect->new(0,0,
+	    $background->w,
+	    $background->h,
+	);
+
+	my $ship_rect = SDL::Rect->new(0,0,
+	    $ship->w,
+	    $ship->h,
+	);
+
+
+
+
 
-    my $background_rect = SDL::Rect->new(
-        -height => $background->height(),
-        -width  => $background->width(),
-    );
 
-    my $ship_rect = SDL::Rect->new(
-        -height => $ship->height(),
-        -width  => $ship->width(),
-    );
 
 
-

 

Fourth step: create a sub to draw the spaceship and background:

-

 

-
    sub draw {
-        my ( $x, $y ) = @_; # spaceship position
+
+
+
+
+
+
+	sub draw {
+	    my ( $x, $y ) = @_; # spaceship position
+
+	    # fix $y for screen resolution
+	    $y = 450 * ( 1000 - $y ) / 1000;
+
+	    # background
+	    SDL::Video::blit_surface($background, $background_rect, $app, $background_rect );
+
+	    # ship
+	    my $ship_dest_rect = SDL::Rect->new(
+		$x, $y, $ship->w, $ship->h,
+	    );
+
+	    SDL::Video::blit_surface($ship, $ship_rect, $app, $ship_dest_rect );
+
+	    SDL::Video::update_rects($app, $background_rect);
+	}
+
 
-        # fix $y for screen resolution
-        $y = 450 * ( 1000 - $y ) / 1000;
 
-        # background
-        $background->blit( $background_rect, $app, $background_rect );
 
-        # ship
-        my $ship_dest_rect = SDL::Rect->new(
-            -height => $ship->height(),
-            -width  => $ship->width(),
-            -x      => $x,
-            -y      => $y,
-        );
 
-        $ship->blit( $ship_rect, $app, $ship_dest_rect );
 
-        $app->update($background_rect);
-    }
 
 
-

 

Note that this sub first combines all the bitmaps, using a blit ("Block Image Transfer") operation -- which is quite fast, but does not update the display.

@@ -284,8 +403,13 @@ between cycles ("flickering").

Finally, add the following lines to the end of the main loop, so that we call the draw() function with the correct spaceship coordinates:

-

 

-
    while ( $height > 0 ) {
+
+
+
+
+
+
+    while ( $height > 0 ) {
 
         # ...
 
@@ -293,8 +417,13 @@ coordinates:

$app->delay(10); } + + + + + +
-

 

That's it!

Run the program and watch the spaceship landing safely on the surface of the moon.