Add acceleration and deceleration to MovementComponent

This commit is contained in:
SeanOMik 2020-07-04 13:15:56 -05:00
parent b24f4feb4a
commit 0c525ae9e6
No known key found for this signature in database
GPG Key ID: FA4D55AC05268A88
4 changed files with 123 additions and 13 deletions

View File

@ -16,11 +16,15 @@ namespace simpleengine {
class MovementComponent : public Component { class MovementComponent : public Component {
public: 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; void Update(const float &delta_time) override;
private: private:
float movement_speed; float max_velocity;
sf::Vector2f velocity;
float acceleration;
float deceleration;
}; };
} }

View File

@ -25,7 +25,9 @@ namespace simpleengine {
virtual ~Entity() = default; virtual ~Entity() = default;
Entity(const Entity& entity) = delete; 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 Update(const float& delta_time) = 0;
virtual void Render(sf::RenderTarget* target) = 0; virtual void Render(sf::RenderTarget* target) = 0;

View File

@ -27,7 +27,7 @@ namespace simpleengine {
entity->Update(delta_time); entity->Update(delta_time);
if (entity->IsGettingDestroyed()) { if (entity->IsGettingDestroyed()) {
entity->DestroyLater(); quit = true;
} }
} }

View File

@ -5,29 +5,133 @@
// //
#include "components/movement/movement_component.h" #include "components/movement/movement_component.h"
#include <utility>
#include "entity.h" #include "entity.h"
simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, float movement_speed) : #include <algorithm>
Component(owning_entity), movement_speed(movement_speed) { #include <iostream>
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) { void simpleengine::MovementComponent::Update(const float &delta_time) {
sf::Vector2f direction;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
owning_entity.Move(delta_time, -1, 0); direction.x = -1;
} }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
owning_entity.Move(delta_time, 0, -1); direction.y = -1;
} }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
owning_entity.Move(delta_time, 1, 0); direction.x = 1;
} }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { 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();
}
}