home *** CD-ROM | disk | FTP | other *** search
/ Game.EXE 2002 June / Game.EXE_06_2002.iso / Alawar / src / Level.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-26  |  6.1 KB  |  259 lines

  1. #include "Level.h"
  2. #include "CellPass.h"
  3. #include "CellWall.h"
  4. #include "Dot.h"
  5. #include "PowerDot.h"
  6. #include "Monster.h"
  7. #include "Cherry.h"
  8. #include <math.h>
  9.  
  10. Level::Level(Scene2D * scene, int number)
  11. :    scene( scene ),
  12.     wall_size_anim( scene, 1, "data/pass" ),
  13.     error( true )
  14. {
  15.     char tmp[128];
  16.     sprintf( tmp,"level%d.txt", number );
  17.     if( load_level( tmp ) )
  18.         error = false;
  19.     creatures.push_back( new Monster( scene, this ) );
  20.     creatures.push_back( new Monster( scene, this ) );
  21. }
  22.  
  23. Level::~Level()
  24. {
  25.     Creatures::iterator crit = creatures.begin();
  26.     for( ; crit != creatures.end(); ++crit )
  27.     {
  28.         delete (*crit); (*crit) = 0;
  29.     }
  30.  
  31.     Array2D< Cell * >::iterator ait = cells.begin();
  32.     for( ; ait != cells.end(); ++ait )
  33.     {
  34.         delete (*ait); (*ait) = 0;
  35.     }
  36.  
  37. }
  38.  
  39. static void intersect( Creatures * a, Creatures * b )
  40. {
  41.     Creatures::iterator ait = a->begin();
  42.     for( ; ait != a->end(); ++ait )
  43.     if( (*ait)->is_solid() )
  44.     {
  45.         Creatures::iterator bit = b->begin();
  46.         for( ; bit != b->end(); ++bit )
  47.         if( (*bit)->is_solid() )
  48.         {
  49.             const float a_size = (*ait)->get_size();
  50.             const float b_size = (*bit)->get_size();
  51.             const Coord a_pos = Coord( (*ait)->get_position().get_x(), (*ait)->get_position().get_y() );
  52.             const Coord b_pos = Coord( (*bit)->get_position().get_x(), (*bit)->get_position().get_y() );
  53.             if (( fabs( a_pos.x - b_pos.x ) < ( a_size + b_size )/4 ) && ( fabs( a_pos.y - b_pos.y ) < ( a_size + b_size )/4 ))
  54.             {
  55.                 (*bit)->process_collision( *ait );
  56.                 (*ait)->process_collision( *bit );
  57.             }
  58.         }
  59.     }
  60. }
  61.  
  62. void Level::move( Creature * creature, const String & where )
  63. {
  64.     if ( where == "pacman_start" )
  65.     {
  66.         creature->pos.src = pacman_start;
  67.         creature->pos.dst = pacman_start;
  68.         creature->pos.koef = 0;
  69.         creature->pos.cell_size = get_cell_size();
  70.     }
  71.     if ( where == "monster_start" )
  72.     {
  73.         creature->pos.src = monster_start;
  74.         creature->pos.dst = monster_start;
  75.         creature->pos.koef = 0;
  76.         creature->pos.cell_size = get_cell_size();
  77.     }
  78. }
  79.  
  80. void Level::add_external_creature(Creature * cre)
  81. {
  82.     external_creatures.push_back( cre );
  83. }
  84.  
  85. void Level::life_cycle(float delta_time)
  86. {
  87.     creatures.life_cycle( delta_time );
  88.     external_creatures.life_cycle( delta_time );
  89.  
  90.     intersect( &creatures, &creatures );
  91.     intersect( &creatures, &external_creatures );
  92.     intersect( &external_creatures, &creatures );
  93.     intersect( &external_creatures, &external_creatures );
  94.  
  95.     Creatures::iterator it = creatures.begin();
  96.     while( it != creatures.end() )
  97.         if( !(*it)->is_alive() )
  98.         {
  99.             creatures.process_death( (*it ) );
  100.             external_creatures.process_death( (*it ) );
  101.             delete (*it);
  102.             it = creatures.erase( it );
  103.         }
  104.         else
  105.             ++it;
  106. }
  107.  
  108. bool Level::next_direction(Creature * p, Direction direction)
  109. {
  110.     const int cell_size = get_cell_size();
  111.  
  112.     int x = p->get_position().dst.x / cell_size;
  113.     int y = p->get_position().dst.y / cell_size;
  114.  
  115.     if ( direction == Direction::RIGHT )
  116.     {
  117.         if ( cells[x+1][y]->can_pass( p ) )
  118.         {
  119.             p->pos.src = p->pos.dst;
  120.             p->pos.dst.x = (x+1)*cell_size;
  121.             p->pos.dst.y = y*cell_size;
  122.             p->pos.koef = 0;
  123.             p->pos.cell_size = cell_size;
  124.             return true;
  125.         }
  126.     }
  127.     if ( direction == Direction::LEFT )
  128.     {
  129.         if ( cells[x-1][y]->can_pass( p ) )
  130.         {
  131.             p->pos.src = p->pos.dst;
  132.             p->pos.dst.x = (x-1)*cell_size;
  133.             p->pos.dst.y = y*cell_size;
  134.             p->pos.koef = 0;
  135.             p->pos.cell_size = cell_size;
  136.             return true;
  137.         }
  138.     }
  139.     if ( direction == Direction::UP )
  140.     {
  141.         if ( cells[x][y-1]->can_pass( p ) )
  142.         {
  143.             p->pos.src = p->pos.dst;
  144.             p->pos.dst.x = x*cell_size;
  145.             p->pos.dst.y = (y-1)*cell_size;
  146.             p->pos.koef = 0;
  147.             return true;
  148.         }
  149.     }
  150.     if ( direction == Direction::DOWN )
  151.     {
  152.         if ( cells[x][y+1]->can_pass( p ) )
  153.         {
  154.             p->pos.src = p->pos.dst;
  155.             p->pos.dst.x = x*cell_size;
  156.             p->pos.dst.y = (y+1)*cell_size;
  157.             p->pos.koef = 0;
  158.             return true;
  159.         }
  160.     }
  161.     return false;
  162. }
  163.  
  164. int Level::get_dot_count()const
  165. {
  166.     int count = 0;
  167.     Creatures::const_iterator it = creatures.begin();
  168.     for( ;it != creatures.end(); ++it )
  169.         if( (*it)->get_name() == "Dot" )
  170.             ++count;
  171.     return count;
  172. }
  173.  
  174. int Level::get_cell_size()const
  175. {
  176.     return wall_size_anim.get_width(0,0);
  177. }
  178.  
  179. bool Level::load_level( const char * level_name )
  180. {
  181.     const int cell_size = get_cell_size();
  182.  
  183.     FILE * file = fopen( level_name, "rt" );
  184.     if ( !file )
  185.         return false;
  186.  
  187.     int cx(0), cy(0);
  188.     fscanf( file, "%d %d", &cx, &cy );
  189.     cells = Array2D<Cell *>( cx, cy, 0 );
  190.  
  191.     Array2D<int> temp_field( cx, cy );
  192.  
  193.     int y;
  194.     for( y = 0; y < cy; ++y )
  195.         for( int x = 0; x < cx; ++x )
  196.         {
  197.             int val( '\n' );
  198.             while( val == '\n' )
  199.                 val = fgetc( file );
  200.             if ( val == -1 )
  201.                 return false;
  202.             temp_field[x][y] = val;
  203.         }
  204.  
  205.     for( y = 0; y < cy; ++y )
  206.         for( int x = 0; x < cx; ++x )
  207.         {
  208.             if ( temp_field[x][y] == 'W' )
  209.             {
  210.                 int mask(0);
  211.                 if ( x != cx-1 && temp_field[x+1][y] == 'W' )
  212.                     mask |= Direction::RIGHT;
  213.                 if ( x != 0 && temp_field[x-1][y] == 'W' )
  214.                     mask |= Direction::LEFT;
  215.                 if ( y != cy-1 && temp_field[x][y+1] == 'W' )
  216.                     mask |= Direction::DOWN;
  217.                 if ( y != 0 && temp_field[x][y-1] == 'W' )
  218.                     mask |= Direction::UP;
  219.  
  220.                 cells[x][y] = new CellWall( scene, x, y, mask );
  221.             }
  222.  
  223.             if ( temp_field[x][y] == 'S' )
  224.             {
  225.                 cells[x][y] = new CellPass( scene, x, y );
  226.                 pacman_start = Coord( x*cell_size, y*cell_size );
  227.             }
  228.             if ( temp_field[x][y] == 'M' )
  229.             {
  230.                 cells[x][y] = new CellPass( scene, x, y );
  231.                 monster_start = Coord( x*cell_size, y*cell_size );
  232.             }
  233.             if ( temp_field[x][y] == ' ' )
  234.                 cells[x][y] = new CellPass( scene, x, y );
  235.  
  236.             if ( temp_field[x][y] == '.' )
  237.             {
  238.                 cells[x][y] = new CellPass( scene, x, y );
  239.                 Dot * dot = new Dot( this, scene, x, y );
  240.                 creatures.push_back( dot );
  241.             }
  242.             if ( temp_field[x][y] == '*' )
  243.             {
  244.                 cells[x][y] = new CellPass( scene, x, y );
  245.                 PowerDot * dot = new PowerDot( this, scene, x, y );
  246.                 creatures.push_back( dot );
  247.             }
  248.             if ( temp_field[x][y] == 'C' )
  249.             {
  250.                 cells[x][y] = new CellPass( scene, x, y );
  251.                 Cherry * cherry = new Cherry( this, scene, x, y );
  252.                 creatures.push_back( cherry );
  253.             }
  254.         }
  255.  
  256.     fclose( file );
  257.  
  258.     return true;
  259. }