From b8afc3d299b00df6cb520f033bb19f1a577088fa Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Sun, 18 Jun 2006 14:36:11 +0000 Subject: [PATCH] Game no longer needs to pause while Tux grows / When Tux ducks and gets stuck under a ledge, he'll get hurt to shrink and be set free again (test at levels/test/glitches.stl) SVN-Revision: 3673 --- src/game_session.cpp | 8 +++--- src/moving_object.hpp | 12 +++++++++ src/object/player.cpp | 67 ++++++++++++++++++++++++++++++--------------------- src/object/player.hpp | 12 ++++++--- src/sector.hpp | 3 ++- 5 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/game_session.cpp b/src/game_session.cpp index b089677bc..daac30fc6 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -474,11 +474,9 @@ GameSession::update(float elapsed_time) if (end_sequence == ENDSEQUENCE_RUNNING) { currentsector->update(elapsed_time/2); } else if(end_sequence == NO_ENDSEQUENCE) { - if(!currentsector->player->growing_timer.started()) { - play_time += elapsed_time; //TODO: make sure we don't count cutscene time - level->stats.time = play_time; - currentsector->update(elapsed_time); - } + play_time += elapsed_time; //TODO: make sure we don't count cutscene time + level->stats.time = play_time; + currentsector->update(elapsed_time); } } diff --git a/src/moving_object.hpp b/src/moving_object.hpp index 63950ccd5..cba449c17 100644 --- a/src/moving_object.hpp +++ b/src/moving_object.hpp @@ -112,9 +112,21 @@ public: */ virtual void set_pos(const Vector& pos) { + dest.move(pos-get_pos()); bbox.set_pos(pos); } + /** + * sets the moving object's bbox to a specific size. Be careful when + * using this function. There are no collision detection checks performed + * here so bad things could happen. + */ + virtual void set_size(float w, float h) + { + dest.set_size(w, h); + bbox.set_size(w, h); + } + CollisionGroup get_group() const { return group; diff --git a/src/object/player.cpp b/src/object/player.cpp index 5fb722e58..39394e9f8 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -64,6 +64,8 @@ static const float WALK_SPEED = 100; static const float KICK_TIME = .3; +static const float UNDUCK_HURT_TIME = 0.25; /**< if Tux cannot unduck for this long, he will get hurt */ + // growing animation Surface* growingtux_left[GROWING_FRAMES]; Surface* growingtux_right[GROWING_FRAMES]; @@ -131,7 +133,6 @@ Player::init() bbox.set_size(31.8, 62.8); else bbox.set_size(31.8, 30.8); - adjust_height = 0; dir = RIGHT; old_dir = dir; @@ -176,6 +177,20 @@ Player::set_controller(Controller* controller) this->controller = controller; } +bool +Player::adjust_height(float new_height) +{ + Rect bbox2 = bbox; + bbox2.move(Vector(0, bbox.get_height() - new_height)); + bbox2.set_height(new_height); + if (!Sector::current()->is_free_space(bbox2)) return false; + // adjust bbox accordingly + // note that we use members of moving_object for this, so we can run this during CD, too + set_pos(bbox2.p1); + set_size(bbox2.get_width(), bbox2.get_height()); + return true; +} + void Player::update(float elapsed_time) { @@ -184,12 +199,6 @@ Player::update(float elapsed_time) return; } - if(adjust_height != 0) { - bbox.move(Vector(0, bbox.get_height() - adjust_height)); - bbox.set_height(adjust_height); - adjust_height = 0; - } - if(!dying && !deactivated) handle_input(); @@ -518,23 +527,26 @@ Player::handle_input() /* Duck! */ if (controller->hold(Controller::DOWN) && is_big() && !duck && physic.get_velocity_y() == 0 && on_ground()) { - duck = true; - bbox.move(Vector(0, 32)); - bbox.set_height(31.8); - } else if(!controller->hold(Controller::DOWN) && is_big() && duck) { - // if we have some velocity left then check if there is space for - // unducking - bbox.move(Vector(0, -32)); - bbox.set_height(63.8); - if(Sector::current()->is_free_space(bbox) || ( - physic.get_velocity_x() > -.01 && physic.get_velocity_x() < .01 - && physic.get_velocity_y() > -.01 && physic.get_velocity_y() < .01)) - { + if (adjust_height(31.8)) { + duck = true; + unduck_hurt_timer.stop(); + } else { + // FIXME: what now? + } + } + /* Unduck! */ + else if(!controller->hold(Controller::DOWN) && is_big() && duck) { + if (adjust_height(63.8)) { duck = false; + unduck_hurt_timer.stop(); } else { - // undo the ducking changes - bbox.move(Vector(0, 32)); - bbox.set_height(31.8); + // if timer is not already running, start it. + if (unduck_hurt_timer.get_period() == 0) { + unduck_hurt_timer.start(UNDUCK_HURT_TIME); + } + else if (unduck_hurt_timer.check()) { + kill(false); + } } } } @@ -599,7 +611,7 @@ void Player::set_bonus(BonusType type, bool animate) { if(player_status->bonus == NO_BONUS) { - adjust_height = 62.8; + if (!adjust_height(62.8)) return; if(animate) growing_timer.start(GROWING_TIME); } @@ -740,13 +752,14 @@ Player::draw(DrawingContext& context) /* Draw Tux */ if(dying) { smalltux_gameover->draw(context, get_pos(), LAYER_FLOATINGOBJECTS + 1); - } else if(growing_timer.get_timeleft() > 0) { + } + else if ((growing_timer.get_timeleft() > 0) && (!duck)) { if (dir == RIGHT) { context.draw_surface(growingtux_right[int((growing_timer.get_timegone() * - GROWING_FRAMES) / GROWING_TIME)], get_pos() - Vector(0, 32), layer); + GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); } else { context.draw_surface(growingtux_left[int((growing_timer.get_timegone() * - GROWING_FRAMES) / GROWING_TIME)], get_pos() - Vector(0, 32), layer); + GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); } } else if (safe_timer.started() && size_t(game_time*40)%2) @@ -913,7 +926,7 @@ Player::kill(bool completely) } else { //growing_timer.start(GROWING_TIME); safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */); - adjust_height = 30.8; + adjust_height(30.8); duck = false; set_bonus(NO_BONUS); } diff --git a/src/object/player.hpp b/src/object/player.hpp index c212822c5..d4645a1b2 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -44,7 +44,7 @@ class Portable; static const float TUX_SAFE_TIME = 1.8; static const float TUX_INVINCIBLE_TIME = 10.0; static const float TUX_INVINCIBLE_TIME_WARNING = 2.0; -static const float GROWING_TIME = 1.0; +static const float GROWING_TIME = 0.35; static const int GROWING_FRAMES = 7; class Camera; @@ -199,6 +199,12 @@ public: */ bool get_ghost_mode() { return ghost_mode; } + /** + * Changes height of bounding box. + * Returns true if successful, false otherwise + */ + bool adjust_height(float new_height); + private: void handle_input(); void handle_input_ghost(); /**< input handling while in ghost mode */ @@ -215,8 +221,6 @@ private: bool visible; - float adjust_height; - Portable* grabbed_object; Sprite* smalltux_gameover; @@ -225,6 +229,8 @@ private: Vector floor_normal; bool ghost_mode; /**< indicates if Tux should float around and through solid objects */ + + Timer unduck_hurt_timer; /**< if Tux wants to stand up again after ducking and cannot, this timer is started */ }; #endif /*SUPERTUX_PLAYER_H*/ diff --git a/src/sector.hpp b/src/sector.hpp index ab96230e6..b2ee2199e 100644 --- a/src/sector.hpp +++ b/src/sector.hpp @@ -129,7 +129,8 @@ public: void collision_tilemap(const Rect& dest, const Vector& movement, CollisionHit& hit) const; /** Checks if at the specified rectangle are gameobjects with STATIC flag set - * (or solid tiles from the tilemap) + * (or solid tiles from the tilemap). + * This does not(!) include badguys or players. */ bool is_free_space(const Rect& rect) const; -- 2.11.0