home *** CD-ROM | disk | FTP | other *** search
/ Game.EXE 2002 June / Game.EXE_06_2002.iso / Alawar / src / Game.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-06  |  10.4 KB  |  492 lines

  1. #include "Game.h"
  2. #include "Level.h"
  3. #include "Pacman.h"
  4. #include <Log/LogPtr.h>
  5. #include <Converter.h>
  6. #include <InputForGameExe/InputManagerPtr.h>
  7.  
  8. class Game::State
  9. {
  10. protected:
  11.     Game * const game;
  12.     const state_enum state;
  13. public:
  14.     State( Game * game, state_enum state )
  15.         :    game( game ),
  16.             state( state )
  17.     {}
  18.     state_enum get_state()const
  19.     {
  20.         return state;
  21.     }
  22.     virtual ~State()
  23.     {}
  24.     virtual state_enum get_new_state()const=0;
  25.  
  26.     virtual void life_cycle(float delta_time)
  27.     {}
  28. };
  29.  
  30. class Game::IntroState : public Game::State
  31. {
  32.     Animation2D anim;
  33.     bool quit;
  34. public:
  35.     IntroState( Game * game )
  36.         :    State( game, INTRO ),
  37.             anim( game->get_scene(), 0, "data/intro" ),
  38.             quit( false )
  39.     {}
  40.     virtual state_enum get_new_state()const
  41.     {
  42.         return quit ? MAIN_MENU : state;
  43.     }
  44.     virtual void life_cycle(float delta_time)
  45.     {
  46.         if( !InputManagerPtr()->key_queue_empty() )
  47.         {
  48.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  49.             if( ev.is_pressed() )
  50.                 quit = true;
  51.         }
  52.     }
  53. };
  54.  
  55. class Game::MainMenuState : public Game::State
  56. {
  57.     int curr;
  58.     const int n_curr;
  59.     bool quit;
  60.     std::vector<Animation2D *> butt;
  61.     Animation2D header;
  62.     Animation2D footer;
  63. public:
  64.     MainMenuState( Game * game )
  65.         :    State( game, MAIN_MENU ),
  66.             header( game->get_scene(), 0, "data/header" ),
  67.             footer( game->get_scene(), 0, "data/footer" ),
  68.             curr( game->curr_main_menu_item ),
  69.             n_curr( 4 ),
  70.             quit( false )
  71.     {
  72.         if( curr < 0 || curr >= n_curr )
  73.         {
  74.             LogPtr()->warning( "curr_main_menu_item became invalid between lifetimes of Game::MainMenuState");
  75.             curr = 0;
  76.         }
  77.         static const char * names[] = { "data/newgame", "data/help", "data/hiscore", "data/exit" };
  78.         header.move( 35, 20 );
  79.         for( int i = 0; i < n_curr; ++i )
  80.         {
  81.             butt.push_back( new Animation2D( game->get_scene(), 0, names[ i ] ) );
  82.             butt.back()->move( 35, 20 + (i + 1)*39 );
  83.             butt.back()->start( 0, true );
  84.         }
  85.         footer.move( 35, 20 + (i + 1)*39 );
  86.  
  87.         header.start( 0, true );
  88.         footer.start( 0, true );
  89.         butt[curr]->start( 1, true );
  90.     }
  91.     virtual ~MainMenuState()
  92.     {
  93.         while( !butt.empty() )
  94.         {
  95.             delete butt.back(); butt.pop_back();
  96.         }
  97.         game->curr_main_menu_item = curr;
  98.     }
  99.     virtual state_enum get_new_state()const
  100.     {
  101.         if( !quit )
  102.             return state;
  103.         switch( curr )
  104.         {
  105.         case 0:
  106.             return LEVEL;
  107.         case 1:
  108.             return HELP;
  109.         case 2:
  110.             return HISCORE;
  111.         case 3:
  112.             return NAG;
  113.         }
  114.         return NAG; // exit, when error
  115.     }
  116.     virtual void life_cycle(float delta_time)
  117.     {
  118.         if( !InputManagerPtr()->key_queue_empty() )
  119.         {
  120.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  121.             if( !quit && ev.is_pressed() )
  122.             {
  123.                 butt[curr]->start( 0, true );
  124.                 if( ev.get_key_name() == "Up" )
  125.                 {
  126.                     curr = (curr + n_curr - 1) % n_curr;
  127.                 }
  128.                 else
  129.                 if( ev.get_key_name() == "Down" )
  130.                 {
  131.                     curr = (curr + 1) % n_curr;
  132.                 }
  133.                 else
  134.                 if( ev.get_key_name() == "Enter" )
  135.                 {
  136.                     quit = true;
  137.                 }
  138.                 butt[curr]->start( 1, true );
  139.             }
  140.         }
  141.     }
  142. };
  143.  
  144. class Game::HiscoreState : public Game::State
  145. {
  146.     bool quit;
  147.     Animation2D header;
  148.     std::vector<FontObject2D *> font_score;
  149.     std::vector<FontObject2D *> font_name;
  150. public:
  151.     HiscoreState( Game * game )
  152.         :    State( game, HISCORE ),
  153.             header( game->get_scene(), 0, "data/hiscore_pic" ),
  154.             quit( false )
  155.     {
  156.         header.move( 35, 20 );
  157.         header.start( 0, true );
  158.         for( int i = 0; i < 6; ++i )
  159.         {
  160.             font_score.push_back( new FontObject2D( game->get_scene(), 0, "data/small_alphabet" ) );
  161.             font_name.push_back( new FontObject2D( game->get_scene(), 0, "data/small_alphabet" ) );
  162.             font_score.back()->move( 190, 80 + 20*i );
  163.             font_name.back()->move( 20, 80 + 20*i );
  164.  
  165.             int score = game->hiscore.get_entry( i ).get_score();
  166.             String name = game->hiscore.get_entry( i ).get_player_name();
  167.  
  168.             if( !name.empty() && score != 0 )
  169.             {
  170.                 font_score.back()->change_text( Converter::convert( score ) );
  171.                 font_name.back()->change_text( name );
  172.             }
  173.         }
  174.     }
  175.     virtual ~HiscoreState()
  176.     {
  177.         while( !font_score.empty() )
  178.         {
  179.             delete font_score.back(); font_score.pop_back();
  180.         }
  181.         while( !font_name.empty() )
  182.         {
  183.             delete font_name.back(); font_name.pop_back();
  184.         }
  185.     }
  186.     virtual state_enum get_new_state()const
  187.     {
  188.         return quit ? MAIN_MENU : state;
  189.     }
  190.     virtual void life_cycle(float delta_time)
  191.     {
  192.         if( !InputManagerPtr()->key_queue_empty() )
  193.         {
  194.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  195.             if( ev.is_pressed() )
  196.                 quit = true;
  197.         }
  198.     }
  199. };
  200.  
  201. class Game::EnterNameState : public Game::State
  202. {
  203.     bool quit;
  204.     Animation2D header;
  205.     String name;
  206.     FontObject2D font_name;
  207. public:
  208.     EnterNameState( Game * game )
  209.         :    State( game, ENTER_NAME ),
  210.             header( game->get_scene(), 0, "data/enter_name" ),
  211.             font_name( game->get_scene(), 0, "data/small_alphabet" ),
  212.             quit( false )
  213.     {
  214.         header.move( 35, 20 );
  215.         header.start( 0, true );
  216.         font_name.move( 20, 80 );
  217.  
  218.         if( game->score <= game->hiscore.get_worst_score() )
  219.             quit = true;
  220.     }
  221.     virtual state_enum get_new_state()const
  222.     {
  223.         return quit ? HISCORE : state;
  224.     }
  225.     virtual void life_cycle(float delta_time)
  226.     {
  227.         if( !InputManagerPtr()->key_queue_empty() )
  228.         {
  229.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  230.             if( ev.is_pressed() && ev.get_key_name() == "Enter" && !name.empty() )
  231.             {
  232.                 game->hiscore.add_entry( Hiscore::Entry( name, game->score ) );
  233.                 quit = true;
  234.             }
  235.             else
  236.             if( ev.is_text() )
  237.             {
  238.                 name += ev.get_key_name();
  239.             }
  240.         }
  241.         name = font_name.change_text( name );
  242.     }
  243. };
  244.  
  245. class Game::HelpState : public Game::State
  246. {
  247.     bool quit;
  248.     Animation2D anim;
  249. public:
  250.     HelpState( Game * game )
  251.         :    State( game, HELP ),
  252.             anim( game->get_scene(), 0, "data/help_pic" ),
  253.             quit( false )
  254.     {
  255.         anim.move( 0, 0 );
  256.         anim.start( 0, true );
  257.     }
  258.     virtual state_enum get_new_state()const
  259.     {
  260.         return quit ? MAIN_MENU : state;
  261.     }
  262.     virtual void life_cycle(float delta_time)
  263.     {
  264.         if( !InputManagerPtr()->key_queue_empty() )
  265.         {
  266.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  267.             if( ev.is_pressed() )
  268.                 quit = true;
  269.         }
  270.     }
  271. };
  272.  
  273. class Game::LevelState : public Game::State
  274. {
  275.     FontObject2D lives_text;
  276.     FontObject2D score_text;
  277.     /**
  278.      * @supplierCardinality 1 
  279.      */
  280.     Level * level;
  281.     /**
  282.      * @supplierCardinality 1 
  283.      */
  284.     Pacman * pacman;
  285.     bool quit;
  286.     int level_num;
  287.     bool load_level()
  288.     {
  289.         pacman->put_on_level( 0 );
  290.         delete level; level = 0;
  291.         level = new Level( game->get_scene(), level_num );
  292.         if( !*level )
  293.         {
  294.             quit = true;
  295.             return false;
  296.         }
  297.         pacman->put_on_level( level );
  298.         level->add_external_creature( pacman );
  299.         return true;
  300.     }
  301. public:
  302.     LevelState( Game * game )
  303.         :    State( game, LEVEL ),
  304.             score_text( game->get_scene(), 3, "data/small_alphabet" ),
  305.             lives_text( game->get_scene(), 3, "data/small_alphabet" ),
  306.             pacman( new Pacman( game->get_scene() ) ),
  307.             level_num( 0 ),
  308.             quit( false ),
  309.             level( 0 )
  310.     {
  311.         score_text.move( 10, 220 );
  312.         score_text.change_text( "0" );
  313.  
  314.         lives_text.move( 180, 220 );
  315.         lives_text.change_text( "0" );
  316.  
  317.         load_level();
  318.     }
  319.     virtual ~LevelState()
  320.     {
  321.         delete level; level = 0;
  322.         delete pacman; pacman = 0;
  323.     }
  324.     virtual state_enum get_new_state()const
  325.     {
  326.         if( quit )
  327.             return ENTER_NAME;
  328.         if( !pacman )
  329.             return ENTER_NAME;
  330.         if( pacman->get_life() < 1 )
  331.             return ENTER_NAME;
  332.         return state;
  333.     }
  334.     virtual void life_cycle(float delta_time)
  335.     {
  336.         if( quit )
  337.             return;
  338.         if( !InputManagerPtr()->key_queue_empty() )
  339.         {
  340.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  341.             if( ev.is_pressed() )
  342.             {
  343.                 if( ev.get_key_name() == "Up" )
  344.                 {
  345.                     if ( pacman )
  346.                         pacman->key_down( Direction::UP );
  347.                 }
  348.                 else
  349.                 if( ev.get_key_name() == "Down" )
  350.                 {
  351.                     if ( pacman )
  352.                         pacman->key_down( Direction::DOWN );
  353.                 }
  354.                 else
  355.                 if( ev.get_key_name() == "Left" )
  356.                 {
  357.                     if ( pacman )
  358.                         pacman->key_down( Direction::LEFT );
  359.                 }
  360.                 else
  361.                 if( ev.get_key_name() == "Right" )
  362.                 {
  363.                     if ( pacman )
  364.                         pacman->key_down( Direction::RIGHT );
  365.                 }
  366.                 else
  367.                 if( ev.get_key_name() == "Esc" )
  368.                 {
  369.                     quit = true;
  370.                 }
  371.             }
  372.         }
  373.         if( level )
  374.         {
  375.             level->life_cycle( delta_time );
  376.             if( level->get_dot_count() <= 0 )
  377.             {
  378.                 ++level_num;
  379.                 load_level();
  380.             }
  381.         }
  382.         if( pacman )
  383.         {
  384.             game->score = pacman->get_score();
  385.             score_text.change_text( String("Score: ") + Converter::convert( int(pacman->get_score()) ) );
  386.             lives_text.change_text( String("Lives: ") + Converter::convert( int(pacman->get_life()) ) );
  387.         }
  388.     }
  389. };
  390.  
  391. class Game::NagState : public Game::State
  392. {
  393.     bool quit;
  394.     Animation2D anim;
  395. public:
  396.     NagState( Game * game )
  397.         :    State( game, NAG ),
  398.             anim( game->get_scene(), 0, "data/nag" ),
  399.             quit( false )
  400.     {
  401.         anim.move( 0, 0 );
  402.         anim.start( 0, true );
  403.     }
  404.     virtual state_enum get_new_state()const
  405.     {
  406.         return quit ? FINISHED: state;
  407.     }
  408.     virtual void life_cycle(float delta_time)
  409.     {
  410.         if( !InputManagerPtr()->key_queue_empty() )
  411.         {
  412.             InputKeyEvent ev = InputManagerPtr()->get_key_event();
  413.             if( ev.is_pressed() )
  414.                 quit = true;
  415.         }
  416.     }
  417. };
  418.  
  419. class Game::FinishedState : public Game::State
  420. {
  421. public:
  422.     FinishedState( Game * game )
  423.         :    State( game, FINISHED )
  424.     {}
  425.     virtual state_enum get_new_state()const
  426.     {
  427.         return state;
  428.     }
  429. };
  430.  
  431. Game::Game(Scene2D * scene)
  432. :    scene( scene ),
  433.     state( 0 ),
  434.     hiscore( 6 ),
  435.     curr_main_menu_item( 0 )
  436. {
  437.     state = new IntroState( this );
  438. }
  439.  
  440. Game::~Game()
  441. {
  442.     delete state; state = 0;
  443. }
  444.  
  445. bool Game::is_alive()const
  446. {
  447.     return state->get_state() != FINISHED;
  448. }
  449.  
  450. void Game::life_cycle(float delta_time)
  451. {
  452.     state->life_cycle( delta_time );
  453.  
  454.     state_enum new_state = state->get_new_state();
  455.     if( new_state != state->get_state()  )
  456.     {
  457.         delete state; state = 0;
  458.         switch( new_state )
  459.         {
  460.         case INTRO:
  461.             state  = new IntroState( this );
  462.             break;
  463.         case MAIN_MENU:
  464.             state = new MainMenuState( this );
  465.             break;
  466.         case ENTER_NAME:
  467.             state = new EnterNameState( this );
  468.             break;
  469.         case HISCORE:
  470.             state = new HiscoreState( this );
  471.             break;
  472.         case HELP:
  473.             state = new HelpState( this );
  474.             break;
  475.         case LEVEL:
  476.             state = new LevelState( this );
  477.             break;
  478.         case NAG:
  479.             state = new NagState( this );
  480.             break;
  481.         case FINISHED:
  482.             state = new FinishedState( this );
  483.             break;
  484.         default:
  485.             // ┼±δΦ ≈≥ε-≥ε φσ ≥ε, Γ√⌡εΣΦ∞
  486.             LogPtr()->error( "Unpossible state switch" );
  487.             state = new FinishedState( this );
  488.             break;
  489.         }
  490.     }
  491. }
  492.