From dd919bf89e65b5777879a98fc8b19e7b49df7e1a Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sun, 5 Jul 2020 01:28:23 -0500 Subject: [PATCH] Create AnimationComponent, and an example to show it --- examples/CMakeLists.txt | 3 +- examples/animation/CMakeLists.txt | 15 ++++ examples/animation/src/main.cpp | 73 +++++++++++++++++++ include/simpleengine/animation.h | 38 ++++++++++ .../components/animation_component.h | 41 +++++++++++ include/simpleengine/entity.h | 4 - src/animation.cpp | 43 +++++++++++ src/components/animation_component.cpp | 48 ++++++++++++ 8 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 examples/animation/CMakeLists.txt create mode 100644 examples/animation/src/main.cpp create mode 100644 include/simpleengine/animation.h create mode 100644 include/simpleengine/components/animation_component.h create mode 100644 src/animation.cpp create mode 100644 src/components/animation_component.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a741a75..7916283 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,2 +1,3 @@ # Add examples as a subdirectory -add_subdirectory(snake) \ No newline at end of file +add_subdirectory(snake) +add_subdirectory(animation) \ No newline at end of file diff --git a/examples/animation/CMakeLists.txt b/examples/animation/CMakeLists.txt new file mode 100644 index 0000000..f33cca9 --- /dev/null +++ b/examples/animation/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required (VERSION 3.6) +project(AnimationExample) + +add_executable(animation_example src/main.cpp) + +# Link headers and source files. +file(GLOB_RECURSE source_list src/*.cpp) +target_sources(animation_example PRIVATE ${source_list}) +target_include_directories(animation_example PUBLIC include) + +# Link simpleengine +target_link_libraries(animation_example PUBLIC simpleengine) + +# Set standard to C++17 +set_target_properties(animation_example PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF) \ No newline at end of file diff --git a/examples/animation/src/main.cpp b/examples/animation/src/main.cpp new file mode 100644 index 0000000..1ac3c88 --- /dev/null +++ b/examples/animation/src/main.cpp @@ -0,0 +1,73 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +class PlayerEntity : public simpleengine::Entity { +private: + sf::Sprite sprite; + sf::Texture texture; + float movement_speed = 95; + sf::Vector2u window_size; + + std::unique_ptr anim_component; +public: + explicit PlayerEntity(sf::Vector2u window_size) : window_size(window_size) { + AddComponent(std::make_unique(*this, movement_speed)); + + texture.loadFromFile("player_sheet.png"); + sprite.setTexture(texture); + + anim_component = std::make_unique(*this, sprite, texture); + anim_component->AddAnimation("IDLE_LEFT", 20, 0, 0, 6, 0, 128, 128); + anim_component->AddAnimation("WALK_LEFT_NO_SWORD", 9, 0, 8, 9, 8, 128, 128); + } + + ~PlayerEntity() override { + std::cout << "Destroying" << std::endl; + + simpleengine::Entity::~Entity(); + } + + void Move(const float& delta_time, const float& x, const float& y) override { + sprite.move(x, y); + } + + void Move(const float& delta_time, const sf::Vector2f& offset) override { + sprite.move(offset * delta_time); + } + + void Move(const sf::Vector2f& offset) override { + sprite.move(offset); + } + + void Update(const float& delta_time) override { + Entity::Update(delta_time); + + //anim_component->PlayAnimation("IDLE_LEFT", delta_time); + anim_component->PlayAnimation("WALK_LEFT_NO_SWORD", delta_time); + } + + void Render(sf::RenderTarget* target) override { + target->draw(sprite); + } +}; + +int main(int argc, char *argv[]) { + simpleengine::Game game(500, 500, "SimpleEngine - Animation Example"); + game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique(game.GetWindow()->getSize()))); + + return game.Run(); +} \ No newline at end of file diff --git a/include/simpleengine/animation.h b/include/simpleengine/animation.h new file mode 100644 index 0000000..afdd23b --- /dev/null +++ b/include/simpleengine/animation.h @@ -0,0 +1,38 @@ +// +// Created by SeanOMik on 7/5/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#ifndef SIMPLEENGINE_ANIMATION_H +#define SIMPLEENGINE_ANIMATION_H + +#include + +namespace simpleengine { + class Animation { + public: + Animation(sf::Sprite &sprite, sf::Texture &texture_sheet, float speed, int start_frame_x, + int start_frame_y, int frame_ct_x, int frame_ct_y, int width, int height); + + void Update(const float &delta_time); + void Reset(); + + /*void Play(); + void Pause();*/ + + private: + sf::Sprite &sprite; + sf::Texture &texture_sheet; + float speed; // Speed is how long it takes until it swaps to next texture. + float timer; + int width; + int height; + sf::IntRect start_rect; + sf::IntRect current_rect; + sf::IntRect end_rect; + + }; +} + +#endif //SIMPLEENGINE_ANIMATION_H diff --git a/include/simpleengine/components/animation_component.h b/include/simpleengine/components/animation_component.h new file mode 100644 index 0000000..b4d562b --- /dev/null +++ b/include/simpleengine/components/animation_component.h @@ -0,0 +1,41 @@ +// +// Created by SeanOMik on 7/4/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#ifndef SIMPLEENGINE_ANIMATION_COMPONENT_H +#define SIMPLEENGINE_ANIMATION_COMPONENT_H + +#include "../component.h" +#include "../animation.h" + +#include + +namespace simpleengine { + class Entity; + + class AnimationComponent : public Component { + private: + + sf::Sprite& sprite; + sf::Texture& texture_sheet; + std::map animations; + + public: + explicit AnimationComponent(Entity& owning_entity, sf::Sprite& sprite, sf::Texture& texture_sheet); + + void Update(const float &delta_time) override; + + void AddAnimation(const std::string& animation_name, float speed, int start_frame_x, int start_frame_y, int frame_ct_x, + int frame_ct_y, int width, int height); + void AddAnimation(const std::string& animation_name, simpleengine::Animation animation); + void UpdateAnimation(const std::string& animation_name, const float& delta_time); + + sf::Sprite &GetSprite() const; + sf::Texture &GetTextureSheet() const; + const std::map &GetAnimations() const; + }; +} + +#endif //SIMPLEENGINE_ANIMATION_COMPONENT_H \ No newline at end of file diff --git a/include/simpleengine/entity.h b/include/simpleengine/entity.h index 05b180d..0e4322e 100644 --- a/include/simpleengine/entity.h +++ b/include/simpleengine/entity.h @@ -43,10 +43,6 @@ namespace simpleengine { void UpdateComponents(const float& delta_time); void AddComponent(std::unique_ptr component); - - std::shared_ptr GetShared() { - return shared_from_this(); - } protected: std::vector> components; bool destroying = false; diff --git a/src/animation.cpp b/src/animation.cpp new file mode 100644 index 0000000..0d6e942 --- /dev/null +++ b/src/animation.cpp @@ -0,0 +1,43 @@ +// +// Created by SeanOMik on 7/5/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include "animation.h" + +simpleengine::Animation::Animation(sf::Sprite &sprite, sf::Texture &texture_sheet, float speed, int start_frame_x, + int start_frame_y, int frame_ct_x, int frame_ct_y, int width, int height) : sprite(sprite), texture_sheet(texture_sheet), + speed(speed), start_rect(sf::IntRect(start_frame_x * width, start_frame_y * height, width, height)), + end_rect(sf::IntRect(frame_ct_x * width, frame_ct_y * height, width, height)), width(width), height(height) { + + timer = 0; + + // Set start of sprite. + this->sprite.setTexture(texture_sheet, true); + this->sprite.setTextureRect(start_rect); + this->current_rect = start_rect; +} + +void simpleengine::Animation::Update(const float &delta_time) { + // Update timer + timer += 100 * delta_time; + if (timer >= speed) { + // Reset animation + timer = 0; + + // We have not reached the end, so change the texture. + if (current_rect != end_rect) { + current_rect.left += width; + } else { + current_rect.left = start_rect.left; + } + + sprite.setTextureRect(current_rect); + } +} + +void simpleengine::Animation::Reset() { + timer = 0; + current_rect = start_rect; +} diff --git a/src/components/animation_component.cpp b/src/components/animation_component.cpp new file mode 100644 index 0000000..e523548 --- /dev/null +++ b/src/components/animation_component.cpp @@ -0,0 +1,48 @@ +// +// Created by SeanOMik on 7/4/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include "components/animation_component.h" +#include "animation.h" + +simpleengine::AnimationComponent::AnimationComponent(Entity& owning_entity, sf::Sprite& sprite, sf::Texture& texture_sheet) + : Component(owning_entity), sprite(sprite), texture_sheet(texture_sheet) { + +} + +void simpleengine::AnimationComponent::Update(const float &delta_time) { + +} + +void simpleengine::AnimationComponent::AddAnimation(const std::string& animation_name, float speed, int start_frame_x, int start_frame_y, int frame_ct_x, + int frame_ct_y, int width, int height) { + + animations.emplace(animation_name, Animation(sprite, texture_sheet, speed, start_frame_x, start_frame_y, frame_ct_x, frame_ct_y, width, height)); +} + +void simpleengine::AnimationComponent::AddAnimation(const std::string& animation_name, simpleengine::Animation animation) { + animations.emplace(animation_name, animation); +} + +void simpleengine::AnimationComponent::UpdateAnimation(const std::string &animation_name, const float &delta_time) { + auto anim = animations.find(animation_name); + if (anim != animations.end()) { + anim->second.Update(delta_time); + } else { + throw std::runtime_error("Animation, \"" + animation_name + "\", was not found!"); + } +} + +sf::Sprite &simpleengine::AnimationComponent::GetSprite() const { + return sprite; +} + +sf::Texture &simpleengine::AnimationComponent::GetTextureSheet() const { + return texture_sheet; +} + +const std::map &simpleengine::AnimationComponent::GetAnimations() const { + return animations; +}