Merge branch 'lobby' of github.com:AnonymusRaccoon/Bomberman into lobby

This commit is contained in:
arthur.jamet
2021-06-14 17:34:56 +02:00
24 changed files with 295 additions and 60 deletions
+5
View File
@@ -30,4 +30,9 @@ namespace RAY::Drawables::Drawables3D
{ {
DrawCubeV(this->_position, this->_dimensions, this->_color); DrawCubeV(this->_position, this->_dimensions, this->_color);
} }
void Cube::drawWiresOn(RAY::Window &)
{
DrawCubeWiresV(this->_position, this->_dimensions, this->_debugColor);
}
} }
+3
View File
@@ -41,6 +41,9 @@ namespace RAY::Drawables::Drawables3D {
//! @brief Draw circle on window //! @brief Draw circle on window
void drawOn(RAY::Window &) override; void drawOn(RAY::Window &) override;
//! @brief Draw cube's wires on window
void drawWiresOn(RAY::Window &) override;
private: private:
//! @brief Dimensions of the cube //! @brief Dimensions of the cube
Vector3 _dimensions; Vector3 _dimensions;
@@ -52,4 +52,9 @@ namespace RAY::Drawables::Drawables3D
{ {
DrawCylinder(this->_position, this->_topRadius, this->_bottomRadius, this->_height, 0, this->_color); DrawCylinder(this->_position, this->_topRadius, this->_bottomRadius, this->_height, 0, this->_color);
} }
void Cylinder::drawWiresOn(RAY::Window &)
{
DrawCylinderWires(this->_position, this->_topRadius, this->_bottomRadius, this->_height, 0, this->_debugColor);
}
} }
@@ -55,6 +55,8 @@ namespace RAY::Drawables::Drawables3D {
//! @brief Draw point on window //! @brief Draw point on window
void drawOn(RAY::Window &) override; void drawOn(RAY::Window &) override;
//! @brief Draw cylinder's wires on window
void drawWiresOn(RAY::Window &) override;
private: private:
//! @brief Radius of the cylinder //! @brief Radius of the cylinder
float _topRadius; float _topRadius;
+5
View File
@@ -30,4 +30,9 @@ namespace RAY::Drawables::Drawables3D
{ {
DrawSphere(this->_position, this->_radius, this->_color); DrawSphere(this->_position, this->_radius, this->_color);
} }
void Sphere::drawWiresOn(RAY::Window &)
{
DrawSphereWires(this->_position, this->_radius, 10, 10, this->_debugColor);
}
} }
+3
View File
@@ -40,6 +40,9 @@ namespace RAY::Drawables::Drawables3D {
//! @brief Draw point on window //! @brief Draw point on window
void drawOn(RAY::Window &) override; void drawOn(RAY::Window &) override;
//! @brief Draw sphere's wires on window
void drawWiresOn(RAY::Window &) override;
private: private:
//! @brief Radius of the sphere //! @brief Radius of the sphere
int _radius; int _radius;
+14
View File
@@ -36,4 +36,18 @@ namespace RAY::Drawables
this->_position = position; this->_position = position;
return *this; return *this;
} }
void ADrawable3D::drawWiresOn(RAY::Window &)
{}
const RAY::Color &ADrawable3D::getDebugColor(void) const
{
return this->_debugColor;
}
ADrawable3D &ADrawable3D::setDebugColor(const Color &debugColor)
{
this->_debugColor = debugColor;
return *this;
}
} }
+13 -1
View File
@@ -30,12 +30,21 @@ namespace RAY::Drawables {
//! @brief Draw drawble on window //! @brief Draw drawble on window
void drawOn(RAY::Window &) override = 0; void drawOn(RAY::Window &) override = 0;
//! @brief Draw drawble's wires on window
virtual void drawWiresOn(RAY::Window &);
//! @return the color of the ADrawable //! @return the color of the ADrawable
const RAY::Color &getColor(void) const; const RAY::Color &getColor(void) const;
//! @brief set color //! @brief set color
ADrawable3D &setColor(const RAY::Color &color); ADrawable3D &setColor(const RAY::Color &color);
//! @return the debug color of the ADrawable
const RAY::Color &getDebugColor(void) const;
//! @brief set the debug color
ADrawable3D &setDebugColor(const RAY::Color &debugColor);
//! @return the position of the ADrawable //! @return the position of the ADrawable
virtual const RAY::Vector3 &getPosition(void) const; virtual const RAY::Vector3 &getPosition(void) const;
@@ -49,6 +58,9 @@ namespace RAY::Drawables {
//! @brief Color of the ADrawable //! @brief Color of the ADrawable
Color _color; Color _color;
//! @brief Color of the ADrawable's Debug
Color _debugColor = GREEN;
}; };
}; };
+14
View File
@@ -114,6 +114,20 @@ namespace RAY::Drawables::Drawables3D
this->_color); this->_color);
} }
void Model::drawWiresOn(RAY::Window &)
{
if (this->_model->meshCount) {
::BoundingBox box = GetMeshBoundingBox(*this->_model->meshes);
box.min.x += this->_position.x;
box.min.y += this->_position.y;
box.min.z += this->_position.z;
box.max.x += this->_position.x;
box.max.y += this->_position.y;
box.max.z += this->_position.z;
DrawBoundingBox(box, this->_debugColor);
}
}
void Model::setShader(const RAY::Shader &shader) void Model::setShader(const RAY::Shader &shader)
{ {
this->_originalShader = this->_model->materials[0].shader; this->_originalShader = this->_model->materials[0].shader;
+3
View File
@@ -87,6 +87,9 @@ namespace RAY::Drawables::Drawables3D {
void drawOn(RAY::Window &) override; void drawOn(RAY::Window &) override;
//! @brief Draw model's wires on window
void drawWiresOn(RAY::Window &) override;
private: private:
//! @brief Raw data from raylib //! @brief Raw data from raylib
std::shared_ptr<::Model> _model; std::shared_ptr<::Model> _model;
+4 -3
View File
@@ -6,14 +6,15 @@
namespace BBM namespace BBM
{ {
LobbyComponent::LobbyComponent(WAL::Entity &entity, int playerID, WAL::Entity &readyButton) LobbyComponent::LobbyComponent(WAL::Entity &entity, int playerID, WAL::Entity &readyButton, WAL::Entity &coloredTile)
: WAL::Component(entity), : WAL::Component(entity),
playerID(playerID), playerID(playerID),
readyButton(readyButton) readyButton(readyButton),
coloredTile(coloredTile)
{} {}
WAL::Component *LobbyComponent::clone(WAL::Entity &entity) const WAL::Component *LobbyComponent::clone(WAL::Entity &entity) const
{ {
return new LobbyComponent(entity, this->playerID, this->readyButton); return new LobbyComponent(entity, this->playerID, this->readyButton, this->coloredTile);
} }
} }
+3 -1
View File
@@ -25,13 +25,15 @@ namespace BBM
bool ready = false; bool ready = false;
//! @brief The entity containing the ready display. //! @brief The entity containing the ready display.
WAL::Entity &readyButton; WAL::Entity &readyButton;
//! @brief The colored rectangle behind the player.
WAL::Entity &coloredTile;
//! @brief The time of last input that this lobby player has made. //! @brief The time of last input that this lobby player has made.
std::chrono::time_point<std::chrono::steady_clock> lastInput; std::chrono::time_point<std::chrono::steady_clock> lastInput;
Component *clone(WAL::Entity &entity) const override; Component *clone(WAL::Entity &entity) const override;
//! @brief Create a new lobby component. //! @brief Create a new lobby component.
explicit LobbyComponent(WAL::Entity &entity, int playerID, WAL::Entity &readyButton); explicit LobbyComponent(WAL::Entity &entity, int playerID, WAL::Entity &readyButton, WAL::Entity &coloredTile);
//! @brief A lobby component is copyable. //! @brief A lobby component is copyable.
LobbyComponent(const LobbyComponent &) = default; LobbyComponent(const LobbyComponent &) = default;
//! @brief A default destructor //! @brief A default destructor
+4 -1
View File
@@ -9,6 +9,7 @@
#include <iostream> #include <iostream>
#include <Items/Bonus.hpp> #include <Items/Bonus.hpp>
#include <Component/Levitate/LevitateComponent.hpp> #include <Component/Levitate/LevitateComponent.hpp>
#include "Component/Movable/MovableComponent.hpp"
#include <Component/Timer/TimerComponent.hpp> #include <Component/Timer/TimerComponent.hpp>
#include <Component/Tag/TagComponent.hpp> #include <Component/Tag/TagComponent.hpp>
@@ -53,6 +54,8 @@ namespace BBM
return; return;
wal.getScene()->scheduleNewEntity("Bonus") wal.getScene()->scheduleNewEntity("Bonus")
.addComponent<PositionComponent>(position) .addComponent<PositionComponent>(position)
.addComponent<TagComponent<Blowable>>()
.addComponent<MovableComponent>()
.addComponent<HealthComponent>(1, [](WAL::Entity &entity, WAL::Wal &wal) { .addComponent<HealthComponent>(1, [](WAL::Entity &entity, WAL::Wal &wal) {
entity.scheduleDeletion(); entity.scheduleDeletion();
}) })
@@ -165,7 +168,7 @@ namespace BBM
for (int i = 0; i < width + 1; i++) { for (int i = 0; i < width + 1; i++) {
for (int j = 0; j < height + 1; j++) { for (int j = 0; j < height + 1; j++) {
if (map[std::make_tuple(i, 0, j)] != HOLE && map[std::make_tuple(i, -1, j)] != BUMPER) if (map[std::make_tuple(i, 0, j)] != HOLE && map[std::make_tuple(i, -1, j)] != BUMPER)
scene->addEntity("Unbreakable Wall") scene->addEntity("Floor")
.addComponent<PositionComponent>(Vector3f(i, -1, j)) .addComponent<PositionComponent>(Vector3f(i, -1, j))
.addComponent<Drawable3DComponent, RAY3D::Model>(floorObj, false, .addComponent<Drawable3DComponent, RAY3D::Model>(floorObj, false,
std::make_pair(MAP_DIFFUSE, floorPng)); std::make_pair(MAP_DIFFUSE, floorPng));
+5
View File
@@ -173,6 +173,11 @@ namespace BBM
return Vector3<T>(std::round(this->x), std::round(this->y), std::round(this->z)); return Vector3<T>(std::round(this->x), std::round(this->y), std::round(this->z));
} }
[[nodiscard]] bool isNull() const
{
return this->x == 0 && this->y == 0 && this->z == 0;
}
operator RAY::Vector3() const requires(std::is_same_v<T, float>) operator RAY::Vector3() const requires(std::is_same_v<T, float>)
{ {
return RAY::Vector3(this->x, this->y, this->z); return RAY::Vector3(this->x, this->y, this->z);
+2 -3
View File
@@ -133,18 +133,17 @@ namespace BBM
entity.getComponent<Drawable2DComponent>().drawable->setColor(ORANGE); entity.getComponent<Drawable2DComponent>().drawable->setColor(ORANGE);
}); });
static const std::vector<RAY::Color> colors = { BLUE, RED, GREEN, YELLOW };
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
auto &playerTile = scene->addEntity("player tile") auto &playerTile = scene->addEntity("player tile")
.addComponent<PositionComponent>(224 * (i + 1) + 200 * i, 1080 / 3, 0) .addComponent<PositionComponent>(224 * (i + 1) + 200 * i, 1080 / 3, 0)
.addComponent<Drawable2DComponent, RAY2D::Rectangle>(RAY::Vector2(224 * (i + 1) + 200 * i, 1080 / 3), RAY::Vector2(200, 200), colors[i]); .addComponent<Drawable2DComponent, RAY2D::Rectangle>(RAY::Vector2(224 * (i + 1) + 200 * i, 1080 / 3), RAY::Vector2(200, 200), RAY::Color(0, 0, 0, 0));
auto &player = scene->addEntity("player") auto &player = scene->addEntity("player")
.addComponent<PositionComponent>(224 * (i + 1) + 200 * i, 1080 / 3, 0) .addComponent<PositionComponent>(224 * (i + 1) + 200 * i, 1080 / 3, 0)
.addComponent<Drawable2DComponent, RAY::Texture>("assets/player/icons/none.png"); .addComponent<Drawable2DComponent, RAY::Texture>("assets/player/icons/none.png");
auto &ready = scene->addEntity("ready") auto &ready = scene->addEntity("ready")
.addComponent<PositionComponent>(224 * (i + 1) + 200 * i, 1080 / 3, 0) .addComponent<PositionComponent>(224 * (i + 1) + 200 * i, 1080 / 3, 0)
.addComponent<Drawable2DComponent, RAY::Texture>(); .addComponent<Drawable2DComponent, RAY::Texture>();
player.addComponent<LobbyComponent>(i, ready); player.addComponent<LobbyComponent>(i, ready, playerTile);
} }
scene->addEntity("camera") scene->addEntity("camera")
.addComponent<PositionComponent>(8, 20, 7) .addComponent<PositionComponent>(8, 20, 7)
+36 -18
View File
@@ -22,23 +22,25 @@ namespace BBM
std::chrono::nanoseconds BombHolderSystem::explosionTimer = 2s; std::chrono::nanoseconds BombHolderSystem::explosionTimer = 2s;
void BombHolderSystem::_bombCollide(WAL::Entity &entity, void BombHolderSystem::_bombCollide(WAL::Entity &entity,
const WAL::Entity &bomb, const WAL::Entity &bomb,
CollisionComponent::CollidedAxis collidedAxis) CollisionComponent::CollidedAxis collidedAxis)
{ {
auto &bombInfo = bomb.getComponent<BasicBombComponent>(); auto &bombInfo = bomb.getComponent<BasicBombComponent>();
if (bombInfo.ignoreOwner && bombInfo.ownerID == entity.getUid()) if (bombInfo.ignoreOwner && bombInfo.ownerID == entity.getUid())
return; return;
return MapGenerator::wallCollided( entity, bomb, collidedAxis); return MapGenerator::wallCollided(entity, bomb, collidedAxis);
} }
BombHolderSystem::BombHolderSystem(WAL::Wal &wal) BombHolderSystem::BombHolderSystem(WAL::Wal &wal)
: System(wal) : System(wal)
{} {}
void BombHolderSystem::_dispatchExplosion(Vector3f position, WAL::Wal &wal, int count) void BombHolderSystem::_dispatchExplosion(const Vector3f &position,
WAL::Wal &wal,
int size,
ExpansionDirection expansionDirections)
{ {
if (count <= 0) if (size <= 0)
return; return;
wal.getScene()->scheduleNewEntity("explosion") wal.getScene()->scheduleNewEntity("explosion")
.addComponent<PositionComponent>(position) .addComponent<PositionComponent>(position)
@@ -46,8 +48,11 @@ namespace BBM
explosion.scheduleDeletion(); explosion.scheduleDeletion();
}) })
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/bombs/explosion/explosion.glb", false, .addComponent<Drawable3DComponent, RAY3D::Model>("assets/bombs/explosion/explosion.glb", false,
std::make_pair(MAP_DIFFUSE, "assets/bombs/explosion/blast.png")); std::make_pair(
wal.getSystem<EventSystem>().dispatchEvent([position, count](WAL::Wal &wal) { MAP_DIFFUSE,
"assets/bombs/explosion/blast.png"
));
wal.getSystem<EventSystem>().dispatchEvent([position, size, expansionDirections](WAL::Wal &wal) {
for (auto &[entity, pos, _] : wal.getScene()->view<PositionComponent, TagComponent<Blowable>>()) { for (auto &[entity, pos, _] : wal.getScene()->view<PositionComponent, TagComponent<Blowable>>()) {
if (pos.position.round() == position) { if (pos.position.round() == position) {
if (auto *health = entity.tryGetComponent<HealthComponent>()) if (auto *health = entity.tryGetComponent<HealthComponent>())
@@ -55,10 +60,18 @@ namespace BBM
return; return;
} }
} }
_dispatchExplosion(position + Vector3f(1, 0, 0), wal, count - 1); if (expansionDirections & ExpansionDirection::FRONT) {
_dispatchExplosion(position + Vector3f(-1, 0, 0), wal, count - 1); _dispatchExplosion(position + Vector3f{1, 0, 0}, wal, size - 1, ExpansionDirection::FRONT);
_dispatchExplosion(position + Vector3f(0, 0, 1), wal, count - 1); }
_dispatchExplosion(position + Vector3f(0, 0, -1), wal, count - 1); if (expansionDirections & ExpansionDirection::BACK) {
_dispatchExplosion(position + Vector3f{-1, 0, 0}, wal, size - 1, ExpansionDirection::BACK);
}
if (expansionDirections & ExpansionDirection::LEFT) {
_dispatchExplosion(position + Vector3f{0, 0, 1}, wal, size - 1, ExpansionDirection::LEFT);
}
if (expansionDirections & ExpansionDirection::RIGHT) {
_dispatchExplosion(position + Vector3f{0, 0, -1}, wal, size - 1, ExpansionDirection::RIGHT);
}
}); });
} }
@@ -67,7 +80,7 @@ namespace BBM
bomb.scheduleDeletion(); bomb.scheduleDeletion();
auto position = bomb.getComponent<PositionComponent>().position.round(); auto position = bomb.getComponent<PositionComponent>().position.round();
auto explosionRadius = bomb.getComponent<BasicBombComponent>().explosionRadius; auto explosionRadius = bomb.getComponent<BasicBombComponent>().explosionRadius;
_dispatchExplosion(position, wal, 3 + (explosionRadius - 3)); _dispatchExplosion(position, wal, explosionRadius);
} }
void BombHolderSystem::_spawnBomb(Vector3f position, BombHolderComponent &holder, unsigned id) void BombHolderSystem::_spawnBomb(Vector3f position, BombHolderComponent &holder, unsigned id)
@@ -76,16 +89,21 @@ namespace BBM
.addComponent<PositionComponent>(position.round()) .addComponent<PositionComponent>(position.round())
.addComponent<BasicBombComponent>(holder.damage, holder.explosionRadius, id) .addComponent<BasicBombComponent>(holder.damage, holder.explosionRadius, id)
.addComponent<TimerComponent>(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion) .addComponent<TimerComponent>(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion)
.addComponent<CollisionComponent>(WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(), .addComponent<CollisionComponent>(
&BombHolderSystem::_bombCollide, 0.25, .75) WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&BombHolderSystem::_bombCollide, 0.25, .75)
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/bombs/bomb.obj", false, .addComponent<Drawable3DComponent, RAY3D::Model>("assets/bombs/bomb.obj", false,
std::make_pair(MAP_DIFFUSE, "assets/bombs/bomb_normal.png")); std::make_pair(
MAP_DIFFUSE,
"assets/bombs/bomb_normal.png"
));
holder.damage = 1; holder.damage = 1;
holder.explosionRadius = 3; holder.explosionRadius = 3;
} }
void BombHolderSystem::onUpdate(WAL::ViewEntity<PositionComponent, BombHolderComponent, ControllableComponent> &entity, void
std::chrono::nanoseconds dtime) BombHolderSystem::onUpdate(WAL::ViewEntity<PositionComponent, BombHolderComponent, ControllableComponent> &entity,
std::chrono::nanoseconds dtime)
{ {
auto &holder = entity.get<BombHolderComponent>(); auto &holder = entity.get<BombHolderComponent>();
auto &position = entity.get<PositionComponent>(); auto &position = entity.get<PositionComponent>();
+31 -2
View File
@@ -14,6 +14,22 @@
namespace BBM namespace BBM
{ {
enum ExpansionDirection
{
UP = 1,
DOWN = 2,
LEFT = 4,
RIGHT = 8,
FRONT = 16,
BACK = 32
};
//! @brief Ta avoid explicit casting
inline ExpansionDirection operator|(ExpansionDirection a, ExpansionDirection b)
{
return static_cast<ExpansionDirection>(static_cast<int>(a) | static_cast<int>(b));
}
//! @brief The system that allow one to place bombs. //! @brief The system that allow one to place bombs.
class BombHolderSystem : public WAL::System<PositionComponent, BombHolderComponent, ControllableComponent> class BombHolderSystem : public WAL::System<PositionComponent, BombHolderComponent, ControllableComponent>
{ {
@@ -22,13 +38,23 @@ namespace BBM
void _spawnBomb(Vector3f position, BombHolderComponent &holder, unsigned id); void _spawnBomb(Vector3f position, BombHolderComponent &holder, unsigned id);
//! @brief Spawn a bomb at the specified position. //! @brief Spawn a bomb at the specified position.
static void _dispatchExplosion(Vector3f position, WAL::Wal &, int count); static void _dispatchExplosion(const Vector3f &position,
WAL::Wal &wal,
int size,
ExpansionDirection expansionDirections = ExpansionDirection::DOWN
| ExpansionDirection::UP
| ExpansionDirection::FRONT
| ExpansionDirection::BACK
| ExpansionDirection::LEFT
| ExpansionDirection::RIGHT);
//! @brief The method triggered when the bomb explode. //! @brief The method triggered when the bomb explode.
static void _bombExplosion(WAL::Entity &bomb, WAL::Wal &); static void _bombExplosion(WAL::Entity &bomb, WAL::Wal &);
//! @brief The method called when a player collide with a bomb. //! @brief The method called when a player collide with a bomb.
static void _bombCollide(WAL::Entity &entity, const WAL::Entity &wall, BBM::CollisionComponent::CollidedAxis collidedAxis); static void
_bombCollide(WAL::Entity &entity, const WAL::Entity &wall, BBM::CollisionComponent::CollidedAxis collidedAxis);
public: public:
//! @brief The explosion time of new bombs. //! @brief The explosion time of new bombs.
static std::chrono::nanoseconds explosionTimer; static std::chrono::nanoseconds explosionTimer;
@@ -39,10 +65,13 @@ namespace BBM
//! @brief A default constructor //! @brief A default constructor
explicit BombHolderSystem(WAL::Wal &wal); explicit BombHolderSystem(WAL::Wal &wal);
//! @brief A bomb holder system is copy constructable //! @brief A bomb holder system is copy constructable
BombHolderSystem(const BombHolderSystem &) = default; BombHolderSystem(const BombHolderSystem &) = default;
//! @brief A default destructor //! @brief A default destructor
~BombHolderSystem() override = default; ~BombHolderSystem() override = default;
//! @brief A bomb holder system is not assignable. //! @brief A bomb holder system is not assignable.
BombHolderSystem &operator=(const BombHolderSystem &) = delete; BombHolderSystem &operator=(const BombHolderSystem &) = delete;
}; };
+26 -14
View File
@@ -23,7 +23,7 @@ namespace BBM
return (overlapX && overlapY && overlapZ); return (overlapX && overlapY && overlapZ);
} }
void CollisionSystem::onFixedUpdate(WAL::ViewEntity<PositionComponent, CollisionComponent> &entity) void CollisionSystem::onFixedUpdate(WAL::ViewEntity<PositionComponent, CollisionComponent, MovableComponent> &entity)
{ {
unsigned int entityUid = entity->getUid(); unsigned int entityUid = entity->getUid();
auto &posA = entity.get<PositionComponent>(); auto &posA = entity.get<PositionComponent>();
@@ -33,8 +33,10 @@ namespace BBM
Vector3f pointAy = pointA; Vector3f pointAy = pointA;
Vector3f pointAz = pointA; Vector3f pointAz = pointA;
if (auto *movable = entity->tryGetComponent<MovableComponent>()) { auto &movable = entity.get<MovableComponent>();
auto vel = movable->getVelocity(); const auto &vel = movable.getVelocity();
if (!vel.isNull()) {
pointAx.x += vel.x; pointAx.x += vel.x;
pointAy.y += vel.y; pointAy.y += vel.y;
pointAz.z += vel.z; pointAz.z += vel.z;
@@ -43,13 +45,21 @@ namespace BBM
Vector3f minAx = Vector3f::min(pointAx, pointAx + colA.bound); Vector3f minAx = Vector3f::min(pointAx, pointAx + colA.bound);
Vector3f maxAx = Vector3f::max(pointAx, pointAx + colA.bound); Vector3f maxAx = Vector3f::max(pointAx, pointAx + colA.bound);
Vector3f minAy = Vector3f::min(pointAy, pointAy + colA.bound); Vector3f minAy;
Vector3f maxAy = Vector3f::max(pointAy, pointAy + colA.bound); Vector3f maxAy;
Vector3f minAz = Vector3f::min(pointAz, pointAz + colA.bound); Vector3f minAz;
Vector3f maxAz = Vector3f::max(pointAz, pointAz + colA.bound); Vector3f maxAz;
for (auto &[other, posB, colB] : this->getView()) { if (!vel.isNull()) {
minAy = Vector3f::min(pointAy, pointAy + colA.bound);
maxAy = Vector3f::max(pointAy, pointAy + colA.bound);
minAz = Vector3f::min(pointAz, pointAz + colA.bound);
maxAz = Vector3f::max(pointAz, pointAz + colA.bound);
}
for (auto &[other, posB, colB] : this->_wal.getScene()->view<PositionComponent, CollisionComponent>()) {
if (other.getUid() == entityUid) if (other.getUid() == entityUid)
continue; continue;
@@ -60,13 +70,15 @@ namespace BBM
Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound); Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound);
if (boxesCollide(minAx, maxAx, minB, maxB)) { if (boxesCollide(minAx, maxAx, minB, maxB)) {
collidedAxis += CollisionComponent::CollidedAxis::X; collidedAxis += vel.isNull() ? 7 : CollisionComponent::CollidedAxis::X;
} }
if (boxesCollide(minAy, maxAy, minB, maxB)) { if (!vel.isNull()) {
collidedAxis += CollisionComponent::CollidedAxis::Y; if (boxesCollide(minAy, maxAy, minB, maxB)) {
} collidedAxis += CollisionComponent::CollidedAxis::Y;
if (boxesCollide(minAz, maxAz, minB, maxB)) { }
collidedAxis += CollisionComponent::CollidedAxis::Z; if (boxesCollide(minAz, maxAz, minB, maxB)) {
collidedAxis += CollisionComponent::CollidedAxis::Z;
}
} }
if (collidedAxis) { if (collidedAxis) {
colA.onCollide(entity, other, static_cast<CollisionComponent::CollidedAxis>(collidedAxis)); colA.onCollide(entity, other, static_cast<CollisionComponent::CollidedAxis>(collidedAxis));
+3 -2
View File
@@ -10,16 +10,17 @@
#include "System/System.hpp" #include "System/System.hpp"
#include "Models/Vector3.hpp" #include "Models/Vector3.hpp"
#include "Component/Collision/CollisionComponent.hpp" #include "Component/Collision/CollisionComponent.hpp"
#include "Component/Movable/MovableComponent.hpp"
#include "Component/Position/PositionComponent.hpp" #include "Component/Position/PositionComponent.hpp"
namespace BBM namespace BBM
{ {
//! @brief A system to handle collisions. //! @brief A system to handle collisions.
class CollisionSystem : public WAL::System<PositionComponent, CollisionComponent> class CollisionSystem : public WAL::System<PositionComponent, CollisionComponent, MovableComponent>
{ {
public: public:
//! @inherit //! @inherit
void onFixedUpdate(WAL::ViewEntity<PositionComponent, CollisionComponent> &entity) override; void onFixedUpdate(WAL::ViewEntity<PositionComponent, CollisionComponent, MovableComponent> &entity) override;
//! @brief A default constructor //! @brief A default constructor
explicit CollisionSystem(WAL::Wal &wal); explicit CollisionSystem(WAL::Wal &wal);
+28 -10
View File
@@ -19,7 +19,7 @@ namespace RAY3D = RAY::Drawables::Drawables3D;
namespace BBM namespace BBM
{ {
std::vector<std::string> LobbySystem::_colors = { std::array<std::string, 4> LobbySystem::_colors = {
"blue", "blue",
"red", "red",
"green", "green",
@@ -28,6 +28,15 @@ namespace BBM
"yellow" "yellow"
}; };
std::array<RAY::Color, 4> LobbySystem::_rayColors = {
BLUE,
RED,
GREEN,
// PURPLE,
// SKYBLUE,
YELLOW
};
LobbySystem::LobbySystem(WAL::Wal &wal) LobbySystem::LobbySystem(WAL::Wal &wal)
: System(wal) : System(wal)
{} {}
@@ -35,7 +44,16 @@ namespace BBM
void LobbySystem::_nextColor(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity) void LobbySystem::_nextColor(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity)
{ {
auto &lobby = entity.get<LobbyComponent>(); auto &lobby = entity.get<LobbyComponent>();
if (lobby.color != -1)
this->_colorTaken[lobby.color] = false;
do {
lobby.color++;
if (lobby.color >= this->_colorTaken.size())
lobby.color = 0;
} while (this->_colorTaken[lobby.color]);
this->_colorTaken[lobby.color] = true;
entity.get<Drawable2DComponent>().drawable = std::make_shared<RAY::Texture>("assets/player/icons/" + _colors[lobby.color] + ".png"); entity.get<Drawable2DComponent>().drawable = std::make_shared<RAY::Texture>("assets/player/icons/" + _colors[lobby.color] + ".png");
lobby.coloredTile.getComponent<Drawable2DComponent>().drawable->setColor(_rayColors[lobby.color]);
} }
void LobbySystem::onUpdate(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity, std::chrono::nanoseconds dtime) void LobbySystem::onUpdate(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity, std::chrono::nanoseconds dtime)
@@ -55,21 +73,19 @@ namespace BBM
})) }))
return; return;
lobby.lastInput = lastTick; lobby.lastInput = lastTick;
lobby.color = 0; lobby.color = -1;
entity.get<Drawable2DComponent>().drawable = std::make_shared<RAY::Texture>("assets/player/icons/" + _colors[lobby.color] + ".png"); this->_nextColor(entity);
// this->_nextColor(entity);
lobby.layout = controller.layout; lobby.layout = controller.layout;
controller.jump = false; controller.jump = false;
return; return;
} }
// if (controller.bomb)
// this->_nextColor(entity);
} }
} }
for (auto &[_, controller] : this->_wal.getScene()->view<ControllableComponent>()) { for (auto &[_, controller] : this->_wal.getScene()->view<ControllableComponent>()) {
if (controller.layout == lobby.layout && controller.jump && !lobby.ready) { if (controller.layout != lobby.layout)
continue;
if (controller.jump && !lobby.ready) {
lobby.ready = true; lobby.ready = true;
lobby.lastInput = lastTick; lobby.lastInput = lastTick;
controller.jump = false; controller.jump = false;
@@ -78,11 +94,13 @@ namespace BBM
if (texture) if (texture)
texture->use("assets/player/icons/ready.png"); texture->use("assets/player/icons/ready.png");
} }
if (controller.bomb && !lobby.ready) {
lobby.lastInput = lastTick;
this->_nextColor(entity);
}
} }
} }
void LobbySystem::onSelfUpdate() void LobbySystem::onSelfUpdate()
{ {
auto &view = this->_wal.getScene()->view<TagComponent<"PlayButton">, Drawable2DComponent>(); auto &view = this->_wal.getScene()->view<TagComponent<"PlayButton">, Drawable2DComponent>();
+6 -2
View File
@@ -20,9 +20,13 @@ namespace BBM
//! @brief Add a controller for the player. //! @brief Add a controller for the player.
static void _addController(WAL::Entity &player, ControllableComponent::Layout layout); static void _addController(WAL::Entity &player, ControllableComponent::Layout layout);
static void _nextColor(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity); void _nextColor(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity);
static std::vector<std::string> _colors; static std::array<std::string, 4> _colors;
static std::array<RAY::Color, 4> _rayColors;
std::array<bool, 4> _colorTaken = {};
public: public:
//! @inherit //! @inherit
void onUpdate(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity, std::chrono::nanoseconds dtime) override; void onUpdate(WAL::ViewEntity<LobbyComponent, Drawable2DComponent> &entity, std::chrono::nanoseconds dtime) override;
+19 -3
View File
@@ -11,8 +11,8 @@
#include <Model/Model.hpp> #include <Model/Model.hpp>
#include "Drawables/ADrawable3D.hpp" #include "Drawables/ADrawable3D.hpp"
#include "Component/Shaders/ShaderComponent.hpp" #include "Component/Shaders/ShaderComponent.hpp"
#include <Drawables/3D/Cube.hpp>
#include "Models/Vector3.hpp"
#include "Component/Collision/CollisionComponent.hpp" #include "Component/Collision/CollisionComponent.hpp"
namespace BBM namespace BBM
@@ -26,6 +26,20 @@ namespace BBM
this->_window.setFPS(this->FPS); this->_window.setFPS(this->FPS);
} }
void RenderSystem::drawBoundingBox(const WAL::Entity &entity, const PositionComponent &posComponent, const Drawable3DComponent &drawable) const
{
auto *dimsComponent = entity.tryGetComponent<CollisionComponent>();
//draws hitbox
if (dimsComponent) {
RAY::Drawables::Drawables3D::Cube boundingBox(posComponent.position, dimsComponent->bound, WHITE);
boundingBox.setDebugColor(RED);
boundingBox.drawWiresOn(this->_window);
}
//draws models contours
drawable.drawable->drawWiresOn(this->_window);
}
void RenderSystem::onSelfUpdate() void RenderSystem::onSelfUpdate()
{ {
this->_camera.update(); this->_camera.update();
@@ -42,6 +56,8 @@ namespace BBM
drawable.drawable->drawOn(this->_window); drawable.drawable->drawOn(this->_window);
if (modelShader) if (modelShader)
modelShader->model->resetShader(); modelShader->model->resetShader();
if (this->_debugMode)
this->drawBoundingBox(entity, pos, drawable);
} }
this->_window.unuseCamera(); this->_window.unuseCamera();
@@ -59,7 +75,7 @@ namespace BBM
} }
} }
if (this->_debugMode) if (this->_debugMode)
this->_window.drawFPS(Vector2f()); this->_window.drawFPS(Vector2f(10, 10));
this->_window.endDrawing(); this->_window.endDrawing();
} }
+4
View File
@@ -6,6 +6,7 @@
#include "Component/Renderer/CameraComponent.hpp" #include "Component/Renderer/CameraComponent.hpp"
#include "Component/Position/PositionComponent.hpp" #include "Component/Position/PositionComponent.hpp"
#include "Component/Renderer/Drawable3DComponent.hpp"
#include "System/System.hpp" #include "System/System.hpp"
#include "Camera/Camera2D.hpp" #include "Camera/Camera2D.hpp"
#include "Window.hpp" #include "Window.hpp"
@@ -39,6 +40,9 @@ namespace BBM
//! @param debug true if debug mode should be enabled //! @param debug true if debug mode should be enabled
void setDebug(bool debug); void setDebug(bool debug);
//! @param entity entity to draw bounding box of
void drawBoundingBox(const WAL::Entity &entity, const PositionComponent &posComponent, const Drawable3DComponent &drawable) const;
//! @brief ctor //! @brief ctor
RenderSystem(WAL::Wal &wal, RAY::Window &window, bool debugMode = false); RenderSystem(WAL::Wal &wal, RAY::Window &window, bool debugMode = false);
//! @brief Default copy ctor //! @brief Default copy ctor
+57
View File
@@ -17,6 +17,8 @@
using namespace WAL; using namespace WAL;
using namespace BBM; using namespace BBM;
// WARN THE COLLISION SYSTEM IS ONLY CHECKING/LOOPING ON MOVABLE ENTITIES
TEST_CASE("Collision test", "[Component][System]") TEST_CASE("Collision test", "[Component][System]")
{ {
@@ -25,6 +27,7 @@ TEST_CASE("Collision test", "[Component][System]")
wal.changeScene(std::make_shared<Scene>()); wal.changeScene(std::make_shared<Scene>());
wal.getScene()->addEntity("player") wal.getScene()->addEntity("player")
.addComponent<PositionComponent>() .addComponent<PositionComponent>()
.addComponent<MovableComponent>()
.addComponent<CollisionComponent>([](Entity &actual, const Entity &, int _) { .addComponent<CollisionComponent>([](Entity &actual, const Entity &, int _) {
try { try {
auto &pos = actual.getComponent<PositionComponent>(); auto &pos = actual.getComponent<PositionComponent>();
@@ -118,6 +121,7 @@ TEST_CASE("Collision test callbacks calls", "[Component][System]")
wal.getScene()->addEntity("block") wal.getScene()->addEntity("block")
.addComponent<PositionComponent>(0, 0, 0) .addComponent<PositionComponent>(0, 0, 0)
.addComponent<MovableComponent>()
.addComponent<CollisionComponent>( .addComponent<CollisionComponent>(
[&nbCallbacksCalled](Entity &actual, const Entity &, int) { nbCallbacksCalled++; }, [&nbCallbacksCalled](Entity &actual, const Entity &, int) { nbCallbacksCalled++; },
[&nbCallbacksCalled](Entity &actual, const Entity &, int) { [&nbCallbacksCalled](Entity &actual, const Entity &, int) {
@@ -156,6 +160,7 @@ TEST_CASE("Collision test callbacks args", "[Component][System]")
wal.getScene()->addEntity("player") wal.getScene()->addEntity("player")
.addComponent<PositionComponent>() .addComponent<PositionComponent>()
.addComponent<MovableComponent>()
.addComponent<CollisionComponent>( .addComponent<CollisionComponent>(
[&nbCallbacksCalled](Entity &actual, const Entity &other, int) { [&nbCallbacksCalled](Entity &actual, const Entity &other, int) {
nbCallbacksCalled++; nbCallbacksCalled++;
@@ -170,6 +175,7 @@ TEST_CASE("Collision test callbacks args", "[Component][System]")
wal.getScene()->addEntity("block") wal.getScene()->addEntity("block")
.addComponent<PositionComponent>(0, 0, 0) .addComponent<PositionComponent>(0, 0, 0)
.addComponent<MovableComponent>()
.addComponent<CollisionComponent>( .addComponent<CollisionComponent>(
[&nbCallbacksCalled](Entity &actual, const Entity &other, int) { [&nbCallbacksCalled](Entity &actual, const Entity &other, int) {
nbCallbacksCalled++; nbCallbacksCalled++;
@@ -193,6 +199,57 @@ TEST_CASE("Collision test callbacks args", "[Component][System]")
REQUIRE(nbCallbacksCalled == 4); REQUIRE(nbCallbacksCalled == 4);
} }
TEST_CASE("Collision test callbacks args with only one movable entity", "[Component][System]")
{
int nbCallbacksCalled = 0;
Wal wal;
CollisionSystem collision(wal);
MovableSystem movable(wal);
wal.changeScene(std::make_shared<Scene>());
wal.getScene()->addEntity("player")
.addComponent<PositionComponent>()
.addComponent<MovableComponent>()
.addComponent<CollisionComponent>(
[&nbCallbacksCalled](Entity &actual, const Entity &other, int) {
nbCallbacksCalled++;
REQUIRE(actual.getName() == "player");
REQUIRE(other.getName() == "block");
},
[&nbCallbacksCalled](Entity &actual, const Entity &other, int) {
// lambda should not be called
nbCallbacksCalled++;
REQUIRE(other.getName() == "plfayer");
REQUIRE(actual.getName() == "blofck");
}, 0, 5.0);
wal.getScene()->addEntity("block")
.addComponent<PositionComponent>(0, 0, 0)
.addComponent<CollisionComponent>(
[&nbCallbacksCalled](Entity &actual, const Entity &other, int) {
// lambda should not be called
nbCallbacksCalled++;
REQUIRE(other.getName() == "playefr");
REQUIRE(actual.getName() == "blocfk");
},
[&nbCallbacksCalled](Entity &actual, const Entity &other, int) {
nbCallbacksCalled++;
REQUIRE(actual.getName() == "player");
REQUIRE(other.getName() == "block");
}, 0, 1);
Entity &entity = wal.getScene()->getEntities().front();
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.update(std::chrono::nanoseconds(1));
collision.fixedUpdate();
REQUIRE(nbCallbacksCalled == 2);
}
TEST_CASE("Vector round", "[Vector]") TEST_CASE("Vector round", "[Vector]")
{ {
Vector3f v(1.3, 1.5, 1.7); Vector3f v(1.3, 1.5, 1.7);