From 0c525ae9e6c920e9d2b97d8ba2fa5634eb8c7e72 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sat, 4 Jul 2020 13:15:56 -0500 Subject: [PATCH] Add acceleration and deceleration to MovementComponent --- .../components/movement/movement_component.h | 8 +- include/simpleengine/entity.h | 4 +- include/simpleengine/events/entity_event.h | 2 +- .../movement/movement_component.cpp | 122 ++++++++++++++++-- 4 files changed, 123 insertions(+), 13 deletions(-) diff --git a/include/simpleengine/components/movement/movement_component.h b/include/simpleengine/components/movement/movement_component.h index ce4ba35..f6b1b64 100644 --- a/include/simpleengine/components/movement/movement_component.h +++ b/include/simpleengine/components/movement/movement_component.h @@ -16,11 +16,15 @@ namespace simpleengine { class MovementComponent : public Component { public: - MovementComponent(Entity& owning_entity, float movement_speed); + MovementComponent(Entity& owning_entity, float max_velocity, float acceleration = 7, float deceleration = 2.5); + void Move(const float &delta_time, const float& dir_x, const float& dir_y); void Update(const float &delta_time) override; private: - float movement_speed; + float max_velocity; + sf::Vector2f velocity; + float acceleration; + float deceleration; }; } diff --git a/include/simpleengine/entity.h b/include/simpleengine/entity.h index 1632c5a..ce8232c 100644 --- a/include/simpleengine/entity.h +++ b/include/simpleengine/entity.h @@ -25,7 +25,9 @@ namespace simpleengine { virtual ~Entity() = default; Entity(const Entity& entity) = delete; - virtual void Move(const float& delta_time, const float& x, const float& y) {}; + virtual void Move(const float& delta_time, const float& dir_x, const float& dir_y) {}; + virtual void Move(const float& delta_time, const sf::Vector2f& offset) {}; + virtual void Move(const sf::Vector2f& offset) {}; virtual void Update(const float& delta_time) = 0; virtual void Render(sf::RenderTarget* target) = 0; diff --git a/include/simpleengine/events/entity_event.h b/include/simpleengine/events/entity_event.h index 3c806c8..30dfd02 100644 --- a/include/simpleengine/events/entity_event.h +++ b/include/simpleengine/events/entity_event.h @@ -27,7 +27,7 @@ namespace simpleengine { entity->Update(delta_time); if (entity->IsGettingDestroyed()) { - entity->DestroyLater(); + quit = true; } } diff --git a/src/components/movement/movement_component.cpp b/src/components/movement/movement_component.cpp index 222abce..dafa7ef 100644 --- a/src/components/movement/movement_component.cpp +++ b/src/components/movement/movement_component.cpp @@ -5,29 +5,133 @@ // #include "components/movement/movement_component.h" - -#include #include "entity.h" -simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, float movement_speed) : - Component(owning_entity), movement_speed(movement_speed) { +#include +#include +simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, float max_velocity, float acceleration, float deceleration) : + Component(owning_entity), max_velocity(max_velocity), acceleration(acceleration), deceleration(deceleration) { + +} + +void simpleengine::MovementComponent::Move(const float &delta_time, const float& dir_x, const float& dir_y) { + // Acceleration + velocity.x += acceleration * dir_x; + // Limit the horizontal velocity + if (velocity.x > 0) { // Right + velocity.x = std::min(velocity.x, max_velocity); + } else if (velocity.x < 0) { // Left + velocity.x = std::max(velocity.x, -max_velocity); + } + + velocity.y += acceleration * dir_y; + // Limit the vertical velocity + if (velocity.y > 0) { // Up + velocity.y = std::min(velocity.y, max_velocity); + } else if (velocity.y < 0) { // Down + velocity.y = std::max(velocity.y, -max_velocity); + } + + // Limit total velocity + float y_sq = velocity.y * velocity.y; + float x_sq = velocity.x * velocity.x; + float abs_sq = y_sq + x_sq; + if (abs_sq > max_velocity * max_velocity) { + float abs = sqrt(abs_sq); + velocity.x *= max_velocity / abs; + velocity.y *= max_velocity / abs; + } + + owning_entity.Move(velocity * delta_time); } void simpleengine::MovementComponent::Update(const float &delta_time) { + sf::Vector2f direction; if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - owning_entity.Move(delta_time, -1, 0); + direction.x = -1; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - owning_entity.Move(delta_time, 0, -1); + direction.y = -1; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - owning_entity.Move(delta_time, 1, 0); + direction.x = 1; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - owning_entity.Move(delta_time, 0, 1); + direction.y = 1; } -} + + //std::cout << "Speed: " << velocity.x << ", " << velocity.y << std::endl; + + // If we're not moving from deceleration or player input, then reset velocity. + bool no_movement = true; + + if (direction.y != 0 || direction.x == 0) { + if (velocity.y > 0) { + if (velocity.y > max_velocity) { + velocity.y = max_velocity; + } + + velocity.y -= deceleration; + if (velocity.y < 0) { + velocity.y = 0; + } + + owning_entity.Move(velocity * delta_time); + no_movement = false; + } else if (velocity.y < 0) { + if (velocity.y < -max_velocity) { + velocity.y = -max_velocity; + } + + velocity.y += deceleration; + if (velocity.y > 0) { + velocity.y = 0; + } + + owning_entity.Move(velocity * delta_time); + no_movement = false; + } + } + + if (direction.x != 0 || direction.y == 0) { + if (velocity.x > 0) { + if (velocity.x > max_velocity) { + velocity.x = max_velocity; + } + + velocity.x -= deceleration; + if (velocity.x < 0) { + velocity.x = 0; + } + + owning_entity.Move(velocity * delta_time); + no_movement = false; + } else if (velocity.x < 0) { + if (velocity.x < -max_velocity) { + velocity.x = -max_velocity; + } + + velocity.x += deceleration; + if (velocity.x > 0) { + velocity.x = 0; + } + + owning_entity.Move(velocity * delta_time); + no_movement = false; + + } + } + + if (direction.x != 0 || direction.y != 0) { + Move(delta_time, direction.x, direction.y); + no_movement = false; + } + + if (no_movement) { + velocity = sf::Vector2f(); + } +} \ No newline at end of file