- changed/clean up level end detection a bit, still not really as it should be
authorIngo Ruhnke <grumbel@gmx.de>
Sat, 17 Apr 2004 13:56:48 +0000 (13:56 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Sat, 17 Apr 2004 13:56:48 +0000 (13:56 +0000)
SVN-Revision: 543

src/gameloop.cpp
src/gameloop.h
src/player.cpp
src/scene.h
src/title.cpp
src/world.cpp
src/world.h
src/worldmap.cpp
src/worldmap.h

index cb91373..f8b96eb 100644 (file)
 
 GameSession* GameSession::current_ = 0;
 
-void
-GameSession::init()
-{
-  game_pause = false;
-}
-
-GameSession::GameSession()
+GameSession::GameSession(const std::string& subset_, int levelnb_, int mode)
+  : world(0), st_gl_mode(mode), levelnb(levelnb_), subset(subset_)
 {
   current_ = this;
-  assert(0);
+  restart_level();
 }
 
-GameSession::GameSession(const std::string& filename)
-{
-  init();
-
-  //assert(!"Don't call me");
-  current_ = this;
-
-  world = new World;
-
-  fps_timer.init(true);
-  frame_timer.init(true);
-
-  world->load(filename);
-}
-
-GameSession::GameSession(const std::string& subset_, int levelnb_, int mode)
-  : subset(subset_),
-    levelnb(levelnb_)
+void
+GameSession::restart_level()
 {
-  init();
-
-  current_ = this;
-
-  world = new World;
+  game_pause = false;
+  exit_status = NONE;
 
   fps_timer.init(true);
   frame_timer.init(true);
 
-  st_gl_mode = mode;
-  
-  /* Init the game: */
-  world->arrays_free();
-  world->set_defaults();
-
   if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
     {
-      if (world->load(subset))
-        exit(1);
+      world = new World(subset);
+    }
+  else if (st_gl_mode == ST_GL_DEMO_GAME)
+    {
+      world = new World(subset);
     }
   else
     {
-      if(world->load(subset, levelnb) != 0)
-        exit(1);
+      world = new World(subset, levelnb);
     }
+    
+  if (st_gl_mode != ST_GL_DEMO_GAME)
+    {
+      if(st_gl_mode != ST_GL_TEST)
+        load_hs();
 
-  world->get_level()->load_gfx();
-  
-  world->activate_bad_guys();
-  world->activate_particle_systems();
-  world->get_level()->load_song();
-
-  if(st_gl_mode != ST_GL_TEST)
-    load_hs();
-
-  if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
-    levelintro();
+      if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
+        levelintro();
+    }
 
   time_left.init(true);
-  start_timers();
+  start_timers(); 
 }
 
 GameSession::~GameSession()
@@ -131,14 +100,11 @@ GameSession::levelintro(void)
   /* Level Intro: */
   clearscreen(0, 0, 0);
 
-  sprintf(str, "LEVEL %d", levelnb);
-  blue_text->drawf(str, 0, 200, A_HMIDDLE, A_TOP, 1);
-
   sprintf(str, "%s", world->get_level()->name.c_str());
-  gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1);
+  gold_text->drawf(str, 0, 200, A_HMIDDLE, A_TOP, 1);
 
   sprintf(str, "TUX x %d", player_status.lives);
-  white_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1);
+  white_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1);
   
   sprintf(str, "by %s", world->get_level()->author.c_str());
   white_small_text->drawf(str, 0, 400, A_HMIDDLE, A_TOP, 1);
@@ -174,8 +140,9 @@ GameSession::process_events()
       switch(event.type)
         {
         case SDL_QUIT:        /* Quit event - quit: */
-          quit = true;
+          st_abort("Received window close", "");
           break;
+
         case SDL_KEYDOWN:     /* A keypress! */
           {
             SDLKey key = event.key.keysym.sym;
@@ -189,7 +156,9 @@ GameSession::process_events()
                 if(!game_pause)
                   {
                     if(st_gl_mode == ST_GL_TEST)
-                      quit = true;
+                      {
+                        exit_status = LEVEL_ABORT;
+                      }
                     else if(show_menu)
                       {
                         Menu::set_current(game_menu);
@@ -249,10 +218,6 @@ GameSession::process_events()
                 if(debug_mode)
                   player_status.distros += 50;
                 break;
-              case SDLK_SPACE:
-                if(debug_mode)
-                  player_status.next_level = 1;
-                break;
               case SDLK_DELETE:
                 if(debug_mode)
                   tux.got_coffee = 1;
@@ -335,100 +300,58 @@ GameSession::process_events()
     } /* while */
 }
 
-int
-GameSession::action(double frame_ratio)
+
+void
+GameSession::check_end_conditions()
 {
-  Player& tux = *world->get_tux();
+  Player* tux = world->get_tux();
 
-  if (tux.is_dead() || player_status.next_level)
+  /* End of level? */
+  if (tux->base.x >= World::current()->get_level()->endpos
+      && World::current()->get_level()->endpos != 0)
     {
-      /* Tux either died, or reached the end of a level! */
-      halt_music();
-      
-      if (player_status.next_level)
-        {
-          /* End of a level! */
-          levelnb++;
-          player_status.next_level = 0;
-          if(st_gl_mode != ST_GL_TEST)
-            {
-              drawresultscreen();
-            }
-          else
-            {
-              world->get_level()->free_gfx();
-              world->get_level()->cleanup();
-              world->get_level()->free_song();
-              world->arrays_free();
-
-              return(0);
-            }
-          tux.level_begin();
-        }
-      else
+      exit_status = LEVEL_FINISHED;
+    }
+  else
+    {
+      // Check End conditions
+      if (tux->is_dead())
         {
-          tux.is_dying();
-
-          /* No more lives!? */
-
+          
           if (player_status.lives < 0)
-            {
+            { // No more lives!?
               if(st_gl_mode != ST_GL_TEST)
                 drawendscreen();
-
+          
               if(st_gl_mode != ST_GL_TEST)
                 {
                   if (player_status.score > hs_score)
                     save_hs(player_status.score);
                 }
-
-              world->get_level()->free_gfx();
-              world->get_level()->cleanup();
-              world->get_level()->free_song();
-              world->arrays_free();
-
-              return(0);
-            } /* if (lives < 0) */
+              
+              exit_status = GAME_OVER;
+            }
+          else
+            { // Still has lives, so reset Tux to the levelstart
+              restart_level();
+            }
         }
+    } 
+}
 
-      /* Either way, (re-)load the (next) level... */
-      tux.level_begin();
-      world->set_defaults();
+void
+GameSession::action(double frame_ratio)
+{
+  check_end_conditions();
+  
+  if (exit_status == NONE)
+    {
+      Player* tux = world->get_tux();
       
-      world->get_level()->cleanup();
-
-      if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
-        {
-          if(world->get_level()->load(subset) != 0)
-            return 0;
-        }
-      else
-        {
-          if(world->get_level()->load(subset, levelnb) != 0)
-            return 0;
-        }
-
-      world->arrays_free();
-      world->activate_bad_guys();
-      world->activate_particle_systems();
-
-      world->get_level()->free_gfx();
-      world->get_level()->load_gfx();
-      world->get_level()->free_song();
-      world->get_level()->load_song();
-
-      if(st_gl_mode != ST_GL_TEST)
-        levelintro();
-      start_timers();
-      /* Play music: */
-      play_current_music();
+      // Update Tux and the World
+      tux->action(frame_ratio);
+      world->action(frame_ratio);
     }
-
-  tux.action(frame_ratio);
-
-  world->action(frame_ratio);
-
-  return -1;
 }
 
 void 
@@ -458,14 +381,13 @@ GameSession::draw()
 }
 
 
-int
+GameSession::ExitStatus
 GameSession::run()
 {
-  Player& tux = *world->get_tux();
+  Player* tux = world->get_tux();
   current_ = this;
   
   int  fps_cnt;
-  bool done;
 
   global_frame_counter = 0;
   game_pause = false;
@@ -489,9 +411,7 @@ GameSession::run()
 
   draw();
 
-  done = false;
-  quit = false;
-  while (!done && !quit)
+  while (exit_status == NONE)
     {
       /* Calculate the movement-factor */
       double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
@@ -505,7 +425,7 @@ GameSession::run()
         }
 
       /* Handle events: */
-      tux.input.old_fire = tux.input.fire;
+      tux->input.old_fire = tux->input.fire;
 
       process_events();
 
@@ -527,7 +447,7 @@ GameSession::run()
                   break;
                 case 7:
                   st_pause_ticks_stop();
-                  done = true;
+                  exit_status = LEVEL_ABORT;
                   break;
                 }
             }
@@ -540,24 +460,13 @@ GameSession::run()
               process_load_game_menu();
             }
         }
-
-
-      /* Handle actions: */
-
+      
+      // Handle actions:
       if(!game_pause && !show_menu)
         {
-          /*float z = frame_ratio;
-            frame_ratio = 1;
-            while(z >= 1)
-            {*/
-          if (action(frame_ratio) == 0)
-            {
-              /* == 0: no more lives */
-              /* == -1: continues */
-              return 0;
-            }
-          /*  --z;
-                     }*/
+          action(frame_ratio);
+          if (exit_status != NONE)
+            return exit_status;
         }
       else
         {
@@ -603,15 +512,14 @@ GameSession::run()
         {
           /* are we low on time ? */
           if (time_left.get_left() < TIME_WARNING
-              && (get_current_music() != HURRYUP_MUSIC))     /* play the fast music */
+              && (get_current_music() != HURRYUP_MUSIC)) /* play the fast music */
             {
               set_current_music(HURRYUP_MUSIC);
               play_current_music();
             }
-
         }
-      else if(tux.dying == DYING_NOT)
-        tux.kill(KILL);
+      else if(tux->dying == DYING_NOT)
+        tux->kill(KILL);
 
       /* Calculate frames per second */
       if(show_fps)
@@ -633,9 +541,7 @@ GameSession::run()
   world->get_level()->cleanup();
   world->get_level()->free_song();
 
-  world->arrays_free();
-
-  return quit;
+  return exit_status;
 }
 
 /* Bounce a brick: */
index 59cf3a4..d03a403 100644 (file)
@@ -24,6 +24,7 @@
 #define ST_GL_TEST 1
 #define ST_GL_LOAD_GAME 2
 #define ST_GL_LOAD_LEVEL_FILE  3
+#define ST_GL_DEMO_GAME  4
 
 extern int game_started;
 
@@ -35,12 +36,11 @@ class World;
 class GameSession
 {
  private:
-  bool quit;
   Timer fps_timer;
   Timer frame_timer;
   World* world;
   int st_gl_mode;
-
+  int levelnb;
   float fps_fps;
   unsigned int last_update_time;
   unsigned int update_time;
@@ -50,21 +50,20 @@ class GameSession
 
   // FIXME: Hack for restarting the level
   std::string subset;
-  int levelnb;
 
+  enum ExitStatus { NONE, LEVEL_FINISHED, GAME_OVER, LEVEL_ABORT };
+  ExitStatus exit_status;
  public:
   Timer time_left;
 
-  GameSession();
-  GameSession(const std::string& filename);
   GameSession(const std::string& subset, int levelnb, int mode);
   ~GameSession();
 
   /** Enter the busy loop */
-  int  run();
+  ExitStatus run();
 
   void draw();
-  int  action(double frame_ratio);
+  void action(double frame_ratio);
 
   Level* get_level() { return world->get_level(); }
   World* get_world() { return world; }
@@ -73,8 +72,9 @@ class GameSession
  private:
   static GameSession* current_;
 
-  void init();
+  void restart_level();
 
+  void check_end_conditions();
   void start_timers();
   void process_events();
 
index 0a5de95..b9a61cd 100644 (file)
@@ -281,13 +281,6 @@ Player::action(double frame_ratio)
       play_current_music();
     }
 
-  /* End of level? */
-  if (base.x >= World::current()->get_level()->endpos
-      && World::current()->get_level()->endpos != 0)
-    {
-      player_status.next_level = 1;
-    }
-
   // check some timers
   skidding_timer.check();
   invincible_timer.check();
@@ -822,9 +815,6 @@ Player::kill(int mode)
 void
 Player::is_dying()
 {
-  /* He died :^( */
-
-  --player_status.lives;
   remove_powerups();
   dying = DYING_NOT;
 }
index 76c5c89..cc4b917 100644 (file)
@@ -25,7 +25,6 @@ struct PlayerStatus
   int  distros;
   int  lives;
 
-  int  next_level;
   int  score_multiplier;
 
   PlayerStatus();
index a7cc2f2..d1e93d7 100644 (file)
@@ -230,7 +230,7 @@ bool title(void)
 
   st_pause_ticks_init();
 
-  GameSession session(datadir + "/levels/misc/menu.stl");
+  GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
 
   //FIXME:activate_particle_systems();
 
index f246c36..1017253 100644 (file)
@@ -33,7 +33,7 @@ Surface* img_distro[4];
 
 World* World::current_ = 0;
 
-World::World()
+World::World(const std::string& filename)
 {
   // FIXME: Move this to action and draw and everywhere else where the
   // world calls child functions
@@ -41,6 +41,32 @@ World::World()
 
   level = new Level;
   tux.init();
+
+  level->load(filename);
+  set_defaults();
+
+  get_level()->load_gfx();
+  activate_bad_guys();
+  activate_particle_systems();
+  get_level()->load_song();
+}
+
+World::World(const std::string& subset, int level_nr)
+{
+  // FIXME: Move this to action and draw and everywhere else where the
+  // world calls child functions
+  current_ = this;
+
+  level = new Level;
+  tux.init();
+
+  level->load(subset, level_nr);
+  set_defaults();
+
+  get_level()->load_gfx();
+  activate_bad_guys();
+  activate_particle_systems();
+  get_level()->load_song();
 }
 
 World::~World()
@@ -63,35 +89,6 @@ World::set_defaults()
   set_current_music(LEVEL_MUSIC);
 }
 
-int
-World::load(const std::string& subset, int level_nr)
-{
-  return level->load(subset, level_nr);
-}
-
-int
-World::load(const std::string& filename)
-{
-  return level->load(filename);
-}
-
-void
-World::arrays_free(void)
-{
-  bad_guys.clear();
-  bouncy_distros.clear();
-  broken_bricks.clear();
-  bouncy_bricks.clear();
-  floating_scores.clear();
-  upgrades.clear();
-  bullets.clear();
-  std::vector<ParticleSystem*>::iterator i;
-  for(i = particle_systems.begin(); i != particle_systems.end(); ++i) {
-    delete *i;
-  }
-  particle_systems.clear();
-}
-
 void
 World::activate_bad_guys()
 {
index a0d0b19..db383e2 100644 (file)
@@ -58,6 +58,8 @@ class World
   static World* current() { return current_; }
   static void set_current(World* w) { current_ = w; }
 
+  World(const std::string& filename);
+  World(const std::string& subset, int level_nr);
   World();
   ~World();
   
@@ -74,16 +76,6 @@ class World
       case (or not). */
   void collision_handler();
   
-  void arrays_free();
-
-  /** Load data for this level: 
-      Returns -1, if the loading of the level failed. */
-  int  load(const std::string& subset, int level);
-
-  /** Load data for this level: 
-      Returns -1, if the loading of the level failed. */
-  int  load(const std::string& filename);
-
   void activate_particle_systems();
   void activate_bad_guys();
 
index 4f9934f..8c7e3fa 100644 (file)
@@ -206,7 +206,6 @@ WorldMap::WorldMap()
 {
   tux = new Tux(this);
 
-  quit = false;
   width  = 20;
   height = 15;
 
@@ -309,7 +308,7 @@ WorldMap::get_input()
           switch(event.type)
             {
             case SDL_QUIT:
-              quit = true;
+              st_abort("Received window close", "");
               break;
           
             case SDL_KEYDOWN:
index b23923e..75abd83 100644 (file)
@@ -114,12 +114,12 @@ class WorldMap
 private:
   Tux* tux;
 
+  bool quit;
+
   Surface* level_sprite;
   Surface* leveldot_green;
   Surface* leveldot_red;
 
-  bool quit;
-
   std::string name;
   std::string music;