<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl -w
#####################################################
### Copyright (c) 2002 Russell B Cecala. All rights
### reserved.  This program is free software; you can
### redistribute it and/or modify it under the same 
### terms as Perl itself.
#####################################################

use strict;
use lib ('.');

use Tk;
use Tk::Canvas;
use Math::Trig;
use Vector2D;
use Viewport;
use Clip2;
use Getopt::Std;

my $width 		= 500;
my $height 		= 500;
my $background 		= 'blue';
my $fill 		= 'yellow';
my $initialX		= 0;
my $initialY		= 800;
my $gravity 		= new Vector2D(0, 1.62);
my $acceleration 	= new Vector2D(0, 20.0);
my $LanderVelocity 	= new Vector2D(0, 0 );
my $staticWindow 	= 0;
my $crashSpeed 		= 10.0;
my $crashSlope 		= 0.0;
my $fuel 		= 20;

my %opts 		= ();
getopts( 'W:H:b:f:F:g:x:y:X:Y:a:c:s:Sh', \%opts );
if( $opts{W} ) { $width 	= $opts{W} ; }
if( $opts{H} ) { $height 	= $opts{H} ; }
if( $opts{b} ) { $background 	= $opts{b} ; }
if( $opts{f} ) { $fill 		= $opts{f} ; }
if( $opts{F} ) { $fuel 		= $opts{F} ; }
if( $opts{x} ) { $initialX 	= $opts{x} ; }
if( $opts{y} ) { $initialY 	= $opts{y} ; }
if( $opts{g} ) { $gravity       -&gt;sety ($opts{g}) ; }
if( $opts{a} ) { $acceleration  -&gt;sety ($opts{a}) ; }
if( $opts{X} ) { $LanderVelocity-&gt;setx ($opts{X}) ; }
if( $opts{Y} ) { $LanderVelocity-&gt;sety ($opts{Y}) ; }
if( $opts{c} ) { $crashSpeed 	= $opts{c}; }
if( $opts{s} ) { $crashSlope 	= $opts{s}; }
if( $opts{S} ) { $staticWindow 	= 1; }
if( $opts{h} ) { &amp;usage; exit;}

sub usage {
print &lt;&lt;USAGE;
	-W &lt;canvas width&gt;	Default is 500
	-H &lt;canvas height&gt;	Default is 500
	-b &lt;background color&gt;	Default is blue
	-f &lt;foreground color&gt;	Default is yellow
	-F &lt;fuel&gt;		Default is 20
	-x &lt;initail x position&gt;	Default is 0
	-y &lt;initail y position&gt;	Default is 800
	-g &lt;gravity&gt;		Default is 1.62 (the moon)
	-a &lt;engine thrust&gt;	Default is 20
	-X &lt;initail X velocity&gt; Default is 0
	-Y &lt;initail Y velocity&gt; Default is 0
	-c &lt;crash velocity&gt; 	Default is 10
	-s &lt;landing slope tolerance&gt; Default is 0
	-S do not resize scene (ship may leave screen)
	-h print this message

	How to play:

	pressing 'k' fires main thruster.
	pressing 'j' rotates lander counter-clockwise
	pressing 'l' rotates lander clockwise
	pressing 'r' restarts the game.

	Place 	g in m/sec2  
	-----	-----------
	Moon 	        1.62
	Mercury         3.58
	Venus 	        8.87
	Earth		9.8
	Mars 	        3.74
	Jupiter        26.01
	Saturn         11.17
	Uranus         10.49
	Neptune        13.25
	Pluto           0.73
USAGE
}

my @LandScape = (
	new Vector2D(  -800,   40 ), #pt  0
	new Vector2D(  -500,   50 ), #pt  1
	new Vector2D(  -400,   50 ), #pt  2
	new Vector2D(  -300,  100 ), #pt  3
	new Vector2D(  -100,    0 ), #pt  4
	new Vector2D(   100,    0 ), #pt  5
	new Vector2D(   150,   75 ), #pt  7
	new Vector2D(   300,   75 ), #pt  8
	new Vector2D(   400,  300 ), #pt  9
	new Vector2D(   450,  100 ), #pt 10
	new Vector2D(   800,    0 ), #pt 11
);

my @Lander = (
	new Vector2D(  0 + $initialX,   0 + $initialY), #pt 0
	new Vector2D( 10 + $initialX,   0 + $initialY), #pt 1
	new Vector2D(  5 + $initialX,   0 + $initialY), #pt 2
	new Vector2D( 10 + $initialX,  10 + $initialY), #pt 3
	new Vector2D( 20 + $initialX,  20 + $initialY), #pt 4
	new Vector2D( 40 + $initialX,  20 + $initialY), #pt 5
	new Vector2D( 50 + $initialX,  10 + $initialY), #pt 6
	new Vector2D( 55 + $initialX,   0 + $initialY), #pt 7
	new Vector2D( 50 + $initialX,   0 + $initialY), #pt 8
	new Vector2D( 60 + $initialX,   0 + $initialY), #pt 9
	new Vector2D( 55 + $initialX,  30 + $initialY), #pt 10
	new Vector2D( 55 + $initialX,  40 + $initialY), #pt 11
	new Vector2D( 40 + $initialX,  50 + $initialY), #pt 12
	new Vector2D( 20 + $initialX,  50 + $initialY), #pt 13
	new Vector2D(  5 + $initialX,  40 + $initialY), #pt 14
	new Vector2D(  5 + $initialX,  30 + $initialY), #pt 15
	new Vector2D( 30 + $initialX, -40 + $initialY), #thruster flame pt 16
	new Vector2D( 30 + $initialX,  25 + $initialY)  #center of gravity pt 17
);

my $top = MainWindow-&gt;new();
my $can = $top-&gt;Canvas( 
	-width =&gt; $width, 
	-height=&gt; $height,
	-background =&gt; $background  )-&gt;form();

my $x_max 	= $width;
my $y_max 	= $height;
my $x_min 	= 5;
my $y_min 	= 5;
my $x_center 	= $can-&gt;reqwidth()/2.0;
my $y_center 	= $can-&gt;reqheight()/2.0;

my $pi		= 4 * atan(1.0);
my $phi 	= $pi/15.0;

my $cosphi 	= cos ( $phi );
my $sinphi 	= sin ( $phi );
my $center 	= new Vector2D( $x_center, $y_center );
my $r_max 	= $can-&gt;reqwidth()/2;
my $start 	= $center-&gt;plus( new Vector2D( 0.9 * $r_max, 0 ) );
my $vp 	= new Viewport();
my $clipbox = new Clip2();

### set up Keys
sub rPressed { ### Restart game
	$can-&gt;delete( 'Lander' );	
	$can-&gt;delete( 'crash' );	
	&amp;initializeLander;
	$vp-&gt;resetwindow();
	foreach my $v ( @Lander ) { 
		$vp-&gt;updatewindowboundaries( $v-&gt;getx(), $v-&gt;gety() ); 
	}
	foreach my $v ( @LandScape ) { 
		$vp-&gt;updatewindowboundaries( $v-&gt;getx(), $v-&gt;gety() ); 
	}
	$vp-&gt;viewportboundaries ( $x_min, $x_max, $y_min, $y_max, 0.9 );
	&amp;play;
}

sub kPressed { ### Fire Thruster
	#Draw Thruster Flame
	if ( $fuel-- &gt; 0 ) {
		&amp;drawThrusterFlame;
		$LanderVelocity-&gt;incr( $acceleration );
	} else {
		print "Out of gas!!!!\n";
	}
	Ev('k');
}
sub lPressed { ### Rotate clockwise
	&amp;rotateLanderCounterClockwise;
	Ev('l');
}

sub jPressed { ### Rotate clockwise
	&amp;rotateLanderClockwise;
	Ev('j');
}

$top-&gt;bind( '&lt;Key-k&gt;',  \&amp;kPressed );
$top-&gt;bind( '&lt;Key-l&gt;',  \&amp;lPressed );
$top-&gt;bind( '&lt;Key-j&gt;',  \&amp;jPressed );
$top-&gt;bind( '&lt;Key-r&gt;',  \&amp;rPressed );
### set up window
foreach my $v ( @Lander ) {
	$vp-&gt;updatewindowboundaries( $v-&gt;getx(), $v-&gt;gety() );
}
foreach my $v ( @LandScape ) {
	$vp-&gt;updatewindowboundaries( $v-&gt;getx(), $v-&gt;gety() );
}
$vp-&gt;viewportboundaries ( $x_min, $x_max, $y_min, $y_max, 0.9 );

&amp;drawLander;
&amp;drawLandScape;
$can-&gt;after( 100, \&amp;play );
MainLoop;

sub rotateLanderClockwise {
	### $Lander[17] is Lander's center of gravity
	foreach my $v ( @Lander ) {
		$v = $v-&gt;rotate( $Lander[17], $cosphi, $sinphi );
	}
	$acceleration = $acceleration-&gt;rotate( 
		new Vector2D( 0.0, 0.0), $cosphi, $sinphi 
	);
}

sub rotateLanderCounterClockwise {
	### $Lander[17] is Lander's center of gravity
	foreach my $v ( @Lander ) {
		$v = $v-&gt;rotate( $Lander[17], $cosphi, -$sinphi );
	}
	$acceleration = $acceleration-&gt;rotate( 
		new Vector2D( 0.0,0.0), $cosphi, -$sinphi 
	);
}


sub moveLander {
	# The Physics: 
	# 	xt = x0 + v0t + ˝at2
	#       vt = v0 + at
	#       a  = -9.8 
	$can-&gt;delete( 'Lander' );
	$LanderVelocity-&gt;decr ( $gravity );
	foreach my $v ( @Lander ) {
		my $u = $LanderVelocity + $gravity *  0.5;
		$v-&gt;incr( $u );
		if ( $staticWindow == 0 ) {
			$vp-&gt;updatewindowboundaries( $v-&gt;getx(), $v-&gt;gety() );
		}
	}
	if ( $staticWindow == 0 ) {
		$vp-&gt;viewportboundaries ( $x_min, $x_max, $y_min, $y_max, 0.9 );
		&amp;drawLandScape;
	}
	&amp;drawLander;
}

sub play {
	&amp;moveLander;
	&amp;updateClipBox;
	my $rc = &amp;touchDown;
	if ( $rc == 0 ) {
		$can-&gt;after( 100, \&amp;play );
	} elsif ( $rc &lt; 0 ) {
		&amp;drawCrash;
		print "fuel = $fuel CRASH!!!!\n";
	} else {
		print "fuel = $fuel The eagle has landed!\n";	
	}
}

sub initializeLander {
	@Lander = (
		new Vector2D(  0 + $initialX,   0 + $initialY), #pt 0
		new Vector2D( 10 + $initialX,   0 + $initialY), #pt 1
		new Vector2D(  5 + $initialX,   0 + $initialY), #pt 2
		new Vector2D( 10 + $initialX,  10 + $initialY), #pt 3
		new Vector2D( 20 + $initialX,  20 + $initialY), #pt 4
		new Vector2D( 40 + $initialX,  20 + $initialY), #pt 5
		new Vector2D( 50 + $initialX,  10 + $initialY), #pt 6
		new Vector2D( 55 + $initialX,   0 + $initialY), #pt 7
		new Vector2D( 50 + $initialX,   0 + $initialY), #pt 8
		new Vector2D( 60 + $initialX,   0 + $initialY), #pt 9
		new Vector2D( 55 + $initialX,  30 + $initialY), #pt 10
		new Vector2D( 55 + $initialX,  40 + $initialY), #pt 11
		new Vector2D( 40 + $initialX,  50 + $initialY), #pt 12
		new Vector2D( 20 + $initialX,  50 + $initialY), #pt 13
		new Vector2D(  5 + $initialX,  40 + $initialY), #pt 14
		new Vector2D(  5 + $initialX,  30 + $initialY), #pt 15
		new Vector2D( 30 + $initialX, -40 + $initialY), #thruster flame pt 16
		new Vector2D( 30 + $initialX,  25 + $initialY)  #center of gravity pt 17
	);
	$LanderVelocity 	= new Vector2D(0, 0 );
	$fuel 		= 20;
	$acceleration 	= new Vector2D(0, 20.0);

	if( $opts{F} ) { $fuel 		= $opts{F} ; }
	if( $opts{X} ) { $LanderVelocity-&gt;setx ($opts{X}) ; }
	if( $opts{Y} ) { $LanderVelocity-&gt;sety ($opts{Y}) ; }
	if( $opts{a} ) { $acceleration  -&gt;sety ($opts{a}) ; }
}

sub drawCrash {
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($clipbox-&gt;getxmin()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymin()), 
		$vp-&gt;x_viewport($clipbox-&gt;getxmax()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymax()), 
		-fill =&gt; 'red',
		-tag  =&gt; 'crash',
		-width =&gt; 5
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($clipbox-&gt;getxmax()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymin()), 
		$vp-&gt;x_viewport($clipbox-&gt;getxmin()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymax()), 
		-fill =&gt; 'red',
		-tag  =&gt; 'crash',
		-width =&gt; 5
	);
}

sub drawClipBox {
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($clipbox-&gt;getxmin()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymin()), 
		$vp-&gt;x_viewport($clipbox-&gt;getxmin()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymax()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'clipbox'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($clipbox-&gt;getxmin()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymax()), 
		$vp-&gt;x_viewport($clipbox-&gt;getxmax()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymax()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'clipbox'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($clipbox-&gt;getxmax()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymax()), 
		$vp-&gt;x_viewport($clipbox-&gt;getxmax()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymin()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'clipbox'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($clipbox-&gt;getxmax()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymin()), 
		$vp-&gt;x_viewport($clipbox-&gt;getxmin()), 
		$vp-&gt;y_viewport($clipbox-&gt;getymin()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'clipbox'
	);
}

sub touchDown {
	my $clipped = 0;
	my $lineSlope = 0;
	my ( $x1, $y1, $x2, $y2 );
	for ( my $i=0; $i&lt;$#LandScape and $clipped == 0 ; $i++ ) {
		$x1 = $LandScape[$i]-&gt;getx();
		$y1 = $LandScape[$i]-&gt;gety();
		$x2 = $LandScape[$i+1]-&gt;getx();
		$y2 = $LandScape[$i+1]-&gt;gety();
		$clipped = $clipbox-&gt;cliped( $x1, $y1, $x2, $y2 ); 
		$lineSlope = ($y2 - $y1)/($x2 - $x1);
	}
	if ( $clipped == 1 ) {
		### calulate the speed at impact
		my $speed = sqrt( 
			$LanderVelocity-&gt;getx() * $LanderVelocity-&gt;getx() + 
			$LanderVelocity-&gt;gety() * $LanderVelocity-&gt;gety());
			print "landing speed is $speed\n" .
		              "Line slope $lineSlope\n";
		if ( $speed &gt;= $crashSpeed ) { 
			return -1;
		} else {
			if ( -$crashSlope &lt;= $lineSlope &amp;&amp; 
			       $lineSlope &lt;= $crashSlope ) {
				return  1;
			} else {
				return -1;
			}
		}
	} 
	return 0;
}

sub drawThrusterFlame {
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[4]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[4]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[16]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[16]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; ['Flame', 'Lander']
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[16]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[16]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[5]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[5]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; ['Flame', 'Lander']
	);
}


sub drawLandScape {
	$can-&gt;delete( 'LandScape' );
	my $start_x = $LandScape[0]-&gt;getx();
	my $start_y = $LandScape[0]-&gt;gety();
	for my $v ( @LandScape ) {
		$can-&gt;create ( 'line', 
			$vp-&gt;x_viewport($start_x), 
			$vp-&gt;y_viewport($start_y), 
			$vp-&gt;x_viewport($v-&gt;getx()), 
			$vp-&gt;y_viewport($v-&gt;gety()), 
			-fill =&gt; $fill,
			-tag  =&gt; 'LandScape'
		);
		$start_x = $v-&gt;getx();
		$start_y = $v-&gt;gety();
	};
}
	
sub drawLander {
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[0]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[0]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[1]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[1]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[2]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[2]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[3]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[3]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[3]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[3]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[4]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[4]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[4]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[4]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[5]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[5]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[5]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[5]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[6]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[6]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[6]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[6]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[7]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[7]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[8]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[8]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[9]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[9]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[5]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[5]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[10]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[10]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[10]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[10]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[11]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[11]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[11]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[11]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[12]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[12]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[12]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[12]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[13]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[13]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[13]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[13]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[14]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[14]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[14]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[14]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[15]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[15]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
	$can-&gt;create ( 'line', 
		$vp-&gt;x_viewport($Lander[15]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[15]-&gt;gety()), 
		$vp-&gt;x_viewport($Lander[4]-&gt;getx()), 
		$vp-&gt;y_viewport($Lander[4]-&gt;gety()), 
		-fill =&gt; $fill,
		-tag  =&gt; 'Lander'
	);
}

### get collision detection bounding box from lander
sub updateClipBox {
	my $smallest_x 	= $Lander[0]-&gt;getx();
	my $smallest_y 	= $Lander[0]-&gt;gety();
	my $largest_x 	= $Lander[0]-&gt;getx();
	my $largest_y 	= $Lander[0]-&gt;gety();
	my $i = 0;

	
	foreach my $v ( @Lander ) {
		# pts 16 and 17 are not really parts of the lander
		# pt 16 is the flame and 17 is center of gravity
		if ( $i &lt; 16 ) {
			if( $v-&gt;getx() &lt;= $smallest_x ) { $smallest_x = $v-&gt;getx(); }
			if( $v-&gt;gety() &lt;= $smallest_y ) { $smallest_y = $v-&gt;gety(); }
			if( $v-&gt;getx() &gt;= $largest_x ) { $largest_x = $v-&gt;getx(); }
			if( $v-&gt;gety() &gt;= $largest_y ) { $largest_y = $v-&gt;gety(); }
		}
		$i++;
	}
	$clipbox-&gt;setclipboundaries( $smallest_x, $smallest_y, $largest_x, $largest_y);
}
=head1 LunarLander

	A Lunar Lander Video game written in Perl/Tk.

=head1 DESCRIPTION

	A Lunar Lander Video game written in Perl/Tk.

=head1 README

	options:

	-W &lt;canvas width&gt;	Default is 500
	-H &lt;canvas height&gt;	Default is 500
	-b &lt;background color&gt;	Default is blue
	-f &lt;foreground color&gt;	Default is yellow
	-F &lt;fuel&gt;		Default is 20
	-x &lt;initail x position&gt;	Default is 0
	-y &lt;initail y position&gt;	Default is 800
	-g &lt;gravity&gt;		Default is 1.62 (the moon)
	-a &lt;engine thrust&gt;	Default is 20
	-X &lt;initail X velocity&gt; Default is 0
	-Y &lt;initail Y velocity&gt; Default is 0
	-c &lt;crash velocity&gt; 	Default is 10
	-s &lt;landing slope tolerance&gt; Default is 0
	-S do not resize scene (ship may leave screen)
	-h print this message

	How to play:

	pressing 'k' fires main thruster.
	pressing 'j' rotates lander counter-clockwise
	pressing 'l' rotates lander clockwise
	pressing 'r' restarts the game.

	Place 	g in m/sec2  
	-----	-----------
	Moon 	        1.62
	Mercury         3.58
	Venus 	        8.87
	Earth		9.8
	Mars 	        3.74
	Jupiter        26.01
	Saturn         11.17
	Uranus         10.49
	Neptune        13.25
	Pluto           0.73

=head1 PREREQUISITES

This script requires the C&lt;strict&gt; module.  
It also requires C&lt;Tk 800.022&gt;.
It also requires C&lt;Tk::Canvas 800.022&gt;.
It also requires C&lt;Math::Trig&gt;.
It also requires C&lt;Vector2D Authur CECALA&gt;
It also requires C&lt;Viewport Author CECALA&gt;
It also requires C&lt;Clip2    Author CECALA&gt;
It also requires C&lt;Getopt::Std&gt;

=head1 COREQUISITES

Tk

=pod OSNAMES

any

=pod SCRIPT CATEGORIES

Fun/Educational
Tk/Example

=cut
</pre></body></html>