New flying platform object.
[supertux.git] / src / world.cpp
index eb15b79..91acb66 100644 (file)
@@ -59,13 +59,13 @@ World::World(const std::string& filename)
   get_level()->load_gfx();
   // add background
   activate_particle_systems();
-  Background* bg = new Background(displaymanager);
+  background = new Background(displaymanager);
   if(level->img_bkgd) {
-    bg->set_image(level->img_bkgd, level->bkgd_speed);
+    background->set_image(level->img_bkgd, level->bkgd_speed);
   } else {
-    bg->set_gradient(level->bkgd_top, level->bkgd_bottom);
+    background->set_gradient(level->bkgd_top, level->bkgd_bottom);
   }
-  gameobjects.push_back(bg);
+  gameobjects.push_back(background);
 
   // add tilemap
   gameobjects.push_back(new TileMap(displaymanager, get_level()));
@@ -92,13 +92,13 @@ World::World(const std::string& subset, int level_nr)
 
   get_level()->load_gfx();
   activate_particle_systems();
-  Background* bg = new Background(displaymanager);
+  background = new Background(displaymanager);
   if(level->img_bkgd) {
-    bg->set_image(level->img_bkgd, level->bkgd_speed);
+    background->set_image(level->img_bkgd, level->bkgd_speed);
   } else {
-    bg->set_gradient(level->bkgd_top, level->bkgd_bottom);
+    background->set_gradient(level->bkgd_top, level->bkgd_bottom);
   }
-  gameobjects.push_back(bg);
+  gameobjects.push_back(background);
   // add tilemap
   gameobjects.push_back(new TileMap(displaymanager, get_level()));  
   get_level()->load_song();
@@ -140,9 +140,6 @@ World::~World()
 void
 World::set_defaults()
 {
-  // Set defaults: 
-  scroll_x = 0;
-
   player_status.score_multiplier = 1;
 
   counting_distros = false;
@@ -168,6 +165,9 @@ World::add_object(GameObject* object)
   Trampoline* trampoline = dynamic_cast<Trampoline*> (object);
   if(trampoline)
     trampolines.push_back(trampoline);
+  FlyingPlatform* flying_platform = dynamic_cast<FlyingPlatform*> (object);
+  if(flying_platform)
+    flying_platforms.push_back(flying_platform);
 
   gameobjects.push_back(object);
 }
@@ -183,7 +183,11 @@ World::parse_objects(lisp_object_t* cur)
 
     if(object_type == "trampoline") {
       add_object(new Trampoline(displaymanager, reader));
-    } else {
+    }
+    else if(object_type == "flying-platform") {
+      add_object(new FlyingPlatform(displaymanager, reader));
+    }
+    else {
       BadGuyKind kind = badguykind_from_string(object_type);
       add_object(new BadGuy(displaymanager, kind, reader));
     }
@@ -213,21 +217,21 @@ void
 World::draw()
 {
   /* Draw objects */
-  displaymanager.get_viewport().set_translation(Vector(scroll_x, scroll_y));
   displaymanager.draw();
 }
 
 void
-World::action(double frame_ratio)
+World::action(float elapsed_time)
 {
-  tux->check_bounds(level->back_scrolling, (bool)level->hor_autoscroll_speed);
-  scrolling(frame_ratio);
-
   /* update objects (don't use iterators here, because the list might change
    * during the iteration)
    */
   for(size_t i = 0; i < gameobjects.size(); ++i)
-    gameobjects[i]->action(frame_ratio);
+    gameobjects[i]->action(elapsed_time);
+
+  tux->check_bounds(displaymanager.get_viewport(),
+      level->back_scrolling, (bool)level->hor_autoscroll_speed);
+  scrolling(elapsed_time);                                                      
 
   /* Handle all possible collisions. */
   collision_handler();
@@ -262,6 +266,12 @@ World::action(double frame_ratio)
             std::remove(trampolines.begin(), trampolines.end(), trampoline),
             trampolines.end());
       }
+      FlyingPlatform* flying_platform= dynamic_cast<FlyingPlatform*> (*i);
+      if(flying_platform) {
+        flying_platforms.erase(
+            std::remove(flying_platforms.begin(), flying_platforms.end(), flying_platform),
+            flying_platforms.end());
+      }
       
       delete *i;
       i = gameobjects.erase(i);
@@ -282,8 +292,11 @@ World::action(double frame_ratio)
 #define CHANGE_DIR_SCROLL_SPEED 2000
 
 /* This functions takes cares of the scrolling */
-void World::scrolling(double frame_ratio)
+void World::scrolling(float elapsed_time)
 {
+  float scroll_x = displaymanager.get_viewport().get_translation().x;
+  float scroll_y = displaymanager.get_viewport().get_translation().y;
+  
   /* Y-axis scrolling */
 
   float tux_pos_y = tux->base.y + (tux->base.height/2);
@@ -307,7 +320,8 @@ void World::scrolling(double frame_ratio)
   /* Auto scrolling */
   if(level->hor_autoscroll_speed)
   {
-    scroll_x += level->hor_autoscroll_speed * frame_ratio;
+    scroll_x += level->hor_autoscroll_speed * elapsed_time;
+    displaymanager.get_viewport().set_translation(Vector(scroll_x, scroll_y));
     return;
   }
 
@@ -354,12 +368,13 @@ void World::scrolling(double frame_ratio)
       constant2 = 0.;
     }
     
-    float number = 2.5/(frame_ratio * CHANGE_DIR_SCROLL_SPEED/1000)*exp((CHANGE_DIR_SCROLL_SPEED-scrolling_timer.get_left())/1400.);
+    float number = 2.5/(elapsed_time * CHANGE_DIR_SCROLL_SPEED/1000)*exp((CHANGE_DIR_SCROLL_SPEED-scrolling_timer.get_left())/1400.);
     if(left) number *= -1.;
 
     scroll_x += number
-           + constant1 * tux->physic.get_velocity_x() * frame_ratio
-           + constant2 * tux->physic.get_acceleration_x() * frame_ratio * frame_ratio;
+           + constant1 * tux->physic.get_velocity_x() * elapsed_time
+           + constant2 * tux->physic.get_acceleration_x() * elapsed_time *
+            elapsed_time;
 
     if ((right && final_scroll_x - scroll_x < 0) || (left && final_scroll_x - scroll_x > 0))
       scroll_x = final_scroll_x;
@@ -378,6 +393,8 @@ void World::scrolling(double frame_ratio)
     scroll_x = level->width * 32 - screen->w;
   if(scroll_x < 0)
     scroll_x = 0;
+
+  displaymanager.get_viewport().set_translation(Vector(scroll_x, scroll_y));
 }
 
 void
@@ -481,6 +498,24 @@ World::collision_handler()
       }
     }
   }
+
+  // CO_FLYING_PLATFORM & (CO_PLAYER or CO_BADGUY)
+  for (FlyingPlatforms::iterator i = flying_platforms.begin(); i != flying_platforms.end(); ++i)
+  {
+    if (rectcollision((*i)->base, tux->base))
+    {
+      if (tux->previous_base.y < tux->base.y &&
+          tux->previous_base.y + tux->previous_base.height 
+          < (*i)->base.y + (*i)->base.height/2)
+      {
+        (*i)->collision(tux, CO_PLAYER, COLLISION_SQUISH);
+        tux->collision(*i, CO_FLYING_PLATFORM);
+      }
+/*      else if (tux->previous_base.y <= tux->base.y)
+      {
+      }*/
+    }
+  }
 }
 
 void
@@ -534,18 +569,18 @@ World::add_upgrade(const Vector& pos, Direction dir, UpgradeKind kind)
   add_object(new Upgrade(displaymanager, pos, dir, kind));
 }
 
-void 
+bool
 World::add_bullet(const Vector& pos, float xm, Direction dir)
 {
   if(tux->got_power == Player::FIRE_POWER)
     {
     if(bullets.size() > MAX_FIRE_BULLETS-1)
-      return;
+      return false;
     }
   else if(tux->got_power == Player::ICE_POWER)
     {
     if(bullets.size() > MAX_ICE_BULLETS-1)
-      return;
+      return false;
     }
 
   Bullet* new_bullet = 0;
@@ -558,6 +593,8 @@ World::add_bullet(const Vector& pos, float xm, Direction dir)
   add_object(new_bullet);
   
   play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
+
+  return true;
 }
 
 void