added tuts
[sdlgit/SDL-Site.git] / pages / SDL-Tutorial-LunarLander.html-inc
diff --git a/pages/SDL-Tutorial-LunarLander.html-inc b/pages/SDL-Tutorial-LunarLander.html-inc
new file mode 100644 (file)
index 0000000..2efac82
--- /dev/null
@@ -0,0 +1,302 @@
+<div class="pod">
+<!-- INDEX START -->
+<h3 id="TOP">Index</h3>
+
+<ul><li><a href="#NAME">NAME</a></li>
+<li><a href="#INTRODUCTION">INTRODUCTION</a>
+<ul>
+<li>
+<ul><li><a href="#CREATING_A_DEMO">CREATING A DEMO</a></li>
+</ul>
+</li>
+<li><a href="#FIRST_VERSION">FIRST VERSION</a></li>
+<li><a href="#CONTROLLING_THE_SHIP">CONTROLLING THE SHIP</a></li>
+<li><a href="#HOW_ABOUT_THE_GRAPHICS">HOW ABOUT THE GRAPHICS?</a>
+<ul><li><a href="#THE_GRAPHICS">THE GRAPHICS</a></li>
+</ul>
+</li>
+<li><a href="#USING_SDL">USING SDL</a></li>
+</ul>
+</li>
+<li><a href="#COPYRIGHT_amp_LICENSE">COPYRIGHT &amp; LICENSE</a>
+</li>
+</ul><hr />
+<!-- INDEX END -->
+
+<h1 id="NAME">NAME</h1><p><a href="#TOP" class="toplink">Top</a></p>
+<div id="NAME_CONTENT">
+<p>Lunar Lander - a small tutorial on Perl SDL</p>
+
+</div>
+<h1 id="INTRODUCTION">INTRODUCTION</h1><p><a href="#TOP" class="toplink">Top</a></p>
+<div id="INTRODUCTION_CONTENT">
+<p>This is a quick introduction to Games, Perl, and  SDL (Simple 
+DirectMedia Layer, a cross-platform multimedia programming 
+library). We'll write a small game -- Lunar Lander -- in 100 
+lines of code, or less.</p>
+
+</div>
+<h3 id="CREATING_A_DEMO">CREATING A DEMO</h3>
+<div id="CREATING_A_DEMO_CONTENT">
+<p>You can see the final version of the demo code by doing:</p>
+<p>&nbsp;</p>
+<pre>   perl -MSDL::Tutorial::LunarLander=lander.pl -e1
+
+</pre>
+<p>&nbsp;</p>
+<p>this will create all three files used in the tutorial:</p>
+
+
+
+
+
+</div>
+<h2 id="FIRST_VERSION">FIRST VERSION</h2>
+<div id="FIRST_VERSION_CONTENT">
+<p>We'll start with a text version of the game.</p>
+<p>&quot;What?&quot;, you may ask. &quot;I thought it was a SDL tutorial&quot;.</p>
+<p>Yes, it is -- thank you for reminding me. But we'll leave the SDL part for
+later. We must build the game logic first!</p>
+<p>One of the traps of game programming is focusing too much on the interface.
+If we start with a simpler simulation, we can worry with the presentation
+later.</p>
+<p>So, here's the initial code:</p>
+<p>&nbsp;</p>
+<pre>    #!/usr/bin/perl
+
+    use strict;
+    use warnings;
+
+    my $height   = 1000; # m
+    my $velocity = 0;    # m/s
+    my $gravity  = 1;    # m/s^2
+
+    my $t = 0;
+
+    while ( $height &gt; 0 ) {
+        print &quot;at $t s height = $height m, velocity = $velocity m/s\n&quot;;
+
+        $height   = $height - $velocity;
+        $velocity = $velocity + $gravity;
+        $t        = $t + 1;
+    }
+
+    if ( $velocity &gt; 10 ) {
+        print &quot;CRASH!!!\n&quot;;
+    } else {
+        print &quot;You landed on the surface safely! :-D\n&quot;;
+    }
+
+</pre>
+<p>&nbsp;</p>
+<p>Run the code and you'll see something like this:</p>
+<p>&nbsp;</p>
+<pre>    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
+    at 4 s height = 994 m, velocity = 4 m/s
+    at 5 s height = 990 m, velocity = 5 m/s
+    ...
+    at 43 s height = 97 m, velocity = 43 m/s
+    at 44 s height = 54 m, velocity = 44 m/s
+    at 45 s height = 10 m, velocity = 45 m/s
+
+    CRASH!!!
+
+</pre>
+<p>&nbsp;</p>
+<p>&quot;What happened? How do I control the ship???&quot;</p>
+
+</div>
+<h2 id="CONTROLLING_THE_SHIP">CONTROLLING THE SHIP</h2>
+<div id="CONTROLLING_THE_SHIP_CONTENT">
+<p>The problem with our first spaceship is that it had no controls!</p>
+<p>So, let's fix this problem, making the spaceship scriptable. (We 
+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!)</p>
+<p>So, create add this simple script to the end of your file:</p>
+<p>&nbsp;</p>
+<pre>    __DATA__
+    at 41s, accelerate 10 m/s^2 up
+    at 43s, 10 m/s^2
+    at 45s, 10
+    at 47s, 10
+    at 49s, 10
+
+</pre>
+<p>&nbsp;</p>
+<p>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.</p>
+<p>We can parse the script using this regular expression:</p>
+<p>&nbsp;</p>
+<pre>    my $script_re = qr/(\d+) \D+ (\d+)/x;
+
+</pre>
+<p>&nbsp;</p>
+<p>And we can build a hash of ( time =&gt; acceleration ) with:</p>
+<p>&nbsp;</p>
+<pre>    my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
+
+</pre>
+<p>&nbsp;</p>
+<p>So the middle section of the program will become:</p>
+<p>&nbsp;</p>
+<pre>    my $script_re = qr/(\d+) \D+ (\d+)/x;
+    my %up = map { $_ =~ $script_re } &lt;DATA&gt;;
+
+    while ( $height &gt; 0 ) {
+        print &quot;at $t s height = $height m, velocity = $velocity m/s\n&quot;;
+
+        if ( $up{$t} ) {
+            my $a = $up{$t};
+            print &quot;(accellerating $a m/s^2)\n&quot;;
+            $velocity = $velocity - $a;
+        }
+
+        $height   = $height - $velocity;
+        $velocity = $velocity + $gravity;
+        $t        = $t + 1;
+    }
+
+</pre>
+<p>&nbsp;</p>
+<p>That's it!</p>
+<p>Try to run the program, and the ship should land safely:</p>
+<p>&nbsp;</p>
+<pre>    ./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
+    at 3 s height = 997 m, velocity = 3 m/s
+    at 4 s height = 994 m, velocity = 4 m/s
+    at 5 s height = 990 m, velocity = 5 m/s
+    ...
+    at 54 s height = 19 m, velocity = 4 m/s
+    at 55 s height = 15 m, velocity = 5 m/s
+    at 56 s height = 10 m, velocity = 6 m/s
+    at 57 s height = 4 m, velocity = 7 m/s
+
+    You landed on the surface safely! :-D
+
+</pre>
+<p>&nbsp;</p>
+<p>Cool, but...</p>
+
+</div>
+<h2 id="HOW_ABOUT_THE_GRAPHICS">HOW ABOUT THE GRAPHICS?</h2>
+<div id="HOW_ABOUT_THE_GRAPHICS_CONTENT">
+<p>Okay, okay... now that we have a working prototype, we can work on
+the graphics. But, first of all, we'll need...</p>
+
+</div>
+<h3 id="THE_GRAPHICS">THE GRAPHICS</h3>
+<div id="THE_GRAPHICS_CONTENT">
+<p>Yes, the graphics.</p>
+<p>We won't use anything fancy here, just two images: a large one, for
+the background, and a smaller one for the spaceship.</p>
+<p>Create the images using the Gimp, or use the images provided by
+this tutorial; Save these images in a subdirectory called &quot;images&quot;:
+(&quot;<code>images/background.jpg</code>&quot; and &quot;<code>images/ship.png</code>&quot;).</p>
+
+</div>
+<h2 id="USING_SDL">USING SDL</h2>
+<div id="USING_SDL_CONTENT">
+<p>First step: use the required libraries:</p>
+<p>&nbsp;</p>
+<pre>    use SDL; #needed to get all constants
+    use SDL::App;
+    use SDL::Surface;
+    use SDL::Rect;
+
+</pre>
+<p>&nbsp;</p>
+<p>Second step: initialize <code>SDL::App</code>:</p>
+<p>&nbsp;</p>
+<pre>    my $app = SDL::App-&gt;new(
+        -title  =&gt; &quot;Lunar Lander&quot;,
+        -width  =&gt; 800,
+        -height =&gt; 600,
+        -depth  =&gt; 32,
+    );
+
+</pre>
+<p>&nbsp;</p>
+<p>Third step: load the images and create the necessary &quot;rectangles&quot;:</p>
+<p>&nbsp;</p>
+<pre>    my $background = SDL::Surface-&gt;new( -name =&gt; 'images/background.jpg', );
+    my $ship       = SDL::Surface-&gt;new( -name =&gt; 'images/ship.png', );
+
+    my $background_rect = SDL::Rect-&gt;new(
+        -height =&gt; $background-&gt;height(),
+        -width  =&gt; $background-&gt;width(),
+    );
+
+    my $ship_rect = SDL::Rect-&gt;new(
+        -height =&gt; $ship-&gt;height(),
+        -width  =&gt; $ship-&gt;width(),
+    );
+
+</pre>
+<p>&nbsp;</p>
+<p>Fourth step: create a sub to draw the spaceship and background:</p>
+<p>&nbsp;</p>
+<pre>    sub draw {
+        my ( $x, $y ) = @_; # spaceship position
+
+        # fix $y for screen resolution
+        $y = 450 * ( 1000 - $y ) / 1000;
+
+        # background
+        $background-&gt;blit( $background_rect, $app, $background_rect );
+
+        # ship
+        my $ship_dest_rect = SDL::Rect-&gt;new(
+            -height =&gt; $ship-&gt;height(),
+            -width  =&gt; $ship-&gt;width(),
+            -x      =&gt; $x,
+            -y      =&gt; $y,
+        );
+
+        $ship-&gt;blit( $ship_rect, $app, $ship_dest_rect );
+
+        $app-&gt;update($background_rect);
+    }
+
+</pre>
+<p>&nbsp;</p>
+<p>Note that this sub first combines all the bitmaps, using a blit
+(&quot;Block Image Transfer&quot;) operation -- which is quite fast, but does
+not update the display.</p>
+<p>The combined image is displayed in the last line. This process of
+combining first, and displaying later, avoids that annoying fading
+between cycles (&quot;flickering&quot;).</p>
+<p>Finally, add the following lines to the end of the main loop, so that
+we call the <code>draw()</code> function with the correct spaceship
+coordinates:</p>
+<p>&nbsp;</p>
+<pre>    while ( $height &gt; 0 ) {
+
+        # ...
+
+        draw( 100, $height );
+        $app-&gt;delay(10);
+    }
+
+</pre>
+<p>&nbsp;</p>
+<p>That's it!</p>
+<p>Run the program and watch the spaceship landing safely on the surface
+of the moon.</p>
+
+</div>
+<h1 id="COPYRIGHT_amp_LICENSE">COPYRIGHT &amp; LICENSE</h1><p><a href="#TOP" class="toplink">Top</a></p>
+<div id="COPYRIGHT_amp_LICENSE_CONTENT">
+<p>Copyright 2009 Nelson Ferraz, all rights reserved.</p>
+<p>This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.</p>
+
+</div>
+</div>
\ No newline at end of file