Butt Jump. As Big Tux, gain lots of speed and press down, then smash bricks, Ice...
authorChristoph Sommer <mail@christoph-sommer.de>
Sat, 19 Jan 2008 19:52:30 +0000 (19:52 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Sat, 19 Jan 2008 19:52:30 +0000 (19:52 +0000)
SVN-Revision: 5282

data/images/creatures/tux/big/buttjump-0.png [new file with mode: 0644]
data/images/creatures/tux/tux.sprite
src/badguy/mriceblock.cpp
src/badguy/snail.cpp
src/object/block.cpp
src/object/block.hpp
src/object/player.cpp

diff --git a/data/images/creatures/tux/big/buttjump-0.png b/data/images/creatures/tux/big/buttjump-0.png
new file mode 100644 (file)
index 0000000..6354fa9
Binary files /dev/null and b/data/images/creatures/tux/big/buttjump-0.png differ
index 0dffcb7..fb9c383 100644 (file)
          (fps 9.0)
          (mirror-action "big-backflip-right"))
 
+       (action
+         (name "big-buttjump-right")
+         (hitbox 16 5 32 64)
+         (images "big/buttjump-0.png"))
+
+       (action
+         (name "big-buttjump-left")
+         (hitbox 16 5 32 64)
+         (mirror-action "big-buttjump-right"))
 
 )
index f5d927e..481bf08 100644 (file)
@@ -186,10 +186,13 @@ MrIceBlock::collision_squished(GameObject& object)
   switch(ice_state) {
     case ICESTATE_KICKED:
     case ICESTATE_NORMAL:
-      squishcount++;
-      if(squishcount >= MAXSQUISHES) {
-        kill_fall();
-        return true;
+      {
+       Player* player = dynamic_cast<Player*>(&object);
+        squishcount++;
+        if ((squishcount >= MAXSQUISHES) || (player && player->butt_jump)) {
+          kill_fall();
+          return true;
+        }
       }
 
       set_state(ICESTATE_FLAT);
index a269533..d68aad7 100644 (file)
@@ -212,10 +212,13 @@ Snail::collision_squished(GameObject& object)
 
     case STATE_KICKED:
     case STATE_NORMAL:
-      squishcount++;
-      if(squishcount >= MAXSQUISHES) {
-        kill_fall();
-        return true;
+      {
+       Player* player = dynamic_cast<Player*>(&object);
+        squishcount++;
+        if ((squishcount >= MAXSQUISHES) || (player && player->butt_jump)) {
+          kill_fall();
+          return true;
+        }
       }
 
       sound_manager->play("sounds/stomp.wav", get_pos());
index fd6e2fc..4cf7920 100644 (file)
@@ -343,23 +343,29 @@ Brick::Brick(const Vector& pos, int data)
 }
 
 void
-Brick::hit(Player& )
+Brick::hit(Player& player)
 {
   if(sprite->get_action() == "empty")
     return;
 
-  try_break(true);
+  try_break(&player);
 }
 
 HitResponse
 Brick::collision(GameObject& other, const CollisionHit& hit){
+
+    Player* player = dynamic_cast<Player*> (&other);
+    if (player) {
+      if (player->butt_jump) try_break();
+    }
+
     BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
     if(badguy) {
       // hit contains no information for collisions with blocks.
       // Badguy's bottom has to be below the top of the brick
       // +7 is required to slide over one tile gaps.
       if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + 7.0 ) ){
-        try_break(false);
+        try_break();
       }
     }
     Portable* portable = dynamic_cast<Portable*> (&other);
@@ -373,24 +379,24 @@ Brick::collision(GameObject& other, const CollisionHit& hit){
 }
 
 void
-Brick::try_break(bool playerhit)
+Brick::try_break(Player* player)
 {
   if(sprite->get_action() == "empty")
     return;
 
   sound_manager->play("sounds/brick.wav");
   Sector* sector = Sector::current();
-  Player& player = *(sector->player);
+  Player& player_one = *(sector->player);
   if(coin_counter > 0) {
     sector->add_object(new BouncyCoin(get_pos()));
     coin_counter--;
-    player.get_status()->add_coins(1);
+    player_one.get_status()->add_coins(1);
     if(coin_counter == 0)
       sprite->set_action("empty");
     start_bounce();
   } else if(breakable) {
-    if(playerhit){
-      if(player.is_big()){
+    if(player){
+      if(player->is_big()){
         start_break();
         return;
       } else {
index 94f87fb..e620d48 100644 (file)
@@ -85,7 +85,7 @@ class Brick : public Block
 public:
   Brick(const Vector& pos, int data);
 
-  void try_break(bool playerhit = false);
+  void try_break(Player* player = false);
   HitResponse collision(GameObject& other, const CollisionHit& hit);
 
 protected:
index dc5abd9..72e4deb 100644 (file)
@@ -54,6 +54,7 @@
 //#define SWIMMING
 
 static const int TILES_FOR_BUTTJUMP = 3;
+static const float BUTTJUMP_MIN_VELOCITY_Y = 700.0f;
 static const float SHOOTING_TIME = .150f;
 /// time before idle animation starts
 static const float IDLE_TIME = 2.5f;
@@ -501,6 +502,8 @@ Player::do_duck() {
     return;
   if (!on_ground())
     return;
+  if (butt_jump)
+    return;
 
   if (adjust_height(31.8f)) {
     duck = true;
@@ -591,7 +594,7 @@ Player::handle_vertical_input()
 
   /* In case the player has pressed Down while in a certain range of air,
      enable butt jump action */
-  if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && jumping) {
+  if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && !on_ground() && (physic.get_velocity_y() >= BUTTJUMP_MIN_VELOCITY_Y)) {
     butt_jump = true;
   }
 
@@ -835,6 +838,10 @@ Player::set_bonus(BonusType type, bool animate)
     if (climbing) stop_climbing(*climbing);
   }
 
+  if (type == NO_BONUS) {
+    if (butt_jump) butt_jump = false;
+  }
+
   if ((type == NO_BONUS) || (type == GROWUP_BONUS)) {
     if ((player_status->bonus == FIRE_BONUS) && (animate)) {
       // visually lose helmet
@@ -1005,6 +1012,24 @@ Player::collision_solid(const CollisionHit& hit)
 
     on_ground_flag = true;
     floor_normal = hit.slope_normal;
+
+    // Butt Jump landed    
+    if (butt_jump) {
+      butt_jump = false;
+      physic.set_velocity_y(-300);
+      on_ground_flag = false;
+      Sector::current()->add_object(new Particles(
+          Vector(get_bbox().p2.x, get_bbox().p2.y),
+          270+20, 270+40,
+          Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
+          LAYER_OBJECTS+1));
+      Sector::current()->add_object(new Particles(
+          Vector(get_bbox().p1.x, get_bbox().p2.y),
+          90-40, 90-20,
+          Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
+          LAYER_OBJECTS+1));
+    }
+
   } else if(hit.top) {
     if(physic.get_velocity_y() < 0)
       physic.set_velocity_y(.2f);