mirror of
https://github.com/zoriya/Bomberman.git
synced 2026-06-01 17:55:48 +00:00
merge develop into animations
This commit is contained in:
@@ -60,6 +60,10 @@ set(SOURCES
|
||||
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
|
||||
sources/System/Collision/CollisionSystem.cpp
|
||||
)
|
||||
|
||||
add_executable(bomberman
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// 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<void (WAL::Entity &, const WAL::Entity &)> onCollide, std::function<void (WAL::Entity &, const WAL::Entity &)> onCollided, Vector3f bound)
|
||||
: WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound(bound)
|
||||
{ }
|
||||
|
||||
CollisionComponent::CollisionComponent(WAL::Entity &entity, std::function<void (WAL::Entity &, const WAL::Entity &)> onCollide, std::function<void (WAL::Entity &, const WAL::Entity &)> onCollided, float boundSize)
|
||||
: WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound({boundSize, boundSize, boundSize})
|
||||
{ }
|
||||
|
||||
CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollide, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollided, Vector3f bound)
|
||||
: WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound(bound)
|
||||
{ }
|
||||
|
||||
CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollide, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollided, float boundSize)
|
||||
: WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound({boundSize, boundSize, boundSize})
|
||||
{ }
|
||||
|
||||
CollisionComponent::CollisionComponent(WAL::Entity &entity, Vector3f bound)
|
||||
: WAL::Component(entity), onCollide(), onCollided(), bound(bound)
|
||||
{ }
|
||||
|
||||
CollisionComponent::CollisionComponent(WAL::Entity &entity, float boundSize)
|
||||
: WAL::Component(entity), onCollide(), onCollided(), bound({boundSize, boundSize, boundSize})
|
||||
{ }
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// 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:
|
||||
public:
|
||||
//! @brief onCollide functions to be called
|
||||
WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollide;
|
||||
//! @brief onCollided functions to be called
|
||||
WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollided;
|
||||
//! @brief Bound size on all axis
|
||||
Vector3f bound;
|
||||
//! @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<void (WAL::Entity &, const WAL::Entity &)> onCollide, std::function<void (WAL::Entity &, const WAL::Entity &)> onCollided, Vector3f bound);
|
||||
|
||||
//! @brief Constructor with a callback function, same boundSize for all axis
|
||||
CollisionComponent(WAL::Entity &entity, std::function<void (WAL::Entity &, const WAL::Entity &)> onCollide, std::function<void (WAL::Entity &, const WAL::Entity &)> onCollided, float boundSize = 0);
|
||||
|
||||
//! @brief Constructor with a WAL::Callback
|
||||
CollisionComponent(WAL::Entity &entity, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollide, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollided,Vector3f bound);
|
||||
|
||||
//! @brief Constructor with a WAL::Callback, same boundSize for all axis
|
||||
CollisionComponent(WAL::Entity &entity, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollide, WAL::Callback<WAL::Entity &, const WAL::Entity &> onCollided, float boundSize = 0);
|
||||
|
||||
//! @brief Constructor of collider with no callback
|
||||
CollisionComponent(WAL::Entity &entity, Vector3f bound);
|
||||
|
||||
//! @brief Constructor no callback, same boundSize for all axis
|
||||
CollisionComponent(WAL::Entity &entity, float boundSize);
|
||||
|
||||
//! @brief Default copy constructor
|
||||
CollisionComponent(const CollisionComponent &) = default;
|
||||
|
||||
//! @brief default destructor
|
||||
~CollisionComponent() override = default;
|
||||
|
||||
//! @brief A component can't be assigned
|
||||
CollisionComponent &operator=(const CollisionComponent &) = delete;
|
||||
};
|
||||
}
|
||||
@@ -19,4 +19,15 @@ namespace BBM
|
||||
{
|
||||
this->_acceleration += force;
|
||||
}
|
||||
|
||||
void MovableComponent::resetVelocity(void)
|
||||
{
|
||||
this->_velocity = {0, 0, 0};
|
||||
}
|
||||
|
||||
const Vector3f &MovableComponent::getVelocity(void) const
|
||||
{
|
||||
return _velocity;
|
||||
}
|
||||
|
||||
} // namespace WAL
|
||||
@@ -18,10 +18,17 @@ namespace BBM
|
||||
//! @brief The velocity of the entity.
|
||||
Vector3f _velocity;
|
||||
public:
|
||||
|
||||
//! @brief Add an instant force to this entity.
|
||||
//! @param force The force to add to this entity's acceleration. The force is added instantly and in one go.
|
||||
void addForce(Vector3f force);
|
||||
|
||||
//! @brief Set velocity to 0
|
||||
void resetVelocity(void);
|
||||
|
||||
//! @brief Get velocity
|
||||
const Vector3f &getVelocity(void) const;
|
||||
|
||||
//! @inherit
|
||||
WAL::Component *clone(WAL::Entity &entity) const override;
|
||||
|
||||
|
||||
@@ -166,6 +166,22 @@ namespace BBM
|
||||
{
|
||||
return RAY::Vector3(this->x, this->y, this->z);
|
||||
}
|
||||
|
||||
static Vector3<T> min(Vector3<T> a, Vector3<T> b)
|
||||
{
|
||||
Vector3<T> min = { std::min(a.x, b.x),
|
||||
std::min(a.y, b.y),
|
||||
std::min(a.z, b.z)};
|
||||
return min;
|
||||
}
|
||||
|
||||
static Vector3<T> max(Vector3<T> a, Vector3<T> b)
|
||||
{
|
||||
Vector3<T> max = { std::max(a.x, b.x),
|
||||
std::max(a.y, b.y),
|
||||
std::max(a.z, b.z)};
|
||||
return max;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Vector3<float> Vector3f;
|
||||
|
||||
@@ -10,11 +10,14 @@
|
||||
#include <System/Renderer/Renderer2DSystem.hpp>
|
||||
#include <Model/Model.hpp>
|
||||
#include <Drawables/2D/Rectangle.hpp>
|
||||
#include <Drawables/3D/Cube.hpp>
|
||||
#include <TraceLog.hpp>
|
||||
#include <System/Renderer/Renderer3DSystem.hpp>
|
||||
#include <System/Keyboard/KeyboardSystem.hpp>
|
||||
#include <System/Controllable/ControllableSystem.hpp>
|
||||
#include <System/Collision/CollisionSystem.hpp>
|
||||
#include <Component/Movable/MovableComponent.hpp>
|
||||
#include <Component/Collision/CollisionComponent.hpp>
|
||||
#include <Component/Controllable/ControllableComponent.hpp>
|
||||
#include <Component/Keyboard/KeyboardComponent.hpp>
|
||||
#include <System/Gamepad/GamepadSystem.hpp>
|
||||
@@ -47,6 +50,7 @@ namespace BBM
|
||||
wal.addSystem<KeyboardSystem>()
|
||||
.addSystem<GamepadSystem>()
|
||||
.addSystem<ControllableSystem>()
|
||||
.addSystem<CollisionSystem>(wal)
|
||||
.addSystem<MovableSystem>();
|
||||
}
|
||||
|
||||
@@ -57,6 +61,7 @@ namespace BBM
|
||||
|
||||
wal.addSystem<Renderer3DSystem<RAY3D::Model>>();
|
||||
wal.addSystem<AnimationsSystem>();
|
||||
wal.addSystem<Renderer3DSystem<RAY3D::Cube>>();
|
||||
|
||||
wal.addSystem<Render2DScreenSystem>(window)
|
||||
.addSystem<Renderer2DSystem<RAY2D::Rectangle>>();
|
||||
@@ -66,19 +71,27 @@ namespace BBM
|
||||
std::shared_ptr<WAL::Scene> loadGameScene()
|
||||
{
|
||||
auto scene = std::make_shared<WAL::Scene>();
|
||||
scene->addEntity("cube")
|
||||
.addComponent<PositionComponent>()
|
||||
.addComponent<Drawable2DComponent<RAY2D::Rectangle>>(Vector2f(), Vector2f(10, 10), RED)
|
||||
.addComponent<ControllableComponent>()
|
||||
.addComponent<KeyboardComponent>()
|
||||
.addComponent<MovableComponent>();;
|
||||
scene->addEntity("player")
|
||||
.addComponent<PositionComponent>()
|
||||
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png"))
|
||||
.addComponent<ControllableComponent>()
|
||||
.addComponent<KeyboardComponent>()
|
||||
.addComponent<AnimationsComponent>(RAY::ModelAnimations("assets/player/player.iqm"), 3)
|
||||
.addComponent<CollisionComponent>(2)
|
||||
.addComponent<MovableComponent>();
|
||||
scene->addEntity("cube")
|
||||
.addComponent<PositionComponent>(-5, 0, -5)
|
||||
.addComponent<Drawable3DComponent<RAY3D::Cube>>(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED)
|
||||
.addComponent<ControllableComponent>()
|
||||
.addComponent<KeyboardComponent>()
|
||||
.addComponent<CollisionComponent>([](WAL::Entity &, const WAL::Entity &){},
|
||||
[](WAL::Entity &actual, const WAL::Entity &) {
|
||||
try {
|
||||
auto &mov = actual.getComponent<MovableComponent>();
|
||||
mov.resetVelocity();
|
||||
} catch (std::exception &e) { };
|
||||
}, 3);
|
||||
|
||||
scene->addEntity("camera")
|
||||
.addComponent<PositionComponent>(8, 20, 7)
|
||||
.addComponent<CameraComponent>(Vector3f(8, 0, 8));
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by Louis Auzuret on 5/20/21
|
||||
//
|
||||
|
||||
#include "Component/Movable/MovableComponent.hpp"
|
||||
#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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CollisionSystem::collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB)
|
||||
{
|
||||
bool overlapX = (minA.x <= maxB.x && maxA.x >= minB.x) || (minB.x <= maxA.x && maxB.x >= minA.x);
|
||||
bool overlapY = (minA.y <= maxB.y && maxA.y >= minB.y) || (minB.y <= maxA.y && maxB.y >= minA.y);
|
||||
bool overlapZ = (minA.z <= maxB.z && maxA.z >= minB.z) || (minB.z <= maxA.z && maxB.z >= minA.z);
|
||||
|
||||
return (overlapX && overlapY && overlapZ);
|
||||
}
|
||||
|
||||
void CollisionSystem::onFixedUpdate(WAL::Entity &entity)
|
||||
{
|
||||
auto &posA = entity.getComponent<PositionComponent>();
|
||||
auto &col = entity.getComponent<CollisionComponent>();
|
||||
Vector3f position = posA.position;
|
||||
if (entity.hasComponent(typeid(MovableComponent)))
|
||||
position += entity.getComponent<MovableComponent>().getVelocity();
|
||||
Vector3f minA = Vector3f::min(position, position + col.bound);
|
||||
Vector3f maxA = Vector3f::max(position, position + col.bound);
|
||||
for (auto &other : _wal.scene->getEntities()) {
|
||||
if (&other == &entity)
|
||||
continue;
|
||||
if (!other.hasComponent<CollisionComponent>() ||
|
||||
!other.hasComponent<PositionComponent>())
|
||||
continue;
|
||||
auto colB = other.getComponent<CollisionComponent>();
|
||||
auto posB = other.getComponent<PositionComponent>().position;
|
||||
Vector3f minB = Vector3f::min(posB, posB + colB.bound);
|
||||
Vector3f maxB = Vector3f::max(posB, posB + colB.bound);
|
||||
if (collide(minA, maxA, minB, maxB)) {
|
||||
col.onCollide(entity, other);
|
||||
colB.onCollided(entity, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
//
|
||||
// Created by Louis Auzuret on 5/20/21
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include "Wal.hpp"
|
||||
#include "System/System.hpp"
|
||||
|
||||
namespace BBM
|
||||
{
|
||||
//! @brief A system to handle collisions.
|
||||
class CollisionSystem : public WAL::System
|
||||
{
|
||||
private:
|
||||
//! @brief reference to the ECS engine to get other entities
|
||||
WAL::Wal &_wal;
|
||||
public:
|
||||
//! @inherit
|
||||
void onFixedUpdate(WAL::Entity &entity) override;
|
||||
|
||||
//! @brief A default constructor
|
||||
CollisionSystem(WAL::Wal &wal);
|
||||
//! @brief A Collision system is copy constructable
|
||||
CollisionSystem(const CollisionSystem &) = default;
|
||||
//! @brief A default destructor
|
||||
~CollisionSystem() override = default;
|
||||
//! @brief A Collision system is assignable.
|
||||
CollisionSystem &operator=(const CollisionSystem &) = default;
|
||||
|
||||
//! @brief check AABB collision
|
||||
static bool collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// Created by Louis Auzuret on 5/31/21.
|
||||
//
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
#include "Entity/Entity.hpp"
|
||||
#include "Component/Position/PositionComponent.hpp"
|
||||
#include "Component/Movable/MovableComponent.hpp"
|
||||
#include "System/Movable/MovableSystem.hpp"
|
||||
#include "System/Collision/CollisionSystem.hpp"
|
||||
#include "Wal.hpp"
|
||||
|
||||
#define private public
|
||||
#include "Component/Collision/CollisionComponent.hpp"
|
||||
|
||||
using namespace WAL;
|
||||
using namespace BBM;
|
||||
|
||||
|
||||
TEST_CASE("Collision test", "[Component][System]")
|
||||
{
|
||||
Wal wal;
|
||||
CollisionSystem collision(wal);
|
||||
wal.scene = std::shared_ptr<Scene>(new Scene);
|
||||
wal.scene->addEntity("player")
|
||||
.addComponent<PositionComponent>()
|
||||
.addComponent<CollisionComponent>([](Entity &actual, const Entity &) {
|
||||
try {
|
||||
auto &pos = actual.getComponent<PositionComponent>();
|
||||
pos.position.x = 1;
|
||||
pos.position.y = 1;
|
||||
pos.position.z = 1;
|
||||
} catch (std::exception &e) {};
|
||||
}, [](Entity &, const Entity &){}, 5.0);
|
||||
Entity &entity = wal.scene->getEntities()[0];
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position == Vector3f());
|
||||
|
||||
entity.getComponent<CollisionComponent>().bound.x = 5;
|
||||
entity.getComponent<CollisionComponent>().bound.y = 5;
|
||||
entity.getComponent<CollisionComponent>().bound.z = 5;
|
||||
|
||||
collision.onUpdate(entity, std::chrono::nanoseconds(1));
|
||||
collision.onFixedUpdate(entity);
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position.x == 0.0);
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position.y == 0.0);
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position.z == 0.0);
|
||||
|
||||
wal.scene->addEntity("block")
|
||||
.addComponent<PositionComponent>(2,2,2)
|
||||
.addComponent<CollisionComponent>(1);
|
||||
Entity &player = wal.scene->getEntities()[0];
|
||||
collision.onUpdate(entity, std::chrono::nanoseconds(1));
|
||||
REQUIRE(player.hasComponent(typeid(PositionComponent)));
|
||||
collision.onFixedUpdate(player);
|
||||
REQUIRE(wal.scene->getEntities().size() == 2);
|
||||
REQUIRE(player.hasComponent(typeid(PositionComponent)));
|
||||
REQUIRE(player.getComponent<PositionComponent>().position.x == 1.0);
|
||||
REQUIRE(player.getComponent<PositionComponent>().position.y == 1);
|
||||
REQUIRE(player.getComponent<PositionComponent>().position.z == 1);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Collsion test with movable", "[Component][System]")
|
||||
{
|
||||
Wal wal;
|
||||
CollisionSystem collision(wal);
|
||||
MovableSystem movable;
|
||||
wal.scene = std::shared_ptr<Scene>(new Scene);
|
||||
wal.scene->addEntity("player")
|
||||
.addComponent<PositionComponent>()
|
||||
.addComponent<CollisionComponent>([](Entity &actual, const Entity &) {}, [](Entity &actual, const Entity &) {}, 5.0)
|
||||
.addComponent<MovableComponent>();
|
||||
|
||||
wal.scene->addEntity("block")
|
||||
.addComponent<PositionComponent>(0, 0, 0)
|
||||
.addComponent<CollisionComponent>([](Entity &actual, const Entity &){}, [](Entity &actual, const Entity &) {
|
||||
try {
|
||||
auto &mov = actual.getComponent<MovableComponent>();
|
||||
mov.resetVelocity();
|
||||
} catch (std::exception &e) {};
|
||||
}, 1);
|
||||
Entity &entity = wal.scene->getEntities()[0];
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position == Vector3f());
|
||||
|
||||
entity.getComponent<CollisionComponent>().bound.x = 5;
|
||||
entity.getComponent<CollisionComponent>().bound.y = 5;
|
||||
entity.getComponent<CollisionComponent>().bound.z = 5;
|
||||
|
||||
entity.getComponent<MovableComponent>().addForce({1, 1, 1});
|
||||
collision.onUpdate(entity, std::chrono::nanoseconds(1));
|
||||
collision.onFixedUpdate(entity);
|
||||
movable.onUpdate(entity, std::chrono::nanoseconds(1));
|
||||
movable.onFixedUpdate(entity);
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position.x == 0.0);
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position.y == 0.0);
|
||||
REQUIRE(entity.getComponent<PositionComponent>().position.z == 0.0);
|
||||
}
|
||||
Reference in New Issue
Block a user