diff --git a/CMakeLists.txt b/CMakeLists.txt index 91817cc7..5b75620d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,10 @@ set(SOURCES sources/Component/Renderer/CameraComponent.hpp sources/System/Renderer/Render2DScreenSystem.cpp sources/System/Renderer/Render2DScreenSystem.hpp + sources/Component/Animation/AnimationsComponent.cpp + sources/Component/Animation/AnimationsComponent.hpp + sources/System/Animation/AnimationsSystem.cpp + sources/System/Animation/AnimationsSystem.hpp sources/Component/Collision/CollisionComponent.cpp sources/Component/Collision/CollisionComponent.hpp sources/System/Collision/CollisionSystem.hpp @@ -70,7 +74,8 @@ set(SOURCES add_executable(bomberman sources/main.cpp - ${SOURCES}) + ${SOURCES} + ) target_include_directories(bomberman PUBLIC sources) target_link_libraries(bomberman PUBLIC wal ray) @@ -81,9 +86,9 @@ add_executable(unit_tests EXCLUDE_FROM_ALL tests/MainTest.cpp tests/EngineTests.cpp tests/CallbackTest.cpp - tests/CollisionTest.cpp tests/MoveTests.cpp -) + tests/CollisionTest.cpp + ) target_include_directories(unit_tests PUBLIC sources) target_link_libraries(unit_tests PUBLIC wal ray) diff --git a/README.md b/README.md index 18e93e7a..0d19b943 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,13 @@ mkdir build cd build cmake .. cmake --build . +cd - ``` Enjoy ! ```bash -./bomberman +./build/bomberman ``` diff --git a/lib/Ray/sources/Model/ModelAnimations.cpp b/lib/Ray/sources/Model/ModelAnimations.cpp index 0bd88c03..6d41832d 100644 --- a/lib/Ray/sources/Model/ModelAnimations.cpp +++ b/lib/Ray/sources/Model/ModelAnimations.cpp @@ -10,12 +10,13 @@ RAY::Cache<::ModelAnimation> RAY::ModelAnimations::_animationsCache(LoadModelAnimations, UnloadModelAnimations); RAY::ModelAnimations::ModelAnimations(const std::string &filePath): - _animationsPtr(_animationsCache.fetch(filePath, &this->_animationCount)) + _animationsPtr(_animationsCache.fetch(filePath, &this->_animationCount)), + _filePath(filePath) { ::ModelAnimation *ptr = this->_animationsPtr.get(); for (int i = 0; i < this->_animationCount; i++) - this->_animations.push_back(RAY::ModelAnimation(ptr[i])); + this->_animations.emplace_back(ptr[i]); } RAY::ModelAnimation &RAY::ModelAnimations::operator[](int index) @@ -28,3 +29,22 @@ size_t RAY::ModelAnimations::getAnimationsCount() const return this->_animationCount; } +std::string RAY::ModelAnimations::getFilePath() const +{ + return this->_filePath; +} + +const RAY::ModelAnimation &RAY::ModelAnimations::at(int index) const +{ + return this->_animations.at(index); +} + +const RAY::ModelAnimation &RAY::ModelAnimations::operator[](int index) const +{ + return this->_animations[index]; +} + +RAY::ModelAnimation &RAY::ModelAnimations::at(int index) +{ + return this->_animations.at(index); +} diff --git a/lib/Ray/sources/Model/ModelAnimations.hpp b/lib/Ray/sources/Model/ModelAnimations.hpp index ba46a0e4..2b99e1d7 100644 --- a/lib/Ray/sources/Model/ModelAnimations.hpp +++ b/lib/Ray/sources/Model/ModelAnimations.hpp @@ -21,21 +21,33 @@ namespace RAY { //! @param filePath Path to the file containing animations ModelAnimations(const std::string &filePath); - //! @brief Only single entity can hold these animations pointers - ModelAnimations(const ModelAnimations &) = delete; + //! @brief default copy ctor + ModelAnimations(const ModelAnimations &) = default; //! @brief Default constructor ~ModelAnimations() = default; - //! @brief Only single entity can hold these animations pointers - ModelAnimations &operator=(const ModelAnimations &) = delete; + //! @brief Default assignment operator + ModelAnimations &operator=(const ModelAnimations &) = default; //! @brief Castin Object to raw model animation pointer ModelAnimation &operator[](int index); + //! @brief std [] const + const ModelAnimation &operator[](int index) const; + + //! @brief std at const + const ModelAnimation &at(int index) const; + + //! @brief std at + ModelAnimation &at(int index); + //! @return the number of loaded animations size_t getAnimationsCount() const; + //! @brief Get the creation file + std::string getFilePath() const; + private: //! @brief Holds the pointer returned by the loading function std::shared_ptr<::ModelAnimation> _animationsPtr; @@ -46,6 +58,9 @@ namespace RAY { //! @brief the number of loaded animations int _animationCount; + //! @brief The file where the animations were loaded (used to create a copy of this class) + const std::string _filePath; + static Cache<::ModelAnimation> _animationsCache; }; } diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp index f30fa3ff..7f041853 100644 --- a/lib/Ray/sources/Utils/Cache.hpp +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -60,13 +60,17 @@ namespace RAY { {}; std::shared_ptr<::ModelAnimation> fetch(const std::string &path, int *counter) { - if (this->_cache.find(path) == this->_cache.end()) - this->_cache.emplace(path, std::shared_ptr<::ModelAnimation>( - this->_dataLoader(path.c_str(), counter), [this, counter](::ModelAnimation *p) { - this->_dataUnloader(p, *counter); - delete p; - })); - return _cache[path]; + if (this->_cache.find(path) != this->_cache.end()) + return this->_cache[path]; + + ::ModelAnimation *animations = this->_dataLoader(path.c_str(), counter); + unsigned int animCount = *counter; + + this->_cache.emplace(path, std::shared_ptr<::ModelAnimation>( + animations, [this, animCount](::ModelAnimation *p) { + this->_dataUnloader(p, animCount); + })); + return this->_cache[path]; }; private: //! @brief function to call to load data diff --git a/sources/Component/Animation/AnimationsComponent.cpp b/sources/Component/Animation/AnimationsComponent.cpp new file mode 100644 index 00000000..4461cc8e --- /dev/null +++ b/sources/Component/Animation/AnimationsComponent.cpp @@ -0,0 +1,71 @@ +// +// Created by cbihan on 01/06/2021. +// + +#include "AnimationsComponent.hpp" +#include "Entity/Entity.hpp" +#include "Model/ModelAnimations.hpp" + +namespace BBM +{ + AnimationsComponent::AnimationsComponent(WAL::Entity &entity, RAY::ModelAnimations modelAnimation, int animIndex, bool play) + : WAL::Component(entity), + _modelAnimation(std::move(modelAnimation)), + _currentAnimIndex(animIndex), + _animDisabled(play) + { + this->_modelAnimation[this->_currentAnimIndex].setFrameCounter(0); + } + + WAL::Component *AnimationsComponent::clone(WAL::Entity &entity) const + { + return new AnimationsComponent(entity, + RAY::ModelAnimations(this->_modelAnimation.getFilePath()), + this->_currentAnimIndex); + } + + size_t AnimationsComponent::getCurrentAnimFrameCounter() const + { + return this->_modelAnimation.at(this->_currentAnimIndex).getFrameCounter(); + } + + RAY::ModelAnimation AnimationsComponent::getCurrentModelAnim() + { + return this->_modelAnimation[this->_currentAnimIndex]; + } + + void AnimationsComponent::setCurrentAnimFrameCounter(size_t animFrameCounter) + { + this->_modelAnimation[this->_currentAnimIndex].setFrameCounter(animFrameCounter); + } + + void AnimationsComponent::resetCurrentAnimFrameCounter() + { + this->_modelAnimation[this->_currentAnimIndex].setFrameCounter(0); + } + + size_t AnimationsComponent::getCurrentAnimIndex() const + { + return this->_currentAnimIndex; + } + + void AnimationsComponent::setAnimIndex(int animIndex) + { + this->_currentAnimIndex = animIndex % static_cast(this->_modelAnimation.getAnimationsCount()); + } + + void AnimationsComponent::incCurrentAnimFrameCounter() + { + this->_modelAnimation[this->_currentAnimIndex].incrementFrameCounter(); + } + + void AnimationsComponent::setAnimDisabled(bool disable) + { + this->_animDisabled = disable; + } + + bool AnimationsComponent::isAnimDisabled() const + { + return this->_animDisabled; + } +} \ No newline at end of file diff --git a/sources/Component/Animation/AnimationsComponent.hpp b/sources/Component/Animation/AnimationsComponent.hpp new file mode 100644 index 00000000..463f241f --- /dev/null +++ b/sources/Component/Animation/AnimationsComponent.hpp @@ -0,0 +1,63 @@ +// +// Created by cbihan on 01/06/2021. +// + +#pragma once + +#include +#include +#include +#include + +namespace BBM +{ + class AnimationsComponent : public WAL::Component + { + private: + //! @brief To get the animation data + RAY::ModelAnimations _modelAnimation; + //! @brief The index of the + int _currentAnimIndex; + //! @brief Bool allowing to play pause an animation + bool _animDisabled; + public: + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief get the current animation index + size_t getCurrentAnimIndex() const; + + //! @brief Set the animation index to use + void setAnimIndex(int animIndex); + + //! @brief get animation frame counter + size_t getCurrentAnimFrameCounter() const; + + //! @brief get the current + RAY::ModelAnimation getCurrentModelAnim(); + + //! @brief set the anim frame counter + void setCurrentAnimFrameCounter(size_t animFrameCounter); + + //! @brief Set the internal anim counter to 0 + void resetCurrentAnimFrameCounter(); + + //! @brief Increment the internal anim counter + void incCurrentAnimFrameCounter(); + + //! @brief Allow to play pause animations + void setAnimDisabled(bool disable); + + //! @brief To know if the animation will be updated or not + bool isAnimDisabled() const; + + //! @brief ctor entity and the path of the animation file + explicit AnimationsComponent(WAL::Entity &entity, RAY::ModelAnimations modelAnimation, int animIndex, bool play = true); + //! @brief copy ctor + AnimationsComponent(const AnimationsComponent &) = default; + //! @brief dtor + ~AnimationsComponent() override = default; + //! @brief assignment operator + AnimationsComponent &operator=(const AnimationsComponent &) = delete; + }; +} diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index db3896c9..8b1f36fd 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -25,6 +25,9 @@ #include "Component/Renderer/CameraComponent.hpp" #include "Runner.hpp" #include "Models/GameState.hpp" +#include +#include "Component/Animation/AnimationsComponent.hpp" +#include "System/Animation/AnimationsSystem.hpp" #include "Map/Map.hpp" namespace RAY2D = RAY::Drawables::Drawables2D; @@ -58,6 +61,7 @@ namespace BBM wal.addSystem>(); wal.addSystem>(); + wal.addSystem(); wal.addSystem(window) .addSystem>(); @@ -72,6 +76,7 @@ namespace BBM .addComponent>("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) .addComponent() .addComponent() + .addComponent(RAY::ModelAnimations("assets/player/player.iqm"), 1) .addComponent(2) .addComponent(); scene->addEntity("cube") @@ -86,7 +91,7 @@ namespace BBM mov.resetVelocity(); } catch (std::exception &e) { }; }, 3); - + scene->addEntity("camera") .addComponent(8, 20, 7) .addComponent(Vector3f(8, 0, 8)); diff --git a/sources/System/Animation/AnimationsSystem.cpp b/sources/System/Animation/AnimationsSystem.cpp new file mode 100644 index 00000000..3400cf10 --- /dev/null +++ b/sources/System/Animation/AnimationsSystem.cpp @@ -0,0 +1,32 @@ +// +// Created by cbihan on 01/06/2021. +// + +#include +#include "AnimationsSystem.hpp" +#include "Component/Animation/AnimationsComponent.hpp" +#include "Model/Model.hpp" +#include "Component/Renderer/Drawable3DComponent.hpp" + +namespace BBM +{ + + AnimationsSystem::AnimationsSystem() + : WAL::System({ + typeid(Drawable3DComponent), + typeid(AnimationsComponent) + }) + { + } + + void AnimationsSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) + { + auto &model = entity.getComponent>(); + auto &anim = entity.getComponent(); + + if (anim.isDisabled()) + return; + model.member.setAnimation(anim.getCurrentModelAnim()); + anim.incCurrentAnimFrameCounter(); + } +} \ No newline at end of file diff --git a/sources/System/Animation/AnimationsSystem.hpp b/sources/System/Animation/AnimationsSystem.hpp new file mode 100644 index 00000000..fb08b2ef --- /dev/null +++ b/sources/System/Animation/AnimationsSystem.hpp @@ -0,0 +1,26 @@ +// +// Created by cbihan on 01/06/2021. +// + +#pragma once + +#include + +namespace BBM +{ + class AnimationsSystem : public WAL::System + { + public: + //! @inherit + void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) override; + + //! @brief A default constructor + AnimationsSystem(); + //! @brief A Controllable system is copy constructable + AnimationsSystem(const AnimationsSystem &) = default; + //! @brief A default destructor + ~AnimationsSystem() override = default; + //! @brief A Controllable system is assignable. + AnimationsSystem &operator=(const AnimationsSystem &) = default; + }; +} \ No newline at end of file diff --git a/sources/System/Controllable/ControllableSystem.cpp b/sources/System/Controllable/ControllableSystem.cpp index 0a9c789c..41c54895 100644 --- a/sources/System/Controllable/ControllableSystem.cpp +++ b/sources/System/Controllable/ControllableSystem.cpp @@ -10,8 +10,6 @@ namespace BBM { - float ControllableSystem::speed = .25f; - ControllableSystem::ControllableSystem() : WAL::System({ typeid(ControllableComponent), diff --git a/sources/System/Controllable/ControllableSystem.hpp b/sources/System/Controllable/ControllableSystem.hpp index fac4db08..ec6eef9d 100644 --- a/sources/System/Controllable/ControllableSystem.hpp +++ b/sources/System/Controllable/ControllableSystem.hpp @@ -14,7 +14,7 @@ namespace BBM { public: //! @brief The speed applied to every controllable entities. - static float speed; + static constexpr const float speed = .25f; //! @inherit void onFixedUpdate(WAL::Entity &entity) override;