diff --git a/CMakeLists.txt b/CMakeLists.txt index 45d0247d..0c0e8f2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,10 @@ set(SOURCES sources/Component/Renderer/CameraComponent.hpp sources/System/Renderer/Render2DScreenSystem.cpp sources/System/Renderer/Render2DScreenSystem.hpp + sources/Component/Collision/CollisionComponent.cpp + sources/Component/Collision/CollisionComponent.hpp + sources/System/Collision/CollisionSystem.hpp + sources/System/Collision/CollisionSystem.cpp ) add_executable(bomberman diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp new file mode 100644 index 00000000..0f14ca27 --- /dev/null +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -0,0 +1,64 @@ +// +// Created by Louis Auzuret on 2021-05-20. +// + +#include "Component/Collision/CollisionComponent.hpp" + + +namespace BBM +{ + CollisionComponent::CollisionComponent(WAL::Entity &entity) + : WAL::Component(entity) + { } + + WAL::Component *CollisionComponent::clone(WAL::Entity &entity) const + { + return new CollisionComponent(entity); + } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, std::function callback, Vector3f bound) + : WAL::Component(entity), onCollide(callback), _boundX(bound.x), _boundY(bound.y), _boundZ(bound.z) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, std::function callback, float boundSize) + : WAL::Component(entity), onCollide(callback), _boundX(boundSize), _boundY(boundSize), _boundZ(boundSize) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback callback, Vector3f bound) + : WAL::Component(entity), onCollide(callback), _boundX(bound.x), _boundY(bound.y), _boundZ(bound.z) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback callback, float boundSize) + : WAL::Component(entity), onCollide(callback), _boundX(boundSize), _boundY(boundSize), _boundZ(boundSize) + { } + + float CollisionComponent::getBoundX(void) const + { + return _boundX; + } + + float CollisionComponent::getBoundY(void) const + { + return _boundY; + } + + float CollisionComponent::getBoundZ(void) const + { + return _boundZ; + } + + void CollisionComponent::setBoundX(float value) + { + _boundX = value; + } + + void CollisionComponent::setBoundY(float value) + { + _boundY = value; + } + + void CollisionComponent::setBoundZ(float value) + { + _boundZ = value; + } +} \ No newline at end of file diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp new file mode 100644 index 00000000..64ecc243 --- /dev/null +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -0,0 +1,62 @@ +// +// Created by Louis Auzuret on 2021-05-20. +// + +#pragma once + +#include "Models/Callback.hpp" +#include "Models/Vector3.hpp" +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" + +namespace BBM +{ + class CollisionComponent : public WAL::Component + { + private: + float _boundX; + float _boundY; + float _boundZ; + public: + //! @brief get bound size on the X axis + float getBoundX(void) const; + //! @brief get bound size on the Y axis + float getBoundY(void) const; + //! @brief get bound size on the Z axis + float getBoundZ(void) const; + //! @brief set bound size on the X axis + void setBoundX(float); + //! @brief set bound size on the Y axis + void setBoundY(float); + //! @brief set bound size on the Z axis + void setBoundZ(float); + //onCollide functions to be called + WAL::Callback onCollide; + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief A component can't be instantiated, it should be derived. + explicit CollisionComponent(WAL::Entity &entity); + + //! @brief Constructor with a callback function + CollisionComponent(WAL::Entity &entity, std::function callback, Vector3f bound); + + //! @brief Constructor with a callback function + CollisionComponent(WAL::Entity &entity, std::function callback, float boundSize = 0); + + //! @brief Constructor with a WAL::Callback + CollisionComponent(WAL::Entity &entity, WAL::Callback callback, Vector3f bound); + + //! @brief Constructor with a WAL::Callback + CollisionComponent(WAL::Entity &entity, WAL::Callback callback, float boundSize = 0); + + //! @brief A component can't be instantiated, it should be derived. + CollisionComponent(const CollisionComponent &) = default; + + //! @brief default destructor + ~CollisionComponent() override = default; + + //! @brief A component can't be assigned + CollisionComponent &operator=(const CollisionComponent &) = delete; + }; +} \ No newline at end of file diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp new file mode 100644 index 00000000..a13d4648 --- /dev/null +++ b/sources/System/Collision/CollisionSystem.cpp @@ -0,0 +1,45 @@ +// +// Created by Louis Auzuret on 5/20/21 +// + +#include "Component/Position/PositionComponent.hpp" +#include "Component/Collision/CollisionComponent.hpp" +#include "System/Collision/CollisionSystem.hpp" + +namespace BBM +{ + CollisionSystem::CollisionSystem(WAL::Wal &wal) + : WAL::System({typeid(PositionComponent), typeid(CollisionComponent)}), _wal(wal) + { + + } + void CollisionSystem::onFixedUpdate(WAL::Entity &entity) + { + try { + auto &posA = entity.getComponent(); + auto &col = entity.getComponent(); + Vector3f minA = { std::min(posA.getX(), posA.getX() + col.getBoundX()), + std::min(posA.getY(), posA.getY() + col.getBoundY()), + std::min(posA.getZ(), posA.getZ() + col.getBoundZ())}; + Vector3f maxA = { std::max(posA.getX(), posA.getX() + col.getBoundX()), + std::max(posA.getY(), posA.getY() + col.getBoundY()), + std::max(posA.getZ(), posA.getZ() + col.getBoundZ())}; + for (auto &other : _wal.scene->getEntities()) { + auto &colB = entity.getComponent(); + auto &posB = other.getComponent(); + Vector3f minB = { std::min(posB.getX(), posB.getX() + colB.getBoundX()), + std::min(posB.getY(), posB.getY() + colB.getBoundY()), + std::min(posB.getZ(), posB.getZ() + colB.getBoundZ())}; + Vector3f maxB = { std::max(posB.getX(), posB.getX() + colB.getBoundX()), + std::max(posB.getY(), posB.getY() + colB.getBoundY()), + std::max(posB.getZ(), posB.getZ() + colB.getBoundZ())}; + if ((minA.x <= maxB.x && maxA.x >= minB.x) && + (minA.y <= maxB.y && maxA.y >= minB.y) && + (minA.z <= maxB.z && maxA.z >= minB.z)) + col.onCollide(entity, other); + } + } catch (std::exception &e) { + return; + } + } +} \ No newline at end of file diff --git a/sources/System/Collision/CollisionSystem.hpp b/sources/System/Collision/CollisionSystem.hpp new file mode 100644 index 00000000..41b7d13c --- /dev/null +++ b/sources/System/Collision/CollisionSystem.hpp @@ -0,0 +1,32 @@ + +// +// Created by Louis Auzuret on 5/20/21 +// + +#pragma once + +#include +#include "Wal.hpp" +#include "System/System.hpp" + +namespace BBM +{ + //! @brief A system to handle collisions. + class CollisionSystem : public WAL::System + { + private: + WAL::Wal &_wal; + public: + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + CollisionSystem(WAL::Wal &wal); + //! @brief A movable system is copy constructable + CollisionSystem(const CollisionSystem &) = default; + //! @brief A default destructor + ~CollisionSystem() override = default; + //! @brief A movable system is assignable. + CollisionSystem &operator=(const CollisionSystem &) = default; + }; +} \ No newline at end of file