NAME

Games::Lineofsight

DESCRIPTION

Many games (Ultima, Nethack) use two-dimensional maps that consists of the squares of the same size in a grid. Line-of-sight means that some of the squares may represent the items that block the vision of the player from seeing squares behind them. With this module you can add that behaviour to your games.

SYNOPSIS

   use Games::Lineofsight qw(lineofsight);

   # The map has to be a two-dimensional array. Each member (or "cell") of the array represents one
   # square in the map. In this example each cell contains only one character but you can put strings
   # to the cells also - practical with the graphical games.

   my @map=(
      [split //,"..:..::........."], # this is the map
      [split //,".......:..X....:"], # . and : represents the ground
      [split //,"...X.....:...:.."], # X is the barrier for the sight
      [split //,".:...:....:....."],
      [split //,"..X....:..X....."],
      [split //,"..X..:........:."],
   );

   my($width)=scalar(@{@map[0]}); # the width of the map
   my($height)=scalar(@map);      # the height of the map
   my($barrier_str)="X";          # string that represents the barrier
   my($hidden_str)="*";           # string that represents a cell behind a barrier
   my($man_str)="@";           # string that represents the viewer 
   my($man_x,$man_y)=(7,3);       # view point coordinates - the player is here

   # recreate the map with line-of-sight

   @map=lineofsight(\@map,$man_x,$man_y,$barrier_str,$hidden_str);

   # draw the map

   for(my $i=0;$i < $height;$i++){
      for(my $j=0;$j < $width;$j++){
         print $man_x == $j && $man_y == $i ? $man_str : $map[$i][$j];
      }
      print "\n";
   }

or

   # The lineofsight() calls get_barriers() and analyze_map() each time it's called. If the viewer
   # moves around the map a lot, it's much faster to read in the barriers once and call only 
   # analyze_map() each time before drawing it.

   use Games::Lineofsight qw(get_barriers analyze_map);

   # The map has to be a two-dimensional array. Each member (or "cell") of the array represents one
   # square in the map. In this example each cell contains only one character but you can put strings
   # to the cells also - practical with the graphical games.

   my @map=(
      [split //,"..:..::........."], # this is the map
      [split //,".......:..X....:"], # . and : represents the ground
      [split //,"...X.....:...:.."], # X is the barrier for the sight
      [split //,".:...:....:....."],
      [split //,"..X....:..X....."],
      [split //,"..X..:........:."],
   );

   my($width)=scalar(@{@map[0]}); # the width of the map
   my($height)=scalar(@map);      # the height of the map
   my($barrier_str)="X";          # string that represents the barrier
   my($hidden_str)="*";           # string that represents a cell behind a barrier
   my($man_str)="@";           # string that represents the viewer
   my($man_x,$man_y)=(7,3);       # view point coordinates - the player is here

   # get_barriers() returns a hash with the information about barriers in the map. In this example we 
   # declare the "X"-character as a barrier. As well you can declare it to be a string in the graphical
   # games; for example "barrier.jpg".

   my %barrier=get_barriers($width,$height,\@map,$barrier_str);

   # analyze_map() returns an array containing the original map looked from the view point. The cells
   # behind the barriers are replaced with given strings. The barriers should be told to the subroutine
   # calling first get_barriers()-subroutine as we already did.

   my @map2=analyze_map($width,$height,\@map,\%barrier,$man_x,$man_y,$hidden_str);

   #draw the map with the lineofsight

   print "\nOriginal map:\n"; 

   draw($width,$height,$man_x,$man_y,\@map2,$man_str);

   # move the viewer two squares right
   
   $man_x+=2;
   
   # refresh the map
   
   my @map2=analyze_map($width,$height,\@map,\%barrier,$man_x,$man_y,$hidden_str);

   #draw the map again

   print "\nViewer has moved:\n"; 

   draw($width,$height,$man_x,$man_y,\@map2,$man_str);
   
   sub draw{
      my($width,$height,$man_x,$man_y,$map,$man_str)=@_;
      for(my $i=0;$i < $height;$i++){
         for(my $j=0;$j < $width;$j++){
            print $man_x == $j && $man_y == $i ? $man_str : $$map[$i][$j];
         }
         print "\n";
      }

   }

KNOWN BUGS

None.

AUTHOR

Ville Jungman

<ville_jungman@hotmail.com, ville.jungman@frakkipalvelunam.fi>

COPYRIGHT

Copyright 2004 Ville Jungman

LICENSE

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