From 7f525144d8e1c46105c6f1be31a02b788efca4fc Mon Sep 17 00:00:00 2001 From: Semphris Date: Thu, 25 Feb 2021 18:57:07 -0500 Subject: [PATCH 1/3] Changed handling of Tux movement - Removed speed ceiling that gets applied whenever the player presses a certain direction. Now, limits are applies regardless of what the player presses, and the speed is brought back within limits smoothly rather than instantly. - Added a boost mechanism, to help Tux gain extra velocity above speed limits for a short amount of time (useful for bumpers). - Fixed the one-wall walljump-climbing bug. --- src/object/bumper.cpp | 3 ++- src/object/player.cpp | 42 ++++++++++++++++++++++++++++++------------ src/object/player.hpp | 4 ++++ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/object/bumper.cpp b/src/object/bumper.cpp index 5f0a3410ba1..1ef75fc8b86 100644 --- a/src/object/bumper.cpp +++ b/src/object/bumper.cpp @@ -67,7 +67,8 @@ Bumper::collision(GameObject& other, const CollisionHit& hit) if (player) { float BOUNCE_DIR = left ? -BOUNCE_X : BOUNCE_X; - player->get_physic().set_velocity(BOUNCE_DIR, BOUNCE_Y); + player->get_physic().set_velocity(0.f, BOUNCE_Y); + player->sideways_push(BOUNCE_DIR); SoundManager::current()->play(TRAMPOLINE_SOUND); m_sprite->set_action((left ? "left-swinging" : "right-swinging"), 1); } diff --git a/src/object/player.cpp b/src/object/player.cpp index 6d227fcc071..1deedbfef90 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -98,6 +98,10 @@ const float MAX_GLIDE_YM = 128; const float MAX_WALLCLING_YM = 64; /** instant velocity when tux starts to walk */ const float WALK_SPEED = 100; +/** rate at which m_boost decreases */ +const float BOOST_DECREASE_RATE = 500; +/** rate at which the speed decreases if going above maximum */ +const float OVERSPEED_DECELERATION = 100; /** multiplied by WALK_ACCELERATION to give friction */ const float NORMAL_FRICTION_MULTIPLIER = 1.5f; @@ -154,6 +158,7 @@ Player::Player(PlayerStatus& player_status, const std::string& name_) : m_on_right_wall(false), m_in_walljump_tile(false), m_can_walljump(false), + m_boost(0.f), m_speedlimit(0), //no special limit m_scripting_controller_old(nullptr), m_jump_early_apex(false), @@ -501,8 +506,16 @@ Player::update(float dt_sec) m_physic.set_acceleration_y(-WATER_FALLOUT_FORCEBACK_STRENGTH); } + if (m_boost != 0.f) + { + bool sign = std::signbit(m_boost); + m_boost = (sign ? -1.f : +1.f) * (std::abs(m_boost) - dt_sec * BOOST_DECREASE_RATE); + if (signbit(m_boost) != sign) + m_boost = 0.f; + } + // calculate movement for this frame - m_col.m_movement = m_physic.get_movement(dt_sec); + m_col.m_movement = m_physic.get_movement(dt_sec) + Vector(m_boost * dt_sec, 0); if (m_grabbed_object != nullptr && !m_dying) { position_grabbed_object(); @@ -769,11 +782,9 @@ Player::handle_horizontal_input() ax = dirsign * WALK_ACCELERATION_X; // limit speed if (vx >= MAX_WALK_XM && dirsign > 0) { - vx = MAX_WALK_XM; - ax = 0; + ax = std::min(ax, -OVERSPEED_DECELERATION); } else if (vx <= -MAX_WALK_XM && dirsign < 0) { - vx = -MAX_WALK_XM; - ax = 0; + ax = std::max(ax, OVERSPEED_DECELERATION); } } else { if ( vx * dirsign < MAX_WALK_XM ) { @@ -782,12 +793,10 @@ Player::handle_horizontal_input() ax = dirsign * RUN_ACCELERATION_X; } // limit speed - if (vx >= MAX_RUN_XM + BONUS_RUN_XM *((m_player_status.bonus == AIR_BONUS) ? 1 : 0) && dirsign > 0) { - vx = MAX_RUN_XM + BONUS_RUN_XM *((m_player_status.bonus == AIR_BONUS) ? 1 : 0); - ax = 0; - } else if (vx <= -MAX_RUN_XM - BONUS_RUN_XM *((m_player_status.bonus == AIR_BONUS) ? 1 : 0) && dirsign < 0) { - vx = -MAX_RUN_XM - BONUS_RUN_XM *((m_player_status.bonus == AIR_BONUS) ? 1 : 0); - ax = 0; + if (vx >= MAX_RUN_XM + BONUS_RUN_XM *((m_player_status.bonus == AIR_BONUS) ? 1 : 0)) { + ax = std::min(ax, -OVERSPEED_DECELERATION); + } else if (vx <= -MAX_RUN_XM - BONUS_RUN_XM *((m_player_status.bonus == AIR_BONUS) ? 1 : 0)) { + ax = std::max(ax, OVERSPEED_DECELERATION); } } @@ -1035,7 +1044,7 @@ Player::handle_vertical_input() if (m_controller->pressed(Control::JUMP) && m_can_walljump && !m_backflipping) { SoundManager::current()->play((is_big()) ? "sounds/bigjump.wav" : "sounds/jump.wav"); - m_physic.set_velocity(m_on_left_wall ? 400.f : -400.f, -520.f); + m_physic.set_velocity(m_on_left_wall ? 450.f : -450.f, -520.f); } m_physic.set_acceleration_y(0); @@ -1746,6 +1755,9 @@ Player::collision_solid(const CollisionHit& hit) kill(false); } } + + if ((hit.left && m_boost < 0.f) || (hit.right && m_boost > 0.f)) + m_boost = 0.f; } HitResponse @@ -2126,4 +2138,10 @@ Player::has_grabbed(const std::string& object_name) const return false; } +void +Player::sideways_push(float delta) +{ + m_boost = delta; +} + /* EOF */ diff --git a/src/object/player.hpp b/src/object/player.hpp index 46b9989e273..c93f484bd80 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -191,6 +191,9 @@ class Player final : public MovingObject, void position_grabbed_object(); void try_grab(); + /** Boosts Tux in a certain direction, sideways. Useful for bumpers/walljumping. */ + void sideways_push(float delta); + private: void handle_input(); void handle_input_ghost(); /**< input handling while in ghost mode */ @@ -238,6 +241,7 @@ class Player final : public MovingObject, bool m_on_right_wall; bool m_in_walljump_tile; bool m_can_walljump; + float m_boost; float m_speedlimit; const Controller* m_scripting_controller_old; /**< Saves the old controller while the scripting_controller is used */ bool m_jump_early_apex; From 0daa42916713188a04cf9525a37ac377977aef8b Mon Sep 17 00:00:00 2001 From: Semphris Date: Fri, 26 Feb 2021 03:36:34 -0500 Subject: [PATCH 2/3] Fixed build errors --- src/object/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/player.cpp b/src/object/player.cpp index 1deedbfef90..faa4ff72dab 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -510,7 +510,7 @@ Player::update(float dt_sec) { bool sign = std::signbit(m_boost); m_boost = (sign ? -1.f : +1.f) * (std::abs(m_boost) - dt_sec * BOOST_DECREASE_RATE); - if (signbit(m_boost) != sign) + if (std::signbit(m_boost) != sign) m_boost = 0.f; } From 9be6ea0458fe750844768eebccdecc2d19837998 Mon Sep 17 00:00:00 2001 From: Semphriss <66701383+Semphriss@users.noreply.github.com> Date: Thu, 4 Mar 2021 16:09:00 -0500 Subject: [PATCH 3/3] Fixed merge error --- src/object/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/player.cpp b/src/object/player.cpp index a961c6fa9bd..417c38aa0cf 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -517,7 +517,7 @@ Player::update(float dt_sec) } // calculate movement for this frame - m_col.m_movement = m_physic.get_movement(dt_sec) + Vector(m_boost * dt_sec, 0); + m_col.set_movement(m_physic.get_movement(dt_sec) + Vector(m_boost * dt_sec, 0)); if (m_grabbed_object != nullptr && !m_dying) { position_grabbed_object();