From: Christoph Sommer Date: Sat, 19 Jan 2008 19:52:30 +0000 (+0000) Subject: Butt Jump. As Big Tux, gain lots of speed and press down, then smash bricks, Ice... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=72325436a6b4c5eef61f4a14ef287a9520717baa;p=supertux.git Butt Jump. As Big Tux, gain lots of speed and press down, then smash bricks, Ice Blocks and Snails SVN-Revision: 5282 --- diff --git a/data/images/creatures/tux/big/buttjump-0.png b/data/images/creatures/tux/big/buttjump-0.png new file mode 100644 index 000000000..6354fa983 Binary files /dev/null and b/data/images/creatures/tux/big/buttjump-0.png differ diff --git a/data/images/creatures/tux/tux.sprite b/data/images/creatures/tux/tux.sprite index 0dffcb7e6..fb9c38363 100644 --- a/data/images/creatures/tux/tux.sprite +++ b/data/images/creatures/tux/tux.sprite @@ -211,5 +211,14 @@ (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")) ) diff --git a/src/badguy/mriceblock.cpp b/src/badguy/mriceblock.cpp index f5d927eac..481bf088f 100644 --- a/src/badguy/mriceblock.cpp +++ b/src/badguy/mriceblock.cpp @@ -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(&object); + squishcount++; + if ((squishcount >= MAXSQUISHES) || (player && player->butt_jump)) { + kill_fall(); + return true; + } } set_state(ICESTATE_FLAT); diff --git a/src/badguy/snail.cpp b/src/badguy/snail.cpp index a2695334d..d68aad7f9 100644 --- a/src/badguy/snail.cpp +++ b/src/badguy/snail.cpp @@ -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(&object); + squishcount++; + if ((squishcount >= MAXSQUISHES) || (player && player->butt_jump)) { + kill_fall(); + return true; + } } sound_manager->play("sounds/stomp.wav", get_pos()); diff --git a/src/object/block.cpp b/src/object/block.cpp index fd6e2fc21..4cf7920e3 100644 --- a/src/object/block.cpp +++ b/src/object/block.cpp @@ -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 (&other); + if (player) { + if (player->butt_jump) try_break(); + } + BadGuy* badguy = dynamic_cast (&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 (&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 { diff --git a/src/object/block.hpp b/src/object/block.hpp index 94f87fb04..e620d481f 100644 --- a/src/object/block.hpp +++ b/src/object/block.hpp @@ -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: diff --git a/src/object/player.cpp b/src/object/player.cpp index dc5abd91b..72e4debd5 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -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);