Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
pods::SDL::Tutorial::LUserLContributed Perlpods::SDL::Tutorial::LunarLander(3)

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

   CATEGORY
       Tutorials

INTRODUCTION
       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.

       CREATING	A DEMO

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

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

       this will create	all three files	used in	the tutorial.

   FIRST VERSION
       We'll start with	a text version of the game.

       "What?",	you may	ask. "I	thought	it was a SDL tutorial".

       Yes, it is -- thank you for reminding me. But we'll leave the SDL part
       for later. We must build	the game logic first!

       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.

       So, here's the initial code:

	   #!/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 > 0 ) {
	       print "at $t s height = $height m, velocity = $velocity m/s\n";

	       $height	 = $height - $velocity;
	       $velocity = $velocity + $gravity;
	       $t	 = $t +	1;
	   }

	   if (	$velocity > 10 ) {
	       print "CRASH!!!\n";
	   } else {
	       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 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!!!

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

   CONTROLLING THE SHIP
       The problem with	our first spaceship is that it had no controls!

       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!)

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

	   __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;

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

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

       So the middle section of	the program will become:

	   my $script_re = qr/(\d+) \D+	(\d+)/x;
	   my %up = map	{ $_ =~	$script_re } <DATA>;

	   while ( $height > 0 ) {
	       print "at $t s height = $height m, velocity = $velocity m/s\n";

	       if ( $up{$t} ) {
		   my $a = $up{$t};
		   print "(accelerating	$a m/s^2)\n";
		   $velocity = $velocity - $a;
	       }

	       $height	 = $height - $velocity;
	       $velocity = $velocity + $gravity;
	       $t	 = $t +	1;
	   }

       That's it!

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

	   ./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

       Cool, but...

   HOW ABOUT THE GRAPHICS?
       Okay, okay... now that we have a	working	prototype, we can work on the
       graphics. But, first of all, we'll need...

       THE GRAPHICS

       Yes, the	graphics.

       We won't	use anything fancy here, just two images: a large one, for the
       background, and a smaller one for the spaceship.

       Create the images using the Gimp, or use	the images provided by this
       tutorial; Save these images in a	subdirectory called "images":
       (""images/background.jpg"" and ""images/ship.png"").

   USING SDL
       First step: use the required libraries:

	       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 "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::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,
	       );

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

	       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);
	       }

       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.

       The combined image is displayed in the last line. This process of
       combining first,	and displaying later, avoids that annoying fading
       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 ) {

	       # ...

	       draw( 100, $height );
	       $app->delay(10);
	   }

       That's it!

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

COPYRIGHT & LICENSE
       Copyright 2009 Nelson Ferraz, all rights	reserved.

       Updated and maintained by the SDL Perl project. See "AUTHORS" in	SDL.

       This program is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

perl v5.32.1			  2021-09-2pods::SDL::Tutorial::LunarLander(3)

NAME | INTRODUCTION | COPYRIGHT & LICENSE

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=pods::SDL::Tutorial::LunarLander&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help