diff --git a/examples/animation/src/main.cpp b/examples/animation/src/main.cpp index ee75a18..aca8e20 100644 --- a/examples/animation/src/main.cpp +++ b/examples/animation/src/main.cpp @@ -20,30 +20,28 @@ class PlayerEntity : public simpleengine::Entity { private: sf::Sprite sprite; sf::Texture texture; - float movement_speed = 130; + float movement_speed = 50; sf::Vector2u window_size; - // Components: + // Components std::shared_ptr hitbox_component; std::shared_ptr move_anim_component; 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.setSmooth(true); 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(*this, sprite, - texture, movement_speed, 5.f, 1.1f); - move_anim_component->SetAnimation(simpleengine::MovementAnimationType::WALK_LEFT, 8, 0, 9, - 9, 9, 128, 128); - move_anim_component->SetAnimation(simpleengine::MovementAnimationType::IDLE_LEFT, 20, 0, 0, - 6, 0, 128, 128); - AddComponent(std::move(move_anim_component)); + move_anim_component = std::make_shared(*this, game, sprite, + texture, movement_speed, 6, 3); + move_anim_component->SetAnimation(simpleengine::MovementAnimationType::WALK_LEFT, 8, 0, 9, 9, 9, 128, 128); + move_anim_component->SetAnimation(simpleengine::MovementAnimationType::IDLE_LEFT, 20, 0, 0, 6, 0, 128, 128); AddComponent(move_anim_component); - hitbox_component = std::make_shared(*this, sprite, - 20.f, 12.f, sprite.getGlobalBounds().width - 40.f, sprite.getGlobalBounds().height - 15.f); + hitbox_component = std::make_shared(*this, sprite, -13, 12, + sprite.getGlobalBounds().width - 35.f, sprite.getGlobalBounds().height - 15.f); AddComponent(hitbox_component); } @@ -66,7 +64,7 @@ public: int main(int argc, char *argv[]) { simpleengine::Game game(700, 700, "SimpleEngine - Animation Example"); - game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique(game.GetWindow()->getSize()))); + game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique(game.GetWindow()->getSize(), game))); return game.Run(); } \ No newline at end of file diff --git a/include/simpleengine/components/movement/movement_component.h b/include/simpleengine/components/movement/movement_component.h index 78ded8e..3fc76f3 100644 --- a/include/simpleengine/components/movement/movement_component.h +++ b/include/simpleengine/components/movement/movement_component.h @@ -13,17 +13,23 @@ namespace simpleengine { class Entity; + class Game; class MovementComponent : public Component { 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 Update(const float& delta_time) override; const sf::Vector2f& GetVelocity() const; const sf::Vector2f& GetLastDirection() const; private: + sf::Vector2f direction; float max_velocity; sf::Vector2f velocity; sf::Vector2f last_direction; diff --git a/include/simpleengine/components/ssma_component.h b/include/simpleengine/components/ssma_component.h index 30d0b6d..5e4ffb8 100644 --- a/include/simpleengine/components/ssma_component.h +++ b/include/simpleengine/components/ssma_component.h @@ -27,7 +27,7 @@ namespace simpleengine { // Use this for side scrollers! class SideScrollerMovementAnimationComponent : public Component { 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); void SetAnimation(const MovementAnimationType& type, simpleengine::Animation animation); diff --git a/src/components/collision_component.cpp b/src/components/collision_component.cpp index b6c778d..a67423e 100644 --- a/src/components/collision_component.cpp +++ b/src/components/collision_component.cpp @@ -12,7 +12,7 @@ #include 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.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 // the offset to the origin if the entity has the SSMA component. - if (owning_entity.HasComponent()) { - offset_x += dynamic_cast(transformable).getGlobalBounds().width * -0.5f; + if (auto ssma_comp = owning_entity.GetComponent(); ssma_comp) { + offset_x += ssma_comp->GetAnimationComponent().GetSprite().getGlobalBounds().width * -0.5f; } } diff --git a/src/components/movement/movement_component.cpp b/src/components/movement/movement_component.cpp index d794ea2..ef5e684 100644 --- a/src/components/movement/movement_component.cpp +++ b/src/components/movement/movement_component.cpp @@ -6,12 +6,22 @@ #include "components/movement/movement_component.h" #include "entity.h" +#include "game.h" +#include #include -simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, float max_velocity, float acceleration, float deceleration) : +#include + +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) { + game.AddEventCallback(std::function([this](sf::Event::KeyEvent event) { + this->OnKeyPress(event); + })); + game.AddEventCallback(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) { @@ -45,85 +55,104 @@ void simpleengine::MovementComponent::Move(const float& delta_time, const float& 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) { - 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. 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 > 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; + 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) { - 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; - + velocity.x = 0; } + + owning_entity.Move(velocity * delta_time); + no_movement = false; } + if (direction.x != 0 || direction.y != 0) { last_direction = direction; diff --git a/src/components/ssma_component.cpp b/src/components/ssma_component.cpp index c44a639..84d5c8a 100644 --- a/src/components/ssma_component.cpp +++ b/src/components/ssma_component.cpp @@ -6,10 +6,10 @@ #include "components/ssma_component.h" -simpleengine::SideScrollerMovementAnimationComponent::SideScrollerMovementAnimationComponent(simpleengine::Entity &owning_entity, - sf::Sprite &sprite, sf::Texture &texture_sheet, float max_velocity, float acceleration, float deceleration) +simpleengine::SideScrollerMovementAnimationComponent::SideScrollerMovementAnimationComponent(simpleengine::Entity &owning_entity, + 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), - 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, @@ -62,7 +62,7 @@ void simpleengine::SideScrollerMovementAnimationComponent::Update(const float& d anim.Update(delta_time); } } 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 (anim_component.HasAnimation("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"); 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 { - // If the user never set a IDLE_LEFT animation, then we need to flip the IDLE_RIGHT one. - if (anim_component.HasAnimation("IDLE_LEFT")) { // Facing left + // If the user never set an IDLE_LEFT animation, then we need to flip the IDLE_RIGHT one. + if (anim_component.HasAnimation("IDLE_LEFT")) { Animation& anim = anim_component.GetAnimation("IDLE_LEFT"); if (anim.IsHorizontallyFlipped()) { anim.FlipHorizontally();