X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplayer.cpp;h=2005f512d179c36d937e650fe1da40a2fac01c12;hb=5f1c84ed5ce0ab5450f92082a9aaaa9ca0effc39;hp=13b41012bc99fc7a04949f7da7b808c7b2553e69;hpb=ed51c9c974fe748420844158b8ce572a1f8ea284;p=supertux.git diff --git a/src/object/player.cpp b/src/object/player.cpp index 13b41012b..2005f512d 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]; @@ -128,10 +130,9 @@ void Player::init() { if(is_big()) - bbox.set_size(31.8, 62.8); + set_size(31.8, 62.8); else - bbox.set_size(31.8, 30.8); - adjust_height = 0; + set_size(31.8, 30.8); 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(); @@ -197,8 +206,7 @@ Player::update(float elapsed_time) if(grabbed_object != NULL && !dying) { Vector pos = get_pos() + - Vector(dir == LEFT ? -16 : 16, - bbox.get_height()*0.66666 - 32); + Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32); grabbed_object->grab(*this, pos, dir); } @@ -283,7 +291,7 @@ Player::handle_horizontal_input() // dust some particles Sector::current()->add_object( new Particles( - Vector(dir == RIGHT ? bbox.p2.x : bbox.p1.x, bbox.p2.y), + Vector(dir == RIGHT ? get_bbox().p2.x : get_bbox().p1.x, get_bbox().p2.y), dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20, Vector(280, -260), Vector(0, 300), 3, Color(.4, .4, .4), 3, .8, LAYER_OBJECTS+1)); @@ -296,7 +304,7 @@ Player::handle_horizontal_input() // we get slower when not pressing any keys if(dirsign == 0) { - if(fabs(vx) < WALK_SPEED) { + if ((on_ground()) && (fabs(vx) < WALK_SPEED)) { vx = 0; ax = 0; } else if(vx < 0) { @@ -324,9 +332,9 @@ Player::handle_horizontal_input() // extend/shrink tux collision rectangle so that we fall through/walk over 1 // tile holes if(fabsf(vx) > MAX_WALK_XM) { - bbox.set_width(34); + set_width(34); } else { - bbox.set_width(31.8); + set_width(31.8); } // on downward slopes, adjust vertical velocity to match slope angle @@ -518,23 +526,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 +610,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 +751,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 +925,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); } @@ -944,11 +956,13 @@ Player::kill(bool completely) void Player::move(const Vector& vector) { - bbox.set_pos(vector); + set_pos(vector); + + // TODO: do we need the following? Seems irrelevant to moving the player if(is_big()) - bbox.set_size(31.8, 63.8); + set_size(31.8, 63.8); else - bbox.set_size(31.8, 31.8); + set_size(31.8, 31.8); duck = false; last_ground_y = vector.y; @@ -962,7 +976,7 @@ Player::check_bounds(Camera* camera) if (get_pos().x < 0) { // Lock Tux to the size of the level, so that he doesn't fall of // on the left side - bbox.set_pos(Vector(0, get_pos().y)); + set_pos(Vector(0, get_pos().y)); } /* Keep in-bounds, vertically: */ @@ -974,12 +988,12 @@ Player::check_bounds(Camera* camera) bool adjust = false; // can happen if back scrolling is disabled if(get_pos().x < camera->get_translation().x) { - bbox.set_pos(Vector(camera->get_translation().x, get_pos().y)); + set_pos(Vector(camera->get_translation().x, get_pos().y)); adjust = true; } if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width()) { - bbox.set_pos(Vector( + set_pos(Vector( camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(), get_pos().y)); adjust = true; @@ -1004,6 +1018,15 @@ Player::add_velocity(const Vector& velocity) } void +Player::add_velocity(const Vector& velocity, const Vector& end_speed) +{ + if (end_speed.x > 0) physic.set_velocity_x(std::min(physic.get_velocity_x() + velocity.x, end_speed.x)); + if (end_speed.x < 0) physic.set_velocity_x(std::max(physic.get_velocity_x() + velocity.x, end_speed.x)); + if (end_speed.y > 0) physic.set_velocity_y(std::min(physic.get_velocity_y() + velocity.y, end_speed.y)); + if (end_speed.y < 0) physic.set_velocity_y(std::max(physic.get_velocity_y() + velocity.y, end_speed.y)); +} + +void Player::bounce(BadGuy& ) { if(controller->hold(Controller::JUMP))