X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplayer.cpp;h=d09b97fca1b99ceade0720b6ffb068a6f2117adb;hb=75acd4b141f45e851a492f089aa9ad24a9552409;hp=951fb718a83388bac1c7d2c5b459da4a3f8d8a92;hpb=ae7bd4f460fdd93934fc0abc9589758a49309bda;p=supertux.git diff --git a/src/object/player.cpp b/src/object/player.cpp index 951fb718a..d09b97fca 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -18,39 +18,38 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include -#include -#include -#include -#include +#include "player.hpp" -#include "gettext.hpp" -#include "sprite/sprite_manager.hpp" #include "audio/sound_manager.hpp" -#include "player.hpp" -#include "tile.hpp" -#include "sprite/sprite.hpp" -#include "sector.hpp" -#include "resources.hpp" -#include "statistics.hpp" +#include "badguy/badguy.hpp" +#include "control/codecontroller.hpp" +#include "control/joystickkeyboardcontroller.hpp" +#include "display_effect.hpp" +#include "log.hpp" +#include "falling_coin.hpp" #include "game_session.hpp" -#include "object/tilemap.hpp" +#include "gettext.hpp" +#include "main.hpp" +#include "object/bullet.hpp" #include "object/camera.hpp" -#include "object/particles.hpp" #include "object/portable.hpp" -#include "object/bullet.hpp" -#include "trigger/trigger_base.hpp" -#include "control/joystickkeyboardcontroller.hpp" -#include "scripting/squirrel_util.hpp" -#include "main.hpp" -#include "platform.hpp" -#include "badguy/badguy.hpp" +#include "object/sprite_particle.hpp" +#include "object/tilemap.hpp" +#include "particles.hpp" #include "player_status.hpp" -#include "log.hpp" -#include "falling_coin.hpp" #include "random_generator.hpp" -#include "object/sprite_particle.hpp" +#include "sector.hpp" +#include "scripting/squirrel_util.hpp" +#include "sprite/sprite.hpp" +#include "sprite/sprite_manager.hpp" +#include "tile.hpp" #include "trigger/climbable.hpp" +#include +#include +#include +#include + //#define SWIMMING namespace { @@ -94,6 +93,12 @@ namespace { /** instant velocity when tux starts to walk */ static const float WALK_SPEED = 100; + /** multiplied by WALK_ACCELERATION to give friction */ + static const float NORMAL_FRICTION_MULTIPLIER = 1.5f; + /** multiplied by WALK_ACCELERATION to give friction */ + static const float ICE_FRICTION_MULTIPLIER = 0.1f; + static const float ICE_ACCELERATION_MULTIPLIER = 0.25f; + /** time of the kick (kicking mriceblock) animation */ static const float KICK_TIME = .3f; /** time of tux cheering (currently unused) */ @@ -105,6 +110,8 @@ namespace { the apex of the jump is reached */ static const float JUMP_EARLY_APEX_FACTOR = 3.0; + static const float JUMP_GRACE_TIME = 0.25f; /**< time before hitting the ground that the jump button may be pressed (and still trigger a jump) */ + bool no_water = true; } @@ -169,6 +176,8 @@ Player::init() backflip_direction = 0; visible = true; swimming = false; + on_ice = false; + ice_this_frame = false; speedlimit = 0; //no special limit on_ground_flag = false; @@ -348,7 +357,11 @@ Player::update(float elapsed_time) grabbed_object = NULL; } + if(!ice_this_frame && on_ground()) + on_ice = false; + on_ground_flag = false; + ice_this_frame = false; // when invincible, spawn particles if (invincible_timer.started() && !dying) @@ -359,17 +372,13 @@ Player::update(float elapsed_time) Vector ppos = Vector(px, py); Vector pspeed = Vector(0, 0); Vector paccel = Vector(0, 0); - // draw bright sparkle when there is lots of time left, dark sparkle when invincibility is about to end - if (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING) { - // make every other a longer sparkle to make trail a bit fuzzy - if (size_t(game_time*20)%2) { - Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "small", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5)); - } else { - Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "medium", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5)); - } - } else { - Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5)); - } + Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", + // draw bright sparkle when there is lots of time left, dark sparkle when invincibility is about to end + (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING) ? + // make every other a longer sparkle to make trail a bit fuzzy + (size_t(game_time*20)%2) ? "small" : "medium" + : + "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5)); } } @@ -400,10 +409,13 @@ Player::apply_friction() if ((on_ground()) && (fabs(physic.get_velocity_x()) < WALK_SPEED)) { physic.set_velocity_x(0); physic.set_acceleration_x(0); - } else if(physic.get_velocity_x() < 0) { - physic.set_acceleration_x(WALK_ACCELERATION_X * 1.5); + } else { + float friction = WALK_ACCELERATION_X * (on_ice ? ICE_FRICTION_MULTIPLIER : NORMAL_FRICTION_MULTIPLIER); + if(physic.get_velocity_x() < 0) { + physic.set_acceleration_x(friction); } else if(physic.get_velocity_x() > 0) { - physic.set_acceleration_x(WALK_ACCELERATION_X * -1.5); + physic.set_acceleration_x(-friction); + } // no friction for physic.get_velocity_x() == 0 } } @@ -488,6 +500,10 @@ Player::handle_horizontal_input() } } + if(on_ice) { + ax *= ICE_ACCELERATION_MULTIPLIER; + } + physic.set_velocity(vx, vy); physic.set_acceleration(ax, ay); @@ -608,7 +624,9 @@ void Player::handle_vertical_input() { // Press jump key - if(controller->pressed(Controller::JUMP) && (can_jump)) { + if(controller->pressed(Controller::JUMP)) jump_button_timer.start(JUMP_GRACE_TIME); + if(controller->hold(Controller::JUMP) && jump_button_timer.started() && can_jump) { + jump_button_timer.stop(); if (duck) { // when running, only jump a little bit; else do a backflip if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) do_jump(-300); else do_backflip(); @@ -666,16 +684,10 @@ Player::handle_input() } /* Peeking */ - if( controller->released( Controller::PEEK_LEFT ) ) { + if( controller->released( Controller::PEEK_LEFT ) || controller->released( Controller::PEEK_RIGHT ) ) { peekingX = AUTO; } - if( controller->released( Controller::PEEK_RIGHT ) ) { - peekingX = AUTO; - } - if( controller->released( Controller::PEEK_UP ) ) { - peekingY = AUTO; - } - if( controller->released( Controller::PEEK_DOWN ) ) { + if( controller->released( Controller::PEEK_UP ) || controller->released( Controller::PEEK_DOWN ) ) { peekingY = AUTO; } if( controller->pressed( Controller::PEEK_LEFT ) ) { @@ -696,7 +708,7 @@ Player::handle_input() if (!backflipping) handle_horizontal_input(); /* Jump/jumping? */ - if (on_ground() && !controller->hold(Controller::JUMP)) + if (on_ground()) can_jump = true; /* Handle vertical movement: */ @@ -949,6 +961,8 @@ Player::draw(DrawingContext& context) } std::string sa_prefix = ""; + std::string sa_postfix = ""; + if (player_status->bonus == GROWUP_BONUS) sa_prefix = "big"; else if (player_status->bonus == FIRE_BONUS) @@ -958,36 +972,41 @@ Player::draw(DrawingContext& context) else sa_prefix = "small"; + if(dir == LEFT) + sa_postfix = "-left"; + else + sa_postfix = "-right"; + /* Set Tux sprite action */ if(dying) { sprite->set_action("gameover"); } else if (growing) { - sprite->set_action_continued((dir == LEFT)?"grow-left":"grow-right"); + sprite->set_action_continued("grow"+sa_postfix); // while growing, do not change action // do_duck() will take care of cancelling growing manually // update() will take care of cancelling when growing completed } else if (climbing) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-skid-left":"-skid-right")); + sprite->set_action(sa_prefix+"-skid"+sa_postfix); } else if (backflipping) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-backflip-left":"-backflip-right")); + sprite->set_action(sa_prefix+"-backflip"+sa_postfix); } else if (duck && is_big()) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-duck-left":"-duck-right")); + sprite->set_action(sa_prefix+"-duck"+sa_postfix); } else if (skidding_timer.started() && !skidding_timer.check()) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-skid-left":"-skid-right")); + sprite->set_action(sa_prefix+"-skid"+sa_postfix); } else if (kick_timer.started() && !kick_timer.check()) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-kick-left":"-kick-right")); + sprite->set_action(sa_prefix+"-kick"+sa_postfix); } else if ((wants_buttjump || does_buttjump) && is_big()) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-buttjump-left":"-buttjump-right")); + sprite->set_action(sa_prefix+"-buttjump"+sa_postfix); } else if (!on_ground()) { - sprite->set_action(sa_prefix+((dir == LEFT)?"-jump-left":"-jump-right")); + sprite->set_action(sa_prefix+"-jump"+sa_postfix); } else { if (fabsf(physic.get_velocity_x()) < 1.0f) { @@ -996,7 +1015,7 @@ Player::draw(DrawingContext& context) idle_stage = 0; idle_timer.start(IDLE_TIME[idle_stage]/1000.0f); - sprite->set_action_continued(sa_prefix+((dir == LEFT)?"-" + IDLE_STAGES[idle_stage] + "-left":"-" + IDLE_STAGES[idle_stage] + "-right")); + sprite->set_action_continued(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix); } else if (idle_timer.check() || (IDLE_TIME[idle_stage] == 0 && sprite->animation_done())) { idle_stage++; @@ -1006,16 +1025,16 @@ Player::draw(DrawingContext& context) idle_timer.start(IDLE_TIME[idle_stage]/1000.0f); if (IDLE_TIME[idle_stage] == 0) - sprite->set_action(sa_prefix+((dir == LEFT)?"-" + IDLE_STAGES[idle_stage] + "-left":"-" + IDLE_STAGES[idle_stage] + "-right"), 1); + sprite->set_action(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix, 1); else - sprite->set_action(sa_prefix+((dir == LEFT)?"-" + IDLE_STAGES[idle_stage] + "-left":"-" + IDLE_STAGES[idle_stage] + "-right")); + sprite->set_action(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix); } else { - sprite->set_action_continued(sa_prefix+((dir == LEFT)?"-" + IDLE_STAGES[idle_stage] + "-left":"-" + IDLE_STAGES[idle_stage] + "-right")); + sprite->set_action_continued(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix); } } else { - sprite->set_action(sa_prefix+((dir == LEFT)?"-walk-left":"-walk-right")); + sprite->set_action(sa_prefix+"-walk"+sa_postfix); } } @@ -1060,6 +1079,11 @@ Player::collision_tile(uint32_t tile_attributes) } } #endif + + if(tile_attributes & Tile::ICE) { + ice_this_frame = true; + on_ice = true; + } } void @@ -1217,9 +1241,7 @@ Player::kill(bool completely) dying_timer.start(3.0); set_group(COLGROUP_DISABLED); - DisplayEffect* effect = new DisplayEffect(); - effect->fade_out(3.0); - Sector::current()->add_object(effect); + Sector::current()->effect->fade_out(3.0); sound_manager->stop_music(3.0); } } @@ -1244,13 +1266,19 @@ Player::move(const Vector& vector) void Player::check_bounds(Camera* camera) { - /* Keep tux in bounds: */ + /* Keep tux in sector bounds: */ if (get_pos().x < 0) { - // Lock Tux to the size of the level, so that he doesn't fall of - // on the left side + // Lock Tux to the size of the level, so that he doesn't fall off + // the left side set_pos(Vector(0, get_pos().y)); } + if (get_bbox().get_right() > Sector::current()->get_width()) { + // Lock Tux to the size of the level, so that he doesn't fall off + // the right side + set_pos(Vector(Sector::current()->get_width() - get_bbox().get_width(), get_pos().y)); + } + /* fallen out of the level? */ if ((get_pos().y > Sector::current()->get_height()) && (!ghost_mode)) { kill(true);