commited Ed <icelus2k5@gmail.com>'s coin and block patch
authorIngo Ruhnke <grumbel@gmx.de>
Mon, 18 Feb 2008 11:54:23 +0000 (11:54 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Mon, 18 Feb 2008 11:54:23 +0000 (11:54 +0000)
- coins fade out
- coins rotate as they fade out
- coins last a little bit longer (but not much)
- coins emerge from behind blocks instead of being drawn over them
- blocks tilt depending on where they're hit

SVN-Revision: 5326

src/object/block.cpp
src/object/block.hpp
src/object/gameobjs.cpp
src/object/gameobjs.hpp
src/object/infoblock.cpp
src/object/invisible_block.cpp

index bb309f0..2a0e2af 100644 (file)
@@ -49,6 +49,7 @@
 static const float BOUNCY_BRICK_MAX_OFFSET = 8;
 static const float BOUNCY_BRICK_SPEED = 90;
 static const float EPSILON = .0001f;
+static const float BUMP_ROTATION_ANGLE = 10;
 
 Block::Block(Sprite* newsprite)
   : sprite(newsprite), bouncing(false), breaking(false), bounce_dir(0), bounce_offset(0)
@@ -115,6 +116,7 @@ Block::update(float elapsed_time)
     movement = Vector(0, offset);
     bounce_dir = 0;
     bouncing = false;
+    sprite->set_angle(0);
   } else {
     movement = Vector(0, bounce_dir * elapsed_time);
   }
@@ -127,18 +129,21 @@ Block::draw(DrawingContext& context)
 }
 
 void
-Block::start_bounce()
+Block::start_bounce(float center_of_hitter)
 {
   original_y = bbox.p1.y;
   bouncing = true;
   bounce_dir = -BOUNCY_BRICK_SPEED;
   bounce_offset = 0;
+
+  float offset = (get_bbox().get_middle().x - center_of_hitter)*2 / get_bbox().get_width();
+  sprite->set_angle(BUMP_ROTATION_ANGLE*offset);
 }
 
 void
-Block::start_break()
+Block::start_break(float center_of_hitter)
 {
-  start_bounce();
+  start_bounce(center_of_hitter);
   breaking = true;
 }
 
@@ -260,7 +265,7 @@ BonusBlock::try_open()
 
   switch(contents) {
     case CONTENT_COIN:
-      Sector::current()->add_object(new BouncyCoin(get_pos()));
+      Sector::current()->add_object(new BouncyCoin(get_pos(), true));
       player.get_status()->add_coins(1);
       Sector::current()->get_level()->stats.coins++;
       break;
@@ -305,7 +310,7 @@ BonusBlock::try_open()
       break;
   }
 
-  start_bounce();
+  start_bounce(player.get_bbox().get_middle().x);
   sprite->set_action("empty");
 }
 
@@ -388,19 +393,19 @@ Brick::try_break(Player* player)
   Sector* sector = Sector::current();
   Player& player_one = *(sector->player);
   if(coin_counter > 0) {
-    sector->add_object(new BouncyCoin(get_pos()));
+    sector->add_object(new BouncyCoin(get_pos(),true));
     coin_counter--;
     player_one.get_status()->add_coins(1);
     if(coin_counter == 0)
       sprite->set_action("empty");
-    start_bounce();
+    start_bounce(player->get_bbox().get_middle().x);
   } else if(breakable) {
     if(player){
       if(player->is_big()){
-        start_break();
+        start_break(player->get_bbox().get_middle().x);
         return;
       } else {
-        start_bounce();
+        start_bounce(player->get_bbox().get_middle().x);
         return;
       }
     }
index e620d48..f6069e4 100644 (file)
@@ -40,8 +40,8 @@ protected:
   friend class FlipLevelTransformer;
 
   virtual void hit(Player& player) = 0;
-  void start_bounce();
-  void start_break();
+  void start_bounce(float center_of_hitter);
+  void start_break(float center_of_hitter);
   void break_me();
 
   Sprite* sprite;
index 1eed690..4af687d 100644 (file)
 #include "main.hpp"
 #include "random_generator.hpp"
 
-BouncyCoin::BouncyCoin(const Vector& pos)
-  : position(pos)
+/** this controls the time over which a bouncy coin fades */
+static const float FADE_TIME = .2f;
+/** this is the total life time of a bouncy coin */
+static const float LIFE_TIME = .5f;
+
+BouncyCoin::BouncyCoin(const Vector& pos, bool emerge)
+  : position(pos), emerge_distance(0)
 {
-  timer.start(.3f);
+  timer.start(LIFE_TIME);
   sprite = sprite_manager->create("images/objects/coin/coin.sprite");
-  sprite->set_action("still");
+
+  if(emerge) {
+    emerge_distance = sprite->get_height();
+  }
 }
 
 BouncyCoin::~BouncyCoin()
@@ -53,7 +61,9 @@ BouncyCoin::~BouncyCoin()
 void
 BouncyCoin::update(float elapsed_time)
 {
-  position.y += -200 * elapsed_time;
+  float dist = -200 * elapsed_time;
+  position.y += dist;
+  emerge_distance += dist;
 
   if(timer.check())
     remove_me();
@@ -62,7 +72,25 @@ BouncyCoin::update(float elapsed_time)
 void
 BouncyCoin::draw(DrawingContext& context)
 {
-  sprite->draw(context, position, LAYER_OBJECTS + 5);
+  float time_left = timer.get_timeleft();
+  bool fading = time_left < FADE_TIME;
+  if(fading) {
+    float alpha = time_left/FADE_TIME;
+    context.push_transform();
+    context.set_alpha(alpha);
+  }
+
+  int layer;
+  if(emerge_distance > 0) {
+    layer = LAYER_OBJECTS - 5;
+  } else {
+    layer = LAYER_OBJECTS + 5;
+  }
+  sprite->draw(context, position, layer);
+
+  if(fading) {
+    context.pop_transform();
+  }
 }
 
 //---------------------------------------------------------------------------
index 5a4063f..b3d50d7 100644 (file)
@@ -36,7 +36,7 @@ class Sprite;
 class BouncyCoin : public GameObject
 {
 public:
-  BouncyCoin(const Vector& pos);
+  BouncyCoin(const Vector& pos, bool emerge=false);
   ~BouncyCoin();
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
@@ -45,6 +45,7 @@ private:
   Sprite* sprite;
   Vector position;
   Timer timer;
+  float emerge_distance;
 };
 
 class BrokenBrick : public GameObject
index dda84e6..919ef9b 100644 (file)
@@ -66,9 +66,9 @@ InfoBlock::~InfoBlock()
 }
 
 void
-InfoBlock::hit(Player& )
+InfoBlock::hit(Player& player)
 {
-  start_bounce();
+  start_bounce(player.get_bbox().get_middle().x);
 
   //if (!stopped) {
   //  ringing->remove_me();
index 2e802fc..4dbe5a3 100644 (file)
@@ -67,7 +67,7 @@ InvisibleBlock::collision(GameObject& other, const CollisionHit& hit)
 }
 
 void
-InvisibleBlock::hit(Player& )
+InvisibleBlock::hit(Player& player)
 {
   sound_manager->play("sounds/brick.wav");
 
@@ -75,7 +75,7 @@ InvisibleBlock::hit(Player& )
     return;
 
   sprite->set_action("empty");
-  start_bounce();
+  start_bounce(player.get_bbox().get_middle().x);
   set_group(COLGROUP_STATIC);
   visible = true;
 }