Update MovementComponent to use EventCallbacks for input.

This commit is contained in:
SeanOMik 2021-03-21 19:55:29 -05:00
parent c8dccc9907
commit f97f882845
No known key found for this signature in database
GPG Key ID: CA09E5BE1F32728A
6 changed files with 139 additions and 94 deletions

View File

@ -20,30 +20,28 @@ class PlayerEntity : public simpleengine::Entity {
private: private:
sf::Sprite sprite; sf::Sprite sprite;
sf::Texture texture; sf::Texture texture;
float movement_speed = 130; float movement_speed = 50;
sf::Vector2u window_size; sf::Vector2u window_size;
// Components: // Components
std::shared_ptr<simpleengine::CollisionComponent> hitbox_component; std::shared_ptr<simpleengine::CollisionComponent> hitbox_component;
std::shared_ptr<simpleengine::SideScrollerMovementAnimationComponent> move_anim_component; std::shared_ptr<simpleengine::SideScrollerMovementAnimationComponent> move_anim_component;
public: public:
explicit PlayerEntity(sf::Vector2u window_size) : Entity(sprite), window_size(window_size) { explicit PlayerEntity(sf::Vector2u window_size, simpleengine::Game& game) : Entity(sprite), window_size(window_size) {
texture.loadFromFile("player_sheet.png"); texture.loadFromFile("player_sheet.png");
texture.setSmooth(true); texture.setSmooth(true);
sprite.setTexture(texture); sprite.setTexture(texture);
sprite.setScale(0.7f, 0.7f); sprite.setScale(0.5, 0.5);
sprite.setPosition(100, 100);
move_anim_component = std::make_shared<simpleengine::SideScrollerMovementAnimationComponent>(*this, sprite, move_anim_component = std::make_shared<simpleengine::SideScrollerMovementAnimationComponent>(*this, game, sprite,
texture, movement_speed, 5.f, 1.1f); texture, movement_speed, 6, 3);
move_anim_component->SetAnimation(simpleengine::MovementAnimationType::WALK_LEFT, 8, 0, 9, move_anim_component->SetAnimation(simpleengine::MovementAnimationType::WALK_LEFT, 8, 0, 9, 9, 9, 128, 128);
9, 9, 128, 128); move_anim_component->SetAnimation(simpleengine::MovementAnimationType::IDLE_LEFT, 20, 0, 0, 6, 0, 128, 128);
move_anim_component->SetAnimation(simpleengine::MovementAnimationType::IDLE_LEFT, 20, 0, 0,
6, 0, 128, 128);
AddComponent(std::move(move_anim_component));
AddComponent(move_anim_component); AddComponent(move_anim_component);
hitbox_component = std::make_shared<simpleengine::CollisionComponent>(*this, sprite, hitbox_component = std::make_shared<simpleengine::CollisionComponent>(*this, sprite, -13, 12,
20.f, 12.f, sprite.getGlobalBounds().width - 40.f, sprite.getGlobalBounds().height - 15.f); sprite.getGlobalBounds().width - 35.f, sprite.getGlobalBounds().height - 15.f);
AddComponent(hitbox_component); AddComponent(hitbox_component);
} }
@ -66,7 +64,7 @@ public:
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
simpleengine::Game game(700, 700, "SimpleEngine - Animation Example"); simpleengine::Game game(700, 700, "SimpleEngine - Animation Example");
game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique<PlayerEntity>(game.GetWindow()->getSize()))); game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique<PlayerEntity>(game.GetWindow()->getSize(), game)));
return game.Run(); return game.Run();
} }

View File

@ -13,17 +13,23 @@
namespace simpleengine { namespace simpleengine {
class Entity; class Entity;
class Game;
class MovementComponent : public Component { class MovementComponent : public Component {
public: public:
MovementComponent(Entity& owning_entity, float max_velocity, float acceleration = 7, float deceleration = 2.5); MovementComponent(Entity& owning_entity, Game& game, float max_velocity, float acceleration = 7, float deceleration = 2.5);
void OnKeyPress(sf::Event::KeyEvent event);
void OnKeyRelease(sf::Event::KeyEvent event);
void Move(const float& delta_time, const float& dir_x, const float& dir_y); 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;
const sf::Vector2f& GetVelocity() const; const sf::Vector2f& GetVelocity() const;
const sf::Vector2f& GetLastDirection() const; const sf::Vector2f& GetLastDirection() const;
private: private:
sf::Vector2f direction;
float max_velocity; float max_velocity;
sf::Vector2f velocity; sf::Vector2f velocity;
sf::Vector2f last_direction; sf::Vector2f last_direction;

View File

@ -27,7 +27,7 @@ namespace simpleengine {
// Use this for side scrollers! // Use this for side scrollers!
class SideScrollerMovementAnimationComponent : public Component { class SideScrollerMovementAnimationComponent : public Component {
public: public:
SideScrollerMovementAnimationComponent(Entity& owning_entity, sf::Sprite &sprite, sf::Texture &texture_sheet, SideScrollerMovementAnimationComponent(Entity& owning_entity, Game& game, sf::Sprite &sprite, sf::Texture &texture_sheet,
float max_velocity, float acceleration, float deceleration); float max_velocity, float acceleration, float deceleration);
void SetAnimation(const MovementAnimationType& type, simpleengine::Animation animation); void SetAnimation(const MovementAnimationType& type, simpleengine::Animation animation);

View File

@ -12,7 +12,7 @@
#include <ostream> #include <ostream>
simpleengine::CollisionComponent::CollisionComponent(Entity& owning_entity, sf::Transformable &transformable, float offset_x, float offset_y, simpleengine::CollisionComponent::CollisionComponent(Entity& owning_entity, sf::Transformable &transformable, float offset_x, float offset_y,
float width, float height) : simpleengine::CollisionComponent::CollisionComponent(owning_entity, transformable, hitbox, offset_x, offset_y) { float width, float height) : simpleengine::CollisionComponent::CollisionComponent(owning_entity, transformable, sf::RectangleShape(), offset_x, offset_y) {
hitbox.setPosition(transformable.getPosition().x + offset_x, transformable.getPosition().y + offset_y); hitbox.setPosition(transformable.getPosition().x + offset_x, transformable.getPosition().y + offset_y);
hitbox.setSize(sf::Vector2f(width, height)); hitbox.setSize(sf::Vector2f(width, height));
@ -30,8 +30,8 @@ simpleengine::CollisionComponent::CollisionComponent(Entity& owning_entity, sf::
// SSMA Component set's the sprites texture offset so we need to set // SSMA Component set's the sprites texture offset so we need to set
// the offset to the origin if the entity has the SSMA component. // the offset to the origin if the entity has the SSMA component.
if (owning_entity.HasComponent<simpleengine::SideScrollerMovementAnimationComponent>()) { if (auto ssma_comp = owning_entity.GetComponent<simpleengine::SideScrollerMovementAnimationComponent>(); ssma_comp) {
offset_x += dynamic_cast<sf::RectangleShape&>(transformable).getGlobalBounds().width * -0.5f; offset_x += ssma_comp->GetAnimationComponent().GetSprite().getGlobalBounds().width * -0.5f;
} }
} }

View File

@ -6,12 +6,22 @@
#include "components/movement/movement_component.h" #include "components/movement/movement_component.h"
#include "entity.h" #include "entity.h"
#include "game.h"
#include <SFML/Window/Keyboard.hpp>
#include <algorithm> #include <algorithm>
simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, float max_velocity, float acceleration, float deceleration) : #include <iostream>
simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, Game& game, float max_velocity, float acceleration, float deceleration) :
Component(owning_entity), max_velocity(max_velocity), acceleration(acceleration), deceleration(deceleration) { Component(owning_entity), max_velocity(max_velocity), acceleration(acceleration), deceleration(deceleration) {
game.AddEventCallback<sf::Event::EventType::KeyPressed>(std::function([this](sf::Event::KeyEvent event) {
this->OnKeyPress(event);
}));
game.AddEventCallback<sf::Event::EventType::KeyReleased>(std::function([this](sf::Event::KeyEvent event) {
this->OnKeyRelease(event);
}));
} }
void simpleengine::MovementComponent::Move(const float& delta_time, const float& dir_x, const float& dir_y) { void simpleengine::MovementComponent::Move(const float& delta_time, const float& dir_x, const float& dir_y) {
@ -45,86 +55,105 @@ void simpleengine::MovementComponent::Move(const float& delta_time, const float&
owning_entity.Move(delta_time, velocity); owning_entity.Move(delta_time, velocity);
} }
void simpleengine::MovementComponent::OnKeyPress(sf::Event::KeyEvent event) {
sf::Keyboard::Key key = event.code;
switch(key) {
case sf::Keyboard::W:
direction.y = -1;
break;
case sf::Keyboard::A:
direction.x = -1;
break;
case sf::Keyboard::S:
direction.y = 1;
break;
case sf::Keyboard::D:
direction.x = 1;
break;
default:
break;
}
}
void simpleengine::MovementComponent::OnKeyRelease(sf::Event::KeyEvent event) {
sf::Keyboard::Key key = event.code;
switch(key) {
case sf::Keyboard::W:
direction.y = (!sf::Keyboard::isKeyPressed(sf::Keyboard::S)) ? 0 : 1;
break;
case sf::Keyboard::A:
direction.x = (!sf::Keyboard::isKeyPressed(sf::Keyboard::D)) ? 0 : 1;
break;
case sf::Keyboard::S:
direction.y = (!sf::Keyboard::isKeyPressed(sf::Keyboard::W)) ? 0 : -1;
break;
case sf::Keyboard::D:
direction.x = (!sf::Keyboard::isKeyPressed(sf::Keyboard::A)) ? 0 : -1;
break;
default:
break;
}
}
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)) {
direction.x = -1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
direction.y = -1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
direction.x = 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
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. // If we're not moving from deceleration or player input, then reset velocity.
bool no_movement = true; 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) { if (velocity.y > 0) {
if (velocity.y > max_velocity) { velocity.y = 0;
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;
} }
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) { if (velocity.x > 0) {
if (velocity.x > max_velocity) { velocity.x = 0;
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;
} }
owning_entity.Move(velocity * delta_time);
no_movement = false;
} }
if (direction.x != 0 || direction.y != 0) { if (direction.x != 0 || direction.y != 0) {
last_direction = direction; last_direction = direction;
Move(delta_time, direction.x, direction.y); Move(delta_time, direction.x, direction.y);

View File

@ -7,9 +7,9 @@
#include "components/ssma_component.h" #include "components/ssma_component.h"
simpleengine::SideScrollerMovementAnimationComponent::SideScrollerMovementAnimationComponent(simpleengine::Entity &owning_entity, simpleengine::SideScrollerMovementAnimationComponent::SideScrollerMovementAnimationComponent(simpleengine::Entity &owning_entity,
sf::Sprite &sprite, sf::Texture &texture_sheet, float max_velocity, float acceleration, float deceleration) Game& game, sf::Sprite &sprite, sf::Texture &texture_sheet, float max_velocity, float acceleration, float deceleration)
: Component(owning_entity), anim_component(owning_entity, sprite, texture_sheet), : Component(owning_entity), anim_component(owning_entity, sprite, texture_sheet),
move_component(owning_entity, max_velocity, acceleration, deceleration) { move_component(owning_entity, game, max_velocity, acceleration, deceleration) {
} }
void simpleengine::SideScrollerMovementAnimationComponent::SetAnimation(const simpleengine::MovementAnimationType &type, void simpleengine::SideScrollerMovementAnimationComponent::SetAnimation(const simpleengine::MovementAnimationType &type,
@ -62,7 +62,7 @@ void simpleengine::SideScrollerMovementAnimationComponent::Update(const float& d
anim.Update(delta_time); anim.Update(delta_time);
} }
} else { } else {
// If the user never set a IDLE_RIGHT animation, then we need to flip the IDLE_LEFT one. // If the user never set an IDLE_RIGHT animation, then we need to flip the IDLE_LEFT one.
if (move_component.GetLastDirection().x > 0) { // Facing right if (move_component.GetLastDirection().x > 0) { // Facing right
if (anim_component.HasAnimation("IDLE_RIGHT")) { if (anim_component.HasAnimation("IDLE_RIGHT")) {
Animation& anim = anim_component.GetAnimation("IDLE_RIGHT"); Animation& anim = anim_component.GetAnimation("IDLE_RIGHT");
@ -75,9 +75,21 @@ void simpleengine::SideScrollerMovementAnimationComponent::Update(const float& d
Animation& anim = anim_component.GetAnimation("IDLE_LEFT"); Animation& anim = anim_component.GetAnimation("IDLE_LEFT");
anim.Update(delta_time); anim.Update(delta_time);
} }
} else if (move_component.GetLastDirection().x < 0) { // Facing left
if (anim_component.HasAnimation("IDLE_LEFT")) {
Animation& anim = anim_component.GetAnimation("IDLE_LEFT");
if (anim.IsHorizontallyFlipped()) {
anim.FlipHorizontally();
}
anim.Update(delta_time);
} else {
Animation& anim = anim_component.GetAnimation("IDLE_RIGHT");
anim.Update(delta_time);
}
} else { } else {
// If the user never set a IDLE_LEFT animation, then we need to flip the IDLE_RIGHT one. // If the user never set an IDLE_LEFT animation, then we need to flip the IDLE_RIGHT one.
if (anim_component.HasAnimation("IDLE_LEFT")) { // Facing left if (anim_component.HasAnimation("IDLE_LEFT")) {
Animation& anim = anim_component.GetAnimation("IDLE_LEFT"); Animation& anim = anim_component.GetAnimation("IDLE_LEFT");
if (anim.IsHorizontallyFlipped()) { if (anim.IsHorizontallyFlipped()) {
anim.FlipHorizontally(); anim.FlipHorizontally();