From 43bd781175ad1f8363fcb706a4347714dff3679a Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 31 May 2021 16:18:24 +0200 Subject: [PATCH 01/14] Adding a bomb holder system --- CMakeLists.txt | 2 +- .../BombHolder/BombHolderComponent.cpp | 19 +------ .../BombHolder/BombHolderComponent.hpp | 29 ++++------ sources/Runner/Runner.cpp | 30 ++++++----- .../System/BombHolder/BombHolderSystem.cpp | 53 +++++++++++++++++++ .../System/BombHolder/BombHolderSystem.hpp | 34 ++++++++++++ sources/System/Keyboard/KeyboardSystem.cpp | 5 +- sources/System/Keyboard/KeyboardSystem.hpp | 2 +- 8 files changed, 121 insertions(+), 53 deletions(-) create mode 100644 sources/System/BombHolder/BombHolderSystem.cpp create mode 100644 sources/System/BombHolder/BombHolderSystem.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2371cd9e..9ff217e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ set(SOURCES sources/Component/Renderer/CameraComponent.hpp sources/System/Renderer/Render2DScreenSystem.cpp sources/System/Renderer/Render2DScreenSystem.hpp -) + sources/System/BombHolder/BombHolderSystem.cpp sources/System/BombHolder/BombHolderSystem.hpp) add_executable(bomberman sources/main.cpp diff --git a/sources/Component/BombHolder/BombHolderComponent.cpp b/sources/Component/BombHolder/BombHolderComponent.cpp index 031dab8b..bff44867 100644 --- a/sources/Component/BombHolder/BombHolderComponent.cpp +++ b/sources/Component/BombHolder/BombHolderComponent.cpp @@ -9,31 +9,16 @@ namespace BBM { BombHolderComponent::BombHolderComponent(WAL::Entity &entity) - : WAL::Component(entity), - _bombCount() + : WAL::Component(entity) {} BombHolderComponent::BombHolderComponent(WAL::Entity &entity, unsigned int maxBombCount) : WAL::Component(entity), - _bombCount(), - _maxBombCount(maxBombCount) + maxBombCount(maxBombCount) {} WAL::Component *BombHolderComponent::clone(WAL::Entity &entity) const { return new BombHolderComponent(entity); } - - void BombHolderComponent::addBomb(unsigned int bombCount) - { - this->_bombCount += bombCount; - } - - void BombHolderComponent::removeBomb(unsigned int damage) - { - if (damage >= this->_bombCount) { - this->_bombCount = 0; - } else - this->_bombCount -= damage; - } } \ No newline at end of file diff --git a/sources/Component/BombHolder/BombHolderComponent.hpp b/sources/Component/BombHolder/BombHolderComponent.hpp index 049fd56c..b35e9620 100644 --- a/sources/Component/BombHolder/BombHolderComponent.hpp +++ b/sources/Component/BombHolder/BombHolderComponent.hpp @@ -8,30 +8,23 @@ #include "Component/Component.hpp" #include "Entity/Entity.hpp" +#include + +using namespace std::chrono_literals; namespace BBM { class BombHolderComponent : public WAL::Component { - - private: - //! @brief bomb count of an entity - unsigned int _bombCount; - //! @brief max bomb count of an entity - unsigned int _maxBombCount; - public: - //! @brief add bomb to the entity - void addBomb(unsigned int bombCount); - - //! @brief add bomb bax of the entity - void addMaxBombCount(unsigned int maxBombCount); - - //! @brief reduce bomb max of the entity - void removeMaxBombCount(unsigned int bombCount); - - //! @brief reduce bomb - void removeBomb(unsigned int bombCount); + //! @brief The number of bomb that this entity hold. + unsigned int bombCount = 1; + //! @brief The max number of bomb that this entity can have. + unsigned int maxBombCount = 3; + //! @brief The number of seconds of each refill. This variable is used to reset the nextBombRefill value. + std::chrono::nanoseconds refillRate = 5000ns; + //! @brief The number of nanosecond before the next bomb refill. + std::chrono::nanoseconds nextBombRefill = refillRate; //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index c6a6c196..a8a321fa 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -4,20 +4,22 @@ #include #include -#include -#include -#include -#include +#include "System/Movable/MovableSystem.hpp" +#include "System/Renderer/RenderScreenSystem.hpp" +#include "System/Renderer/Render2DScreenSystem.hpp" +#include "System/Renderer/Renderer2DSystem.hpp" #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include "Component/BombHolder/BombHolderComponent.hpp" +#include "System/BombHolder/BombHolderSystem.hpp" +#include "System/Renderer/Renderer3DSystem.hpp" +#include "System/Keyboard/KeyboardSystem.hpp" +#include "System/Controllable/ControllableSystem.hpp" +#include "Component/Movable/MovableComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Component/Keyboard/KeyboardComponent.hpp" +#include "System/Gamepad/GamepadSystem.hpp" #include "Models/Vector2.hpp" #include "Component/Renderer/CameraComponent.hpp" #include "Runner.hpp" @@ -43,6 +45,7 @@ namespace BBM wal.addSystem() .addSystem() .addSystem() + .addSystem(wal) .addSystem(); } @@ -66,13 +69,14 @@ namespace BBM .addComponent>(Vector2f(), Vector2f(10, 10), RED) .addComponent() .addComponent() - .addComponent();; + .addComponent(); scene->addEntity("player") .addComponent() .addComponent>("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) .addComponent() .addComponent() - .addComponent(); + .addComponent() + .addComponent(); scene->addEntity("camera") .addComponent(0, 20, -5) .addComponent(); diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp new file mode 100644 index 00000000..1132c3be --- /dev/null +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -0,0 +1,53 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#include "Component/Renderer/Drawable3DComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "BombHolderSystem.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/BombHolder/BombHolderComponent.hpp" + +using namespace std::chrono_literals; +namespace RAY3D = RAY::Drawables::Drawables3D; + +namespace BBM +{ + BombHolderSystem::BombHolderSystem(WAL::Wal &wal) + : WAL::System({ + typeid(PositionComponent), + typeid(BombHolderComponent), + typeid(ControllableComponent) + }), + _wal(wal) + {} + + void BombHolderSystem::_spawnBomb(Vector3f position) + { + this->_wal.scene->addEntity("Bomb") + .addComponent(position) + .addComponent>("assets/bombs/bomb.obj", + std::make_pair(MAP_DIFFUSE, "assets/bombs/bomb_normal.png")); + } + + void BombHolderSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) + { + auto &holder = entity.getComponent(); + auto &position = entity.getComponent(); + auto &controllable = entity.getComponent(); + + if (holder.bombCount < holder.maxBombCount) { + holder.nextBombRefill -= dtime; + if (holder.nextBombRefill <= 0ns) { + holder.nextBombRefill = holder.refillRate; + holder.bombCount++; + std::cout << "Count: " << holder.bombCount << std::endl; + } + } + if (controllable.bomb && holder.bombCount > 0) { + holder.bombCount--; + std::cout << "Now" << std::endl; + this->_spawnBomb(position.position); + } + } +} \ No newline at end of file diff --git a/sources/System/BombHolder/BombHolderSystem.hpp b/sources/System/BombHolder/BombHolderSystem.hpp new file mode 100644 index 00000000..1241c9d9 --- /dev/null +++ b/sources/System/BombHolder/BombHolderSystem.hpp @@ -0,0 +1,34 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#pragma once + +#include +#include +#include "Models/Vector3.hpp" + +namespace BBM +{ + //! @brief The system that allow one to place bombs. + class BombHolderSystem : public WAL::System + { + private: + //! @brief A reference to the engine to spawn new entities. + WAL::Wal &_wal; + //! @brief Spawn a bomb at the specified position. + void _spawnBomb(Vector3f position); + public: + //! @inherit + void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief A default constructor + explicit BombHolderSystem(WAL::Wal &wal); + //! @brief A bomb holder system is copy constructable + BombHolderSystem(const BombHolderSystem &) = default; + //! @brief A default destructor + ~BombHolderSystem() override = default; + //! @brief A bomb holder system is not assignable. + BombHolderSystem &operator=(const BombHolderSystem &) = delete; + }; +} diff --git a/sources/System/Keyboard/KeyboardSystem.cpp b/sources/System/Keyboard/KeyboardSystem.cpp index 13ad9804..a6c5963b 100644 --- a/sources/System/Keyboard/KeyboardSystem.cpp +++ b/sources/System/Keyboard/KeyboardSystem.cpp @@ -3,7 +3,6 @@ // Edited by Benjamin Henry on 2021-05-20. // -#include #include "KeyboardSystem.hpp" #include "Component/Keyboard/KeyboardComponent.hpp" #include "Component/Controllable/ControllableComponent.hpp" @@ -21,7 +20,7 @@ namespace BBM }) {} - void KeyboardSystem::onFixedUpdate(WAL::Entity &entity) + void KeyboardSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) { const auto &keyboard = entity.getComponent(); auto &controllable = entity.getComponent(); @@ -33,7 +32,7 @@ namespace BBM }; for (auto key : keyPressedMap) - key.second = Keyboard::isDown(key.first); + key.second = Keyboard::isPressed(key.first); controllable.move = Vector2f(); if (Keyboard::isDown(keyboard.keyRight)) controllable.move.x += 1; diff --git a/sources/System/Keyboard/KeyboardSystem.hpp b/sources/System/Keyboard/KeyboardSystem.hpp index f17c5f15..5aba771e 100644 --- a/sources/System/Keyboard/KeyboardSystem.hpp +++ b/sources/System/Keyboard/KeyboardSystem.hpp @@ -15,7 +15,7 @@ namespace BBM { public: //! @inherit - void onFixedUpdate(WAL::Entity &entity) override; + void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) override; //! @brief A default constructor KeyboardSystem(); From 8009c0619b0ad592e8f7b3ce8eb4eafe853b8bed Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 31 May 2021 17:00:46 +0200 Subject: [PATCH 02/14] Fixing refill times --- sources/Component/BombHolder/BombHolderComponent.hpp | 2 +- sources/System/BombHolder/BombHolderSystem.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sources/Component/BombHolder/BombHolderComponent.hpp b/sources/Component/BombHolder/BombHolderComponent.hpp index b35e9620..03906e84 100644 --- a/sources/Component/BombHolder/BombHolderComponent.hpp +++ b/sources/Component/BombHolder/BombHolderComponent.hpp @@ -22,7 +22,7 @@ namespace BBM //! @brief The max number of bomb that this entity can have. unsigned int maxBombCount = 3; //! @brief The number of seconds of each refill. This variable is used to reset the nextBombRefill value. - std::chrono::nanoseconds refillRate = 5000ns; + std::chrono::nanoseconds refillRate = 5000ms; //! @brief The number of nanosecond before the next bomb refill. std::chrono::nanoseconds nextBombRefill = refillRate; diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index 1132c3be..dc56b418 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -36,18 +36,16 @@ namespace BBM auto &position = entity.getComponent(); auto &controllable = entity.getComponent(); + if (controllable.bomb && holder.bombCount > 0) { + holder.bombCount--; + this->_spawnBomb(position.position); + } if (holder.bombCount < holder.maxBombCount) { holder.nextBombRefill -= dtime; if (holder.nextBombRefill <= 0ns) { holder.nextBombRefill = holder.refillRate; holder.bombCount++; - std::cout << "Count: " << holder.bombCount << std::endl; } } - if (controllable.bomb && holder.bombCount > 0) { - holder.bombCount--; - std::cout << "Now" << std::endl; - this->_spawnBomb(position.position); - } } } \ No newline at end of file From 44b68b15e643690f32de96cab3f91dcd89988f15 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 31 May 2021 17:19:23 +0200 Subject: [PATCH 03/14] Adding a timer component --- CMakeLists.txt | 2 +- sources/Component/Timer/TimerComponent.cpp | 32 +++++++++++++++++++ sources/Component/Timer/TimerComponent.hpp | 37 ++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 sources/Component/Timer/TimerComponent.cpp create mode 100644 sources/Component/Timer/TimerComponent.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ff217e8..0710a85a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ set(SOURCES sources/Component/Renderer/CameraComponent.hpp sources/System/Renderer/Render2DScreenSystem.cpp sources/System/Renderer/Render2DScreenSystem.hpp - sources/System/BombHolder/BombHolderSystem.cpp sources/System/BombHolder/BombHolderSystem.hpp) + sources/System/BombHolder/BombHolderSystem.cpp sources/System/BombHolder/BombHolderSystem.hpp sources/Component/Timer/TimerComponent.cpp sources/Component/Timer/TimerComponent.hpp) add_executable(bomberman sources/main.cpp diff --git a/sources/Component/Timer/TimerComponent.cpp b/sources/Component/Timer/TimerComponent.cpp new file mode 100644 index 00000000..09ad1f5b --- /dev/null +++ b/sources/Component/Timer/TimerComponent.cpp @@ -0,0 +1,32 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#include "TimerComponent.hpp" + +#include + +namespace BBM +{ + TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay) + : WAL::Component(entity), + ringIn(delay) + {} + + TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, const WAL::Callback &callback) + : WAL::Component(entity), + ringIn(delay), + callback(callback) + {} + + TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, std::function callback) + : WAL::Component(entity), + ringIn(delay), + callback(std::move(callback)) + {} + + WAL::Component *TimerComponent::clone(WAL::Entity &entity) const + { + return new TimerComponent(entity, this->ringIn, this->callback); + } +} \ No newline at end of file diff --git a/sources/Component/Timer/TimerComponent.hpp b/sources/Component/Timer/TimerComponent.hpp new file mode 100644 index 00000000..e6c005db --- /dev/null +++ b/sources/Component/Timer/TimerComponent.hpp @@ -0,0 +1,37 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#pragma once + +#include +#include +#include "Models/Callback.hpp" + +namespace BBM +{ + //! @brief + class TimerComponent : public WAL::Component + { + public: + //! @brief The callback to call when the timer ring. + WAL::Callback callback; + //! @brief The ring delay of this timer component. + std::chrono::nanoseconds ringIn; + + Component * clone(WAL::Entity &entity) const override; + + //! @brief A default constructor + TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay); + //! @brief Create a timer with a callback. + TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, const WAL::Callback &callback); + //! @brief Create a timer with a function to call on ring. + TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, std::function callback); + //! @brief A timer component is copy constructable + TimerComponent(const TimerComponent &) = default; + //! @brief A default destructor + ~TimerComponent() override = default; + //! @brief A component is not assignable. + TimerComponent &operator=(const TimerComponent &) = delete; + }; +} From 1cf2a9ee9fda1c96d5e76684f6bbf59c76df0d56 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 31 May 2021 17:28:56 +0200 Subject: [PATCH 04/14] Creating the timer system --- CMakeLists.txt | 14 +++++++++++--- sources/Runner/Runner.cpp | 4 +++- sources/System/Timer/TimerSystem.cpp | 27 +++++++++++++++++++++++++++ sources/System/Timer/TimerSystem.hpp | 26 ++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 sources/System/Timer/TimerSystem.cpp create mode 100644 sources/System/Timer/TimerSystem.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0710a85a..14240035 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,11 +56,18 @@ set(SOURCES sources/Component/Renderer/CameraComponent.hpp sources/System/Renderer/Render2DScreenSystem.cpp sources/System/Renderer/Render2DScreenSystem.hpp - sources/System/BombHolder/BombHolderSystem.cpp sources/System/BombHolder/BombHolderSystem.hpp sources/Component/Timer/TimerComponent.cpp sources/Component/Timer/TimerComponent.hpp) + sources/System/BombHolder/BombHolderSystem.cpp + sources/System/BombHolder/BombHolderSystem.hpp + sources/Component/Timer/TimerComponent.cpp + sources/Component/Timer/TimerComponent.hpp + sources/System/Timer/TimerSystem.cpp + sources/System/Timer/TimerSystem.hpp +) add_executable(bomberman sources/main.cpp - ${SOURCES}) + ${SOURCES} +) target_include_directories(bomberman PUBLIC sources) target_link_libraries(bomberman PUBLIC wal ray) @@ -71,7 +78,8 @@ add_executable(unit_tests EXCLUDE_FROM_ALL tests/MainTest.cpp tests/EngineTests.cpp tests/CallbackTest.cpp - tests/MoveTests.cpp) + tests/MoveTests.cpp +) target_include_directories(unit_tests PUBLIC sources) target_link_libraries(unit_tests PUBLIC wal ray) diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index a8a321fa..5f416812 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "System/Timer/TimerSystem.hpp" #include "Component/BombHolder/BombHolderComponent.hpp" #include "System/BombHolder/BombHolderSystem.hpp" #include "System/Renderer/Renderer3DSystem.hpp" @@ -42,7 +43,8 @@ namespace BBM void addSystems(WAL::Wal &wal) { - wal.addSystem() + wal.addSystem() + .addSystem() .addSystem() .addSystem() .addSystem(wal) diff --git a/sources/System/Timer/TimerSystem.cpp b/sources/System/Timer/TimerSystem.cpp new file mode 100644 index 00000000..e299549a --- /dev/null +++ b/sources/System/Timer/TimerSystem.cpp @@ -0,0 +1,27 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#include "TimerSystem.hpp" +#include "Component/Timer/TimerComponent.hpp" + +using namespace std::chrono_literals; + +namespace BBM +{ + TimerSystem::TimerSystem() + : WAL::System({ + typeid(TimerComponent) + }) + {} + + void TimerSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) + { + auto &timer = entity.getComponent(); + timer.ringIn -= dtime; + if (timer.ringIn <= 0ns) { + timer.setDisable(true); + timer.callback(entity); + } + } +} \ No newline at end of file diff --git a/sources/System/Timer/TimerSystem.hpp b/sources/System/Timer/TimerSystem.hpp new file mode 100644 index 00000000..a3cf8a2b --- /dev/null +++ b/sources/System/Timer/TimerSystem.hpp @@ -0,0 +1,26 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#pragma once + +#include + +namespace BBM +{ + class TimerSystem : public WAL::System + { + public: + //! @inherit + void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief A default constructor + TimerSystem(); + //! @brief A timer system is copy constructable. + TimerSystem(const TimerSystem &) = default; + //! @brief A default destructor + ~TimerSystem() override = default; + //! @breief A timer system is assignable. + TimerSystem &operator=(const TimerSystem &) = default; + }; +} From 334d7b32e20c47c2ef62a8df4f9ce0c98d616761 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 31 May 2021 17:38:50 +0200 Subject: [PATCH 05/14] Adding a should delete and handling disabled components --- lib/wal/sources/Entity/Entity.cpp | 28 +++++++++++++++++++++++----- lib/wal/sources/Entity/Entity.hpp | 21 +++++++++++++++------ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/lib/wal/sources/Entity/Entity.cpp b/lib/wal/sources/Entity/Entity.cpp index 56627a16..17ebd6c2 100644 --- a/lib/wal/sources/Entity/Entity.cpp +++ b/lib/wal/sources/Entity/Entity.cpp @@ -46,25 +46,43 @@ namespace WAL Entity &Entity::addComponent(const Component &component) { - if (this->hasComponent(typeid(component))) + if (this->hasComponent(typeid(component), false)) throw DuplicateError("A component of the type \"" + std::string(typeid(component).name()) + "\" already exists."); this->_components.emplace_back(component.clone(*this)); return *this; } - bool Entity::hasComponent(const std::type_info &type) const + bool Entity::hasComponent(const std::type_info &type, bool skipDisabled) const { auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { return typeid(*cmp) == type; }); - return existing != this->_components.end(); + if (existing == this->_components.end()) + return false; + if (skipDisabled) + return !(*existing)->isDisabled(); + return true; } - bool Entity::hasComponent(const std::type_index &type) const + bool Entity::hasComponent(const std::type_index &type, bool skipDisabled) const { auto existing = std::find_if(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) { return std::type_index(typeid(*cmp)) == type; }); - return existing != this->_components.end(); + if (existing == this->_components.end()) + return false; + if (skipDisabled) + return !(*existing)->isDisabled(); + return true; + } + + bool Entity::shouldDelete() const + { + return this->_shouldDelete; + } + + void Entity::scheduleDeletion() + { + this->_shouldDelete = true; } } // namespace WAL \ No newline at end of file diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 8e157c6e..090c9baf 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -23,6 +23,8 @@ namespace WAL std::string _name; //! @brief Is this entity enabled? bool _disabled = false; + //! @brief Has this entity been scheduled for deletion? + bool _shouldDelete; //! @brief The list of the components of this entity std::vector> _components = {}; @@ -36,10 +38,14 @@ namespace WAL //! @brief Used if the entity is disabled bool isDisable() const; - //! @brief Disable this entity. void setDisable(bool disabled); + //! @brief Has this entity been scheduled for deletion? + bool shouldDelete() const; + //! @brief Schedule this entity for deletion + void scheduleDeletion(); + //! @brief Get a component of a specific type //! @throw NotFoundError if the component could not be found template @@ -55,21 +61,24 @@ namespace WAL } //! @brief Check if this entity has a component. + //! @param skipDisabled True if you want to skip disabled components (consider them non present), false otherwise. //! @tparam T The type of the component template - bool hasComponent() const + bool hasComponent(bool skipDisabled = true) const { const std::type_info &type = typeid(T); - return this->hasComponent(type); + return this->hasComponent(type, skipDisabled); } //! @brief Check if this entity has a component. + //! @param skipDisabled True if you want to skip disabled components (consider them non present), false otherwise. //! @param type The type of the component - bool hasComponent(const std::type_info &type) const; + bool hasComponent(const std::type_info &type, bool skipDisabled = true) const; //! @brief Check if this entity has a component. + //! @param skipDisabled True if you want to skip disabled components (consider them non present), false otherwise. //! @param type The type of the component - bool hasComponent(const std::type_index &type) const; + bool hasComponent(const std::type_index &type, bool skipDisabled = true) const; //! @brief Add a component to this entity. The component is constructed in place. //! @throw DuplicateError is thrown if a component with the same type already exist. @@ -77,7 +86,7 @@ namespace WAL template Entity &addComponent(Types &&...params) { - if (this->hasComponent()) + if (this->hasComponent(false)) throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists."); this->_components.push_back(std::make_unique(*this, std::forward(params)...)); return *this; From f8e5446946828a9fb7c202e0a0cfcee28605a93f Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 31 May 2021 17:50:58 +0200 Subject: [PATCH 06/14] Adding a todo --- lib/wal/sources/Wal.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index 50a87188..76b893e6 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -133,6 +133,7 @@ namespace WAL this->_fixedUpdate(); } this->_update(dtime); + // TODO delete entities scheduled for deletion. callback(*this, state); } } From 42a45a06ff9b7a6022aad146bb08e600f418e894 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 1 Jun 2021 14:48:15 +0200 Subject: [PATCH 07/14] Allowing entities to be deleted --- lib/wal/sources/Entity/Entity.hpp | 2 ++ lib/wal/sources/Wal.hpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 090c9baf..2321934d 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -122,5 +122,7 @@ namespace WAL ~Entity() = default; //! @brief An entity is not assignable Entity &operator=(const Entity &) = delete; + //! @brief An entity is move assignable. + Entity &operator=(Entity &&) = default; }; } // namespace WAL \ No newline at end of file diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index 76b893e6..9c40d1da 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -133,7 +133,10 @@ namespace WAL this->_fixedUpdate(); } this->_update(dtime); - // TODO delete entities scheduled for deletion. + auto &entities = this->scene->getEntities(); + entities.erase(std::remove_if(entities.begin(), entities.end(), [](auto &entity) { + return entity.shouldDelete(); + }), entities.end()); callback(*this, state); } } From 9dca04e3850f209ad0034952bed9133dc671e4dd Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 1 Jun 2021 15:33:32 +0200 Subject: [PATCH 08/14] Making bomb explose --- sources/Component/Timer/TimerComponent.cpp | 4 ++-- sources/Component/Timer/TimerComponent.hpp | 9 +++++---- sources/Runner/Runner.cpp | 2 +- sources/System/BombHolder/BombHolderSystem.cpp | 11 +++++++++++ sources/System/BombHolder/BombHolderSystem.hpp | 6 ++++++ sources/System/Timer/TimerSystem.cpp | 7 ++++--- sources/System/Timer/TimerSystem.hpp | 6 +++++- 7 files changed, 34 insertions(+), 11 deletions(-) diff --git a/sources/Component/Timer/TimerComponent.cpp b/sources/Component/Timer/TimerComponent.cpp index 09ad1f5b..7845df9d 100644 --- a/sources/Component/Timer/TimerComponent.cpp +++ b/sources/Component/Timer/TimerComponent.cpp @@ -13,13 +13,13 @@ namespace BBM ringIn(delay) {} - TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, const WAL::Callback &callback) + TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, const WAL::Callback &callback) : WAL::Component(entity), ringIn(delay), callback(callback) {} - TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, std::function callback) + TimerComponent::TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, std::function callback) : WAL::Component(entity), ringIn(delay), callback(std::move(callback)) diff --git a/sources/Component/Timer/TimerComponent.hpp b/sources/Component/Timer/TimerComponent.hpp index e6c005db..f239ceb4 100644 --- a/sources/Component/Timer/TimerComponent.hpp +++ b/sources/Component/Timer/TimerComponent.hpp @@ -6,6 +6,7 @@ #include #include +#include #include "Models/Callback.hpp" namespace BBM @@ -15,18 +16,18 @@ namespace BBM { public: //! @brief The callback to call when the timer ring. - WAL::Callback callback; + WAL::Callback callback; //! @brief The ring delay of this timer component. std::chrono::nanoseconds ringIn; - Component * clone(WAL::Entity &entity) const override; + Component *clone(WAL::Entity &entity) const override; //! @brief A default constructor TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay); //! @brief Create a timer with a callback. - TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, const WAL::Callback &callback); + TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, const WAL::Callback &callback); //! @brief Create a timer with a function to call on ring. - TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, std::function callback); + TimerComponent(WAL::Entity &entity, std::chrono::nanoseconds delay, std::function callback); //! @brief A timer component is copy constructable TimerComponent(const TimerComponent &) = default; //! @brief A default destructor diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 5f416812..9c5652b8 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -43,7 +43,7 @@ namespace BBM void addSystems(WAL::Wal &wal) { - wal.addSystem() + wal.addSystem(wal) .addSystem() .addSystem() .addSystem() diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index dc56b418..c7243acd 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -2,6 +2,7 @@ // Created by Zoe Roux on 5/31/21. // +#include #include "Component/Renderer/Drawable3DComponent.hpp" #include "Component/Controllable/ControllableComponent.hpp" #include "BombHolderSystem.hpp" @@ -13,6 +14,8 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { + std::chrono::nanoseconds BombHolderSystem::explosionTimer = 3s; + BombHolderSystem::BombHolderSystem(WAL::Wal &wal) : WAL::System({ typeid(PositionComponent), @@ -22,10 +25,18 @@ namespace BBM _wal(wal) {} + void BombHolderSystem::_bombExplosion(WAL::Entity &bomb, const WAL::Wal &wal) + { + std::cout << "Boom" << std::endl; + bomb.scheduleDeletion(); + } + void BombHolderSystem::_spawnBomb(Vector3f position) { + std::cout << "Spawnned" << std::endl; this->_wal.scene->addEntity("Bomb") .addComponent(position) + .addComponent(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion) .addComponent>("assets/bombs/bomb.obj", std::make_pair(MAP_DIFFUSE, "assets/bombs/bomb_normal.png")); } diff --git a/sources/System/BombHolder/BombHolderSystem.hpp b/sources/System/BombHolder/BombHolderSystem.hpp index 1241c9d9..1dc13c72 100644 --- a/sources/System/BombHolder/BombHolderSystem.hpp +++ b/sources/System/BombHolder/BombHolderSystem.hpp @@ -18,7 +18,13 @@ namespace BBM WAL::Wal &_wal; //! @brief Spawn a bomb at the specified position. void _spawnBomb(Vector3f position); + + //! @brief The method triggered when the bomb explode. + static void _bombExplosion(WAL::Entity &bomb, const WAL::Wal &); public: + //! @brief The explosion time of new bombs. + static std::chrono::nanoseconds explosionTimer; + //! @inherit void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override; diff --git a/sources/System/Timer/TimerSystem.cpp b/sources/System/Timer/TimerSystem.cpp index e299549a..e1765a23 100644 --- a/sources/System/Timer/TimerSystem.cpp +++ b/sources/System/Timer/TimerSystem.cpp @@ -9,10 +9,11 @@ using namespace std::chrono_literals; namespace BBM { - TimerSystem::TimerSystem() + TimerSystem::TimerSystem(WAL::Wal &wal) : WAL::System({ typeid(TimerComponent) - }) + }), + _wal(wal) {} void TimerSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) @@ -21,7 +22,7 @@ namespace BBM timer.ringIn -= dtime; if (timer.ringIn <= 0ns) { timer.setDisable(true); - timer.callback(entity); + timer.callback(entity, this->_wal); } } } \ No newline at end of file diff --git a/sources/System/Timer/TimerSystem.hpp b/sources/System/Timer/TimerSystem.hpp index a3cf8a2b..f925dd82 100644 --- a/sources/System/Timer/TimerSystem.hpp +++ b/sources/System/Timer/TimerSystem.hpp @@ -5,17 +5,21 @@ #pragma once #include +#include namespace BBM { class TimerSystem : public WAL::System { + private: + //! @brief The wal engine + WAL::Wal &_wal; public: //! @inherit void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override; //! @brief A default constructor - TimerSystem(); + TimerSystem(WAL::Wal &); //! @brief A timer system is copy constructable. TimerSystem(const TimerSystem &) = default; //! @brief A default destructor From 2da5b219b91bdadae97f4a56059c2962c5e0fc83 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 1 Jun 2021 17:06:35 +0200 Subject: [PATCH 09/14] Adding an event system --- CMakeLists.txt | 2 +- sources/Component/Timer/TimerComponent.hpp | 2 +- sources/Runner/Runner.cpp | 8 ++++- .../System/BombHolder/BombHolderSystem.cpp | 17 +++++++-- .../System/BombHolder/BombHolderSystem.hpp | 4 ++- sources/System/Event/EventSystem.cpp | 28 +++++++++++++++ sources/System/Event/EventSystem.hpp | 36 +++++++++++++++++++ 7 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 sources/System/Event/EventSystem.cpp create mode 100644 sources/System/Event/EventSystem.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 14240035..86be286d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ set(SOURCES sources/Component/Timer/TimerComponent.hpp sources/System/Timer/TimerSystem.cpp sources/System/Timer/TimerSystem.hpp -) + sources/System/Event/EventSystem.cpp sources/System/Event/EventSystem.hpp) add_executable(bomberman sources/main.cpp diff --git a/sources/Component/Timer/TimerComponent.hpp b/sources/Component/Timer/TimerComponent.hpp index f239ceb4..513ccb71 100644 --- a/sources/Component/Timer/TimerComponent.hpp +++ b/sources/Component/Timer/TimerComponent.hpp @@ -16,7 +16,7 @@ namespace BBM { public: //! @brief The callback to call when the timer ring. - WAL::Callback callback; + WAL::Callback callback; //! @brief The ring delay of this timer component. std::chrono::nanoseconds ringIn; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 9c5652b8..eb531502 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include "System/Event/EventSystem.hpp" +#include "System/Health/HealthSystem.hpp" #include "System/Timer/TimerSystem.hpp" #include "Component/BombHolder/BombHolderComponent.hpp" #include "System/BombHolder/BombHolderSystem.hpp" @@ -48,6 +51,8 @@ namespace BBM .addSystem() .addSystem() .addSystem(wal) + .addSystem() + .addSystem() .addSystem(); } @@ -78,7 +83,8 @@ namespace BBM .addComponent() .addComponent() .addComponent() - .addComponent(); + .addComponent() + .addComponent(1); scene->addEntity("camera") .addComponent(0, 20, -5) .addComponent(); diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index c7243acd..2c289ce4 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -2,12 +2,14 @@ // Created by Zoe Roux on 5/31/21. // -#include +#include "Component/Timer/TimerComponent.hpp" +#include "System/Event/EventSystem.hpp" #include "Component/Renderer/Drawable3DComponent.hpp" #include "Component/Controllable/ControllableComponent.hpp" #include "BombHolderSystem.hpp" #include "Component/Position/PositionComponent.hpp" #include "Component/BombHolder/BombHolderComponent.hpp" +#include "Component/Health/HealthComponent.hpp" using namespace std::chrono_literals; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -15,6 +17,7 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { std::chrono::nanoseconds BombHolderSystem::explosionTimer = 3s; + float BombHolderSystem::explosionRadius = 3; BombHolderSystem::BombHolderSystem(WAL::Wal &wal) : WAL::System({ @@ -25,10 +28,20 @@ namespace BBM _wal(wal) {} - void BombHolderSystem::_bombExplosion(WAL::Entity &bomb, const WAL::Wal &wal) + void BombHolderSystem::_bombExplosion(WAL::Entity &bomb, WAL::Wal &wal) { std::cout << "Boom" << std::endl; bomb.scheduleDeletion(); + auto &bombPosition = bomb.getComponent(); + wal.getSystem().dispatchEvent([&bombPosition](WAL::Entity &entity){ + if (!entity.hasComponent() || + !entity.hasComponent()) + return; + auto &position = entity.getComponent(); + + if (position.position.distance(bombPosition.position) <= BombHolderSystem::explosionRadius) + entity.getComponent().takeDmg(1); + }); } void BombHolderSystem::_spawnBomb(Vector3f position) diff --git a/sources/System/BombHolder/BombHolderSystem.hpp b/sources/System/BombHolder/BombHolderSystem.hpp index 1dc13c72..83f80711 100644 --- a/sources/System/BombHolder/BombHolderSystem.hpp +++ b/sources/System/BombHolder/BombHolderSystem.hpp @@ -20,10 +20,12 @@ namespace BBM void _spawnBomb(Vector3f position); //! @brief The method triggered when the bomb explode. - static void _bombExplosion(WAL::Entity &bomb, const WAL::Wal &); + static void _bombExplosion(WAL::Entity &bomb, WAL::Wal &); public: //! @brief The explosion time of new bombs. static std::chrono::nanoseconds explosionTimer; + //! @brief The radius of the explosion. + static float explosionRadius; //! @inherit void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override; diff --git a/sources/System/Event/EventSystem.cpp b/sources/System/Event/EventSystem.cpp new file mode 100644 index 00000000..e37e9f53 --- /dev/null +++ b/sources/System/Event/EventSystem.cpp @@ -0,0 +1,28 @@ +// +// Created by Zoe Roux on 6/1/21. +// + +#include "EventSystem.hpp" + +namespace BBM +{ + EventSystem::EventSystem() + : WAL::System({}) + {} + + void EventSystem::dispatchEvent(const std::function &event) + { + this->_events.emplace_back(event); + } + + void EventSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) + { + for (auto &event : this->_events) + event(entity); + } + + void EventSystem::onSelfUpdate() + { + this->_events.clear(); + } +} \ No newline at end of file diff --git a/sources/System/Event/EventSystem.hpp b/sources/System/Event/EventSystem.hpp new file mode 100644 index 00000000..0defda29 --- /dev/null +++ b/sources/System/Event/EventSystem.hpp @@ -0,0 +1,36 @@ +// +// Created by Zoe Roux on 6/1/21. +// + +#pragma once + +#include +#include +#include + +namespace BBM +{ + class EventSystem : public WAL::System + { + private: + //! @brief The list of events that occurred in the last update. + std::vector> _events; + public: + //! @brief Inform the system that a new event has occurred and it should run the given method on every entities. + void dispatchEvent(const std::function& event); + + //! @inherit + void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override; + //! @inherit + void onSelfUpdate() override; + + //! @brief A default constructor + EventSystem(); + //! @brief An event system is copy constructable. + EventSystem(const EventSystem &) = default; + //! @brief A default destructor + ~EventSystem() override = default; + //! @brief An event system is not assignable. + EventSystem &operator=(const EventSystem &) = delete; + }; +} From 328ad91c4376f3a1f96ecec023e4037fce5607a1 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 7 Jun 2021 14:49:25 +0200 Subject: [PATCH 10/14] Fixing unknown bug --- CMakeLists.txt | 2 +- lib/wal/sources/Entity/Entity.hpp | 4 +--- lib/wal/sources/Wal.hpp | 1 - sources/Component/BombHolder/BombHolderComponent.cpp | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dfb9d892..352a531b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,7 @@ add_executable(unit_tests EXCLUDE_FROM_ALL tests/EngineTests.cpp tests/CallbackTest.cpp tests/MoveTests.cpp -tests/ViewTest.cpp + tests/ViewTest.cpp tests/CollisionTest.cpp ) target_include_directories(unit_tests PUBLIC sources) diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 43aecb33..9fbd3657 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -27,7 +27,7 @@ namespace WAL //! @brief Is this entity enabled? bool _disabled = false; //! @brief Has this entity been scheduled for deletion? - bool _shouldDelete; + bool _shouldDelete = false; //! @brief The list of the components of this entity std::unordered_map> _components = {}; @@ -174,7 +174,5 @@ namespace WAL ~Entity() = default; //! @brief An entity is not assignable Entity &operator=(const Entity &) = delete; - //! @brief An entity is move assignable. - Entity &operator=(Entity &&) = default; }; } // namespace WAL \ No newline at end of file diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index b9c39aa9..e3d2a4f5 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -52,7 +52,6 @@ namespace WAL } for (auto &system : this->_systems) system->update(dtime); - auto &entities = this->scene->getEntities(); this->scene->deleteMarkedEntities(); callback(*this, state); } diff --git a/sources/Component/BombHolder/BombHolderComponent.cpp b/sources/Component/BombHolder/BombHolderComponent.cpp index bff44867..9f75b8ae 100644 --- a/sources/Component/BombHolder/BombHolderComponent.cpp +++ b/sources/Component/BombHolder/BombHolderComponent.cpp @@ -19,6 +19,6 @@ namespace BBM WAL::Component *BombHolderComponent::clone(WAL::Entity &entity) const { - return new BombHolderComponent(entity); + return new BombHolderComponent(entity, this->maxBombCount); } } \ No newline at end of file From 7234d511304345ec9709ecd8b4416ce925a60b80 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 7 Jun 2021 17:57:45 +0200 Subject: [PATCH 11/14] Allowing entities to be created and removed --- lib/wal/sources/Entity/Entity.cpp | 11 +++++--- lib/wal/sources/Entity/Entity.hpp | 12 ++++++--- lib/wal/sources/Scene/Scene.cpp | 18 ++++++++++++- lib/wal/sources/Scene/Scene.hpp | 11 ++++++-- lib/wal/sources/View/View.hpp | 6 +++-- lib/wal/sources/Wal.hpp | 4 +-- sources/Map/Map.cpp | 16 +++++------ .../System/BombHolder/BombHolderSystem.cpp | 2 +- tests/ViewTest.cpp | 27 +++++++++++++++++++ 9 files changed, 84 insertions(+), 23 deletions(-) diff --git a/lib/wal/sources/Entity/Entity.cpp b/lib/wal/sources/Entity/Entity.cpp index d9cd550c..e4e07453 100644 --- a/lib/wal/sources/Entity/Entity.cpp +++ b/lib/wal/sources/Entity/Entity.cpp @@ -11,17 +11,19 @@ namespace WAL { unsigned Entity::nextID = 0; - Entity::Entity(Scene &scene, std::string name) + Entity::Entity(Scene &scene, std::string name, bool notifyScene) : _uid(Entity::nextID++), _scene(scene), - _name(std::move(name)) + _name(std::move(name)), + _notifyScene(notifyScene) { } Entity::Entity(const Entity &other) : _uid(Entity::nextID++), _scene(other._scene), _name(other._name), - _disabled(other._disabled) + _disabled(other._disabled), + _notifyScene(other._notifyScene) { for (const auto &cmp : other._components) this->addComponent(*cmp.second); @@ -53,7 +55,8 @@ namespace WAL if (this->hasComponent(type, false)) throw DuplicateError("A component of the type \"" + std::string(type.name()) + "\" already exists."); this->_components.emplace(type, component.clone(*this)); - this->_scene._componentAdded(*this, type); + if (this->_notifyScene) + this->_scene._componentAdded(*this, type); return *this; } diff --git a/lib/wal/sources/Entity/Entity.hpp b/lib/wal/sources/Entity/Entity.hpp index 9fbd3657..9eab09a4 100644 --- a/lib/wal/sources/Entity/Entity.hpp +++ b/lib/wal/sources/Entity/Entity.hpp @@ -28,6 +28,8 @@ namespace WAL bool _disabled = false; //! @brief Has this entity been scheduled for deletion? bool _shouldDelete = false; + //! @brief Should this entity notify the scene of component changes? + bool _notifyScene; //! @brief The list of the components of this entity std::unordered_map> _components = {}; @@ -40,6 +42,8 @@ namespace WAL //! @brief Callback called when a component is removed //! @param type The type of component void _componentRemoved(const std::type_index &type); + + friend Scene; protected: //! @brief A reference to the ECS. Scene &_scene; @@ -141,7 +145,8 @@ namespace WAL if (this->hasComponent(type)) throw DuplicateError("A component of the type \"" + std::string(type.name()) + "\" already exists."); this->_components[type] = std::make_unique(*this, TypeHolder()..., std::forward(params)...); - this->_componentAdded(type); + if (this->_notifyScene) + this->_componentAdded(type); return *this; } @@ -160,12 +165,13 @@ namespace WAL if (existing == this->_components.end()) throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\"."); this->_components.erase(existing); - this->_componentRemoved(type); + if (this->_notifyScene) + this->_componentRemoved(type); return *this; } //! @brief A default constructor - explicit Entity(Scene &wal, std::string name); + explicit Entity(Scene &wal, std::string name, bool notifyScene = true); //! @brief An entity is copyable Entity(const Entity &); //! @brief An entity is movable. diff --git a/lib/wal/sources/Scene/Scene.cpp b/lib/wal/sources/Scene/Scene.cpp index c4e610cf..34ca940c 100644 --- a/lib/wal/sources/Scene/Scene.cpp +++ b/lib/wal/sources/Scene/Scene.cpp @@ -24,6 +24,11 @@ namespace WAL return this->_entities.emplace_back(*this, name); } + Entity &Scene::scheduleNewEntity(const std::string &name) + { + return this->_newEntities.emplace_back(*this, name, false); + } + void Scene::_componentAdded(Entity &entity, const std::type_index &type) { for (auto &view : this->_views) { @@ -52,7 +57,7 @@ namespace WAL view->erase(entity); } - void Scene::deleteMarkedEntities() + void Scene::applyChanges() { this->_entities.remove_if([this](auto &entity) { if (!entity.shouldDelete()) @@ -60,5 +65,16 @@ namespace WAL this->_entityRemoved(entity); return true; }); + for (auto &entity : this->_newEntities) { + for (auto &view : this->_views) { + bool valid = std::all_of(view->getTypes().begin(), view->getTypes().end(), [&entity](const auto &type){ + return entity.hasComponent(type); + }); + if (valid) + view->emplace_back(entity); + } + entity._notifyScene = true; + } + this->_entities.splice(this->_entities.end(), this->_newEntities); } } // namespace WAL \ No newline at end of file diff --git a/lib/wal/sources/Scene/Scene.hpp b/lib/wal/sources/Scene/Scene.hpp index 4dfc5ad8..3d7f702a 100644 --- a/lib/wal/sources/Scene/Scene.hpp +++ b/lib/wal/sources/Scene/Scene.hpp @@ -23,6 +23,8 @@ namespace WAL //! @brief The list of registered entities std::list _entities = {}; + //! @brief The list of entities to add on the next call to applyChanges. + std::list _newEntities = {}; //! @brief The list of cached views to update. std::vector> _views = {}; @@ -46,6 +48,11 @@ namespace WAL //! @return The created entity is returned. Entity &addEntity(const std::string &name); + //! @brief Add a new entity to the scene, this entity will be added on the next call to applyChanges. + //! @param name The name of the created entity. + //! @return The created entity is returned. + Entity &scheduleNewEntity(const std::string &name); + template View &view() { @@ -59,8 +66,8 @@ namespace WAL return *view; } - //! @brief Delete entities marked as deleted. - void deleteMarkedEntities(); + //! @brief Delete entities marked as deleted and create scheduled entities. + void applyChanges(); //! @brief A default constructor Scene() = default; diff --git a/lib/wal/sources/View/View.hpp b/lib/wal/sources/View/View.hpp index 15b31e09..6b847341 100644 --- a/lib/wal/sources/View/View.hpp +++ b/lib/wal/sources/View/View.hpp @@ -179,8 +179,10 @@ namespace WAL void erase(const Entity &entity) override { this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [&entity](const auto &ref){ - return &std::get<0>(ref).get() == &entity; - })); + if (std::get<0>(ref).get().getUid() == entity.getUid()) + return true; + return std::get<0>(ref).get().getUid() == entity.getUid(); + }), this->_entities.end()); } //! @brief Construct a view from a list of entities. diff --git a/lib/wal/sources/Wal.hpp b/lib/wal/sources/Wal.hpp index e3d2a4f5..4748e84e 100644 --- a/lib/wal/sources/Wal.hpp +++ b/lib/wal/sources/Wal.hpp @@ -52,7 +52,7 @@ namespace WAL } for (auto &system : this->_systems) system->update(dtime); - this->scene->deleteMarkedEntities(); + this->scene->applyChanges(); callback(*this, state); } } @@ -76,7 +76,7 @@ namespace WAL } for (auto &system : wal._systems) system->update(dtime); - wal.scene->deleteMarkedEntities(); + wal.scene->applyChanges(); callback(wal, state); } #endif diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index e71d2c34..4386546a 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -20,14 +20,14 @@ namespace BBM const auto &wallPos = wall.getComponent(); auto diff = pos.position + mov->getVelocity() - wallPos.position; // mov->_velocity = Vector3f(); - if (diff.x <= 0 && mov->_velocity.x < 0) - mov->_velocity.x = 0; - if (diff.x >= 0 && mov->_velocity.x > 0) - mov->_velocity.x = 0; - if (diff.z <= 0 && mov->_velocity.z < 0) - mov->_velocity.z = 0; - if (diff.z >= 0 && mov->_velocity.z > 0) - mov->_velocity.z = 0; +// if (diff.x <= 0 && mov->_velocity.x < 0) +// mov->_velocity.x = 0; +// if (diff.x >= 0 && mov->_velocity.x > 0) +// mov->_velocity.x = 0; +// if (diff.z <= 0 && mov->_velocity.z < 0) +// mov->_velocity.z = 0; +// if (diff.z >= 0 && mov->_velocity.z > 0) +// mov->_velocity.z = 0; } const std::string MapGenerator::assetsPath = "./assets/"; diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index f09d2356..621c87b2 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -39,7 +39,7 @@ namespace BBM void BombHolderSystem::_spawnBomb(Vector3f position) { std::cout << "Spawnned" << std::endl; - this->_wal.scene->addEntity("Bomb") + this->_wal.scene->scheduleNewEntity("Bomb") .addComponent(position) .addComponent(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion) .addComponent("assets/bombs/bomb.obj", diff --git a/tests/ViewTest.cpp b/tests/ViewTest.cpp index 569d42ad..aaa1bf36 100644 --- a/tests/ViewTest.cpp +++ b/tests/ViewTest.cpp @@ -50,6 +50,33 @@ TEST_CASE("View cache", "[View]") REQUIRE(&view == &scene.view()); } +TEST_CASE("View add entity", "[View]") +{ + Scene scene; + auto &entity = scene.addEntity("player") + .addComponent() + .addComponent(); + REQUIRE(scene.view().size() == 1); + scene.scheduleNewEntity("test") + .addComponent(); + scene.applyChanges(); + REQUIRE(scene.view().size() == 2); +} + +TEST_CASE("View remove entity", "[View]") +{ + Scene scene; + auto &entity = scene.addEntity("player") + .addComponent() + .addComponent(); + REQUIRE(scene.view().size() == 1); + entity.scheduleDeletion(); + scene.applyChanges(); + REQUIRE(scene.view().size() == 0); + for (auto &it : scene.view()) + REQUIRE(false); +} + TEST_CASE("View cache switch", "[View]") { Scene scene; From fe9a650427e8709c41700f188afd1bc078795fa8 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 7 Jun 2021 21:47:04 +0200 Subject: [PATCH 12/14] Making walls breakables --- sources/Component/Health/HealthComponent.cpp | 5 +++-- sources/Component/Health/HealthComponent.hpp | 2 +- sources/Map/Map.cpp | 7 ++++++- sources/Map/Map.hpp | 1 + sources/System/BombHolder/BombHolderSystem.cpp | 6 ++++-- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/sources/Component/Health/HealthComponent.cpp b/sources/Component/Health/HealthComponent.cpp index fe81fabb..80c9ef7e 100644 --- a/sources/Component/Health/HealthComponent.cpp +++ b/sources/Component/Health/HealthComponent.cpp @@ -13,9 +13,10 @@ namespace BBM _healthPoint() {} - HealthComponent::HealthComponent(WAL::Entity &entity, unsigned int healthPoint) + HealthComponent::HealthComponent(WAL::Entity &entity, unsigned int healthPoint, WAL::Callback onDeath) : WAL::Component(entity), - _healthPoint(healthPoint) + _healthPoint(healthPoint), + onDeath(onDeath) {} WAL::Component *HealthComponent::clone(WAL::Entity &entity) const diff --git a/sources/Component/Health/HealthComponent.hpp b/sources/Component/Health/HealthComponent.hpp index 2eadafc5..c613c6b3 100644 --- a/sources/Component/Health/HealthComponent.hpp +++ b/sources/Component/Health/HealthComponent.hpp @@ -39,7 +39,7 @@ namespace BBM explicit HealthComponent(WAL::Entity &entity); //! @brief Constructor - HealthComponent(WAL::Entity &entity, unsigned int healthPoint); + HealthComponent(WAL::Entity &entity, unsigned int healthPoint, WAL::Callback onDeath = WAL::Callback()); //! @brief A Health component can't be instantiated, it should be derived. HealthComponent(const HealthComponent &) = default; diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 4386546a..ed26beb0 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -30,6 +30,11 @@ namespace BBM // mov->_velocity.z = 0; } + void MapGenerator::wallDestroyed(WAL::Entity &entity) + { + entity.scheduleDeletion(); + } + const std::string MapGenerator::assetsPath = "./assets/"; const std::string MapGenerator::wallAssetsPath = MapGenerator::assetsPath + "map/"; const std::string MapGenerator::imageExtension = ".png"; @@ -133,7 +138,7 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) - .addComponent(1) + .addComponent(1, &MapGenerator::wallDestroyed) .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp index 0e54ea4c..49e82e5b 100644 --- a/sources/Map/Map.hpp +++ b/sources/Map/Map.hpp @@ -155,6 +155,7 @@ namespace BBM public: static void wallCollide(WAL::Entity &entity, const WAL::Entity &wall); + static void wallDestroyed(WAL::Entity &entity); //! @param width Width of the map diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index 621c87b2..45b28069 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -31,8 +31,10 @@ namespace BBM if (!health || !pos) return; - if (pos->position.distance(bombPosition.position) <= BombHolderSystem::explosionRadius) - health->takeDmg(1); + if (pos->position.distance(bombPosition.position) > BombHolderSystem::explosionRadius) + return; + // TODO do a raycast here to only remove health to entities that are not behind others. + health->takeDmg(1); }); } From e531d1de67afb67a84c458aa931dda2e5f4505ef Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 8 Jun 2021 10:09:34 +0200 Subject: [PATCH 13/14] Removing usless statement --- lib/wal/sources/View/View.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/wal/sources/View/View.hpp b/lib/wal/sources/View/View.hpp index 6b847341..50726a82 100644 --- a/lib/wal/sources/View/View.hpp +++ b/lib/wal/sources/View/View.hpp @@ -178,9 +178,7 @@ namespace WAL void erase(const Entity &entity) override { - this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [&entity](const auto &ref){ - if (std::get<0>(ref).get().getUid() == entity.getUid()) - return true; + this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [&entity](const auto &ref) { return std::get<0>(ref).get().getUid() == entity.getUid(); }), this->_entities.end()); } From af7f972d30759fd7977866f752a481ec5c36428f Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 8 Jun 2021 14:28:46 +0200 Subject: [PATCH 14/14] Fixing has component with disabled ones --- lib/wal/sources/Entity/Entity.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/wal/sources/Entity/Entity.cpp b/lib/wal/sources/Entity/Entity.cpp index e4e07453..8e4ff0f1 100644 --- a/lib/wal/sources/Entity/Entity.cpp +++ b/lib/wal/sources/Entity/Entity.cpp @@ -70,7 +70,9 @@ namespace WAL auto cmp = this->_components.find(type); if (cmp == this->_components.end()) return false; - return !cmp->second->isDisabled(); + if (skipDisabled) + return !cmp->second->isDisabled(); + return true; } void Entity::_componentAdded(const std::type_index &type)