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:
sf::Sprite sprite;
sf::Texture texture;
float movement_speed = 130;
float movement_speed = 50;
sf::Vector2u window_size;
// Components:
// Components
std::shared_ptr<simpleengine::CollisionComponent> hitbox_component;
std::shared_ptr<simpleengine::SideScrollerMovementAnimationComponent> 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<simpleengine::SideScrollerMovementAnimationComponent>(*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<simpleengine::SideScrollerMovementAnimationComponent>(*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<simpleengine::CollisionComponent>(*this, sprite,
20.f, 12.f, sprite.getGlobalBounds().width - 40.f, sprite.getGlobalBounds().height - 15.f);
hitbox_component = std::make_shared<simpleengine::CollisionComponent>(*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<PlayerEntity>(game.GetWindow()->getSize())));
game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique<PlayerEntity>(game.GetWindow()->getSize(), game)));
return game.Run();
}

View File

@ -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;

View File

@ -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);

View File

@ -12,7 +12,7 @@
#include <ostream>
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<simpleengine::SideScrollerMovementAnimationComponent>()) {
offset_x += dynamic_cast<sf::RectangleShape&>(transformable).getGlobalBounds().width * -0.5f;
if (auto ssma_comp = owning_entity.GetComponent<simpleengine::SideScrollerMovementAnimationComponent>(); ssma_comp) {
offset_x += ssma_comp->GetAnimationComponent().GetSprite().getGlobalBounds().width * -0.5f;
}
}

View File

@ -6,12 +6,22 @@
#include "components/movement/movement_component.h"
#include "entity.h"
#include "game.h"
#include <SFML/Window/Keyboard.hpp>
#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) {
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) {
@ -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;

View File

@ -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();