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

# Conflicts:
#	CMakeLists.txt
#	sources/Runner/Runner.cpp
This commit is contained in:
Clément Le Bihan
2021-06-08 16:29:57 +02:00
25 changed files with 544 additions and 51 deletions
+16 -5
View File
@@ -10,8 +10,6 @@ include_directories(bomberman sources)
add_subdirectory(${PROJECT_SOURCE_DIR}/lib/wal)
add_subdirectory(${PROJECT_SOURCE_DIR}/lib/Ray)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
if (EMSCRIPTEN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
@@ -31,7 +29,9 @@ set(SOURCES
sources/Component/Movable/MovableComponent.hpp
sources/Component/Controllable/ControllableComponent.hpp
sources/Component/Controllable/ControllableComponent.cpp
sources/Component/Gamepad/GamepadComponent.cpp
sources/Component/BombHolder/BombHolderComponent.cpp
sources/Component/BombHolder/BombHolderComponent.hpp
sources/Component/Gamepad/GamepadComponent.cpp
sources/Component/Gamepad/GamepadComponent.hpp
sources/Component/Keyboard/KeyboardComponent.cpp
sources/Component/Keyboard/KeyboardComponent.hpp
@@ -61,6 +61,14 @@ set(SOURCES
sources/System/Renderer/RenderSystem.cpp
sources/Component/Renderer/CameraComponent.cpp
sources/Component/Renderer/CameraComponent.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
sources/System/Event/EventSystem.cpp
sources/System/Event/EventSystem.hpp
sources/Component/Animation/AnimationsComponent.cpp
sources/Component/Animation/AnimationsComponent.hpp
sources/System/Animation/AnimationsSystem.cpp
@@ -73,11 +81,14 @@ set(SOURCES
sources/Component/Animator/AnimatorComponent.hpp
sources/System/Animator/AnimatorSystem.cpp
sources/System/Animator/AnimatorSystem.hpp
sources/Component/Shaders/ShaderComponent.cpp sources/Component/Shaders/ShaderComponent.hpp)
sources/Component/Shaders/ShaderComponent.cpp
sources/Component/Shaders/ShaderComponent.hpp
)
add_executable(bomberman
sources/main.cpp
${SOURCES}
)
)
target_include_directories(bomberman PUBLIC sources)
target_link_libraries(bomberman PUBLIC wal ray)
+27 -9
View File
@@ -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);
@@ -50,21 +52,27 @@ namespace WAL
Entity &Entity::addComponent(const Component &component)
{
const std::type_index &type = typeid(component);
if (this->hasComponent(type))
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;
}
bool Entity::hasComponent(const std::type_info &type) const
bool Entity::hasComponent(const std::type_info &type, bool skipDisabled) const
{
return this->hasComponent(static_cast<const std::type_index &>(type));
return this->hasComponent(static_cast<const std::type_index &>(type), skipDisabled);
}
bool Entity::hasComponent(const std::type_index &type) const
bool Entity::hasComponent(const std::type_index &type, bool skipDisabled) const
{
return this->_components.contains(type);
auto cmp = this->_components.find(type);
if (cmp == this->_components.end())
return false;
if (skipDisabled)
return !cmp->second->isDisabled();
return true;
}
void Entity::_componentAdded(const std::type_index &type)
@@ -76,4 +84,14 @@ namespace WAL
{
this->_scene._componentRemoved(*this, type);
}
bool Entity::shouldDelete() const
{
return this->_shouldDelete;
}
void Entity::scheduleDeletion()
{
this->_shouldDelete = true;
}
} // namespace WAL
+23 -8
View File
@@ -26,6 +26,10 @@ namespace WAL
std::string _name;
//! @brief Is this entity enabled?
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<std::type_index, std::unique_ptr<Component>> _components = {};
@@ -38,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;
@@ -49,10 +55,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
//! @tparam The type of the component
//! @throw NotFoundError if the component could not be found
@@ -106,21 +116,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<typename T>
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.
@@ -132,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<T>(*this, TypeHolder<TNested>()..., std::forward<Types>(params)...);
this->_componentAdded(type);
if (this->_notifyScene)
this->_componentAdded(type);
return *this;
}
@@ -151,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.
+32
View File
@@ -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) {
@@ -45,4 +50,31 @@ namespace WAL
view->erase(entity);
}
}
void Scene::_entityRemoved(const Entity &entity)
{
for (auto &view : this->_views)
view->erase(entity);
}
void Scene::applyChanges()
{
this->_entities.remove_if([this](auto &entity) {
if (!entity.shouldDelete())
return false;
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
+13
View File
@@ -23,6 +23,8 @@ namespace WAL
//! @brief The list of registered entities
std::list<Entity> _entities = {};
//! @brief The list of entities to add on the next call to applyChanges.
std::list<Entity> _newEntities = {};
//! @brief The list of cached views to update.
std::vector<std::shared_ptr<IView>> _views = {};
@@ -34,6 +36,9 @@ namespace WAL
//! @param entity The entity with the removed component
//! @param type The type of the component removed.
void _componentRemoved(const Entity &entity, const std::type_index &type);
//! @brief Remove an entity from every views.
//! @param entity The entity to remove.
void _entityRemoved(const Entity &entity);
public:
//! @brief Get the list of entities.
std::list<Entity> &getEntities();
@@ -43,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<typename ...Components>
View<Components...> &view()
{
@@ -56,6 +66,9 @@ namespace WAL
return *view;
}
//! @brief Delete entities marked as deleted and create scheduled entities.
void applyChanges();
//! @brief A default constructor
Scene() = default;
//! @brief A scene is copy constructable
+3 -3
View File
@@ -178,9 +178,9 @@ 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;
}));
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());
}
//! @brief Construct a view from a list of entities.
+2
View File
@@ -52,6 +52,7 @@ namespace WAL
}
for (auto &system : this->_systems)
system->update(dtime);
this->scene->applyChanges();
callback(*this, state);
}
}
@@ -75,6 +76,7 @@ namespace WAL
}
for (auto &system : wal._systems)
system->update(dtime);
wal.scene->applyChanges();
callback(wal, state);
}
#endif
@@ -0,0 +1,24 @@
//
// Created by Tom Augier on 2021-05-20.
// Edited by Benjamin Henry on 2021-05-20.
// Edited by Louis Auzuret on 2021-05-20.
//
#include "BombHolderComponent.hpp"
namespace BBM
{
BombHolderComponent::BombHolderComponent(WAL::Entity &entity)
: WAL::Component(entity)
{}
BombHolderComponent::BombHolderComponent(WAL::Entity &entity, unsigned int maxBombCount)
: WAL::Component(entity),
maxBombCount(maxBombCount)
{}
WAL::Component *BombHolderComponent::clone(WAL::Entity &entity) const
{
return new BombHolderComponent(entity, this->maxBombCount);
}
}
@@ -0,0 +1,47 @@
//
// Created by Tom Augier on 2021-05-20.
// Edited by Benjamin Henry on 2021-05-20.
// Edited by Louis Auzuret on 2021-05-20.
//
#pragma once
#include "Component/Component.hpp"
#include "Entity/Entity.hpp"
#include <chrono>
using namespace std::chrono_literals;
namespace BBM
{
class BombHolderComponent : public WAL::Component
{
public:
//! @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 = 5000ms;
//! @brief The number of nanosecond before the next bomb refill.
std::chrono::nanoseconds nextBombRefill = refillRate;
//! @inherit
WAL::Component *clone(WAL::Entity &entity) const override;
//! @brief A component can't be instantiated, it should be derived.
explicit BombHolderComponent(WAL::Entity &entity);
//! @brief Constructor
BombHolderComponent(WAL::Entity &entity, unsigned int maxBombCount);
//! @brief A component can't be instantiated, it should be derived.
BombHolderComponent(const BombHolderComponent &) = default;
//! @brief default destructor
~BombHolderComponent() override = default;
//! @brief A component can't be assigned
BombHolderComponent &operator=(const BombHolderComponent &) = delete;
};
}
+5 -5
View File
@@ -10,15 +10,15 @@
namespace BBM
{
HealthComponent::HealthComponent(WAL::Entity &entity, unsigned int healthPoint, std::function<void (WAL::Entity &)> callback)
: WAL::Component(entity),
_healthPoint(healthPoint),
onDeath(std::move(callback))
HealthComponent::HealthComponent(WAL::Entity &entity, unsigned int healthPoint, const WAL::Callback<WAL::Entity &> &onDeath)
: WAL::Component(entity),
_healthPoint(healthPoint),
onDeath(onDeath)
{}
WAL::Component *HealthComponent::clone(WAL::Entity &entity) const
{
return new HealthComponent(entity);
return new HealthComponent(entity, this->_healthPoint, this->onDeath);
}
void HealthComponent::addHealthPoint(unsigned int healthPoint)
+1 -1
View File
@@ -36,7 +36,7 @@ namespace BBM
WAL::Component *clone(WAL::Entity &entity) const override;
//! @brief Constructor
explicit HealthComponent(WAL::Entity &entity, unsigned int healthPoint = 1, std::function<void (WAL::Entity &)> callback = {});
HealthComponent(WAL::Entity &entity, unsigned int healthPoint, const WAL::Callback<WAL::Entity &> &onDeath = WAL::Callback<WAL::Entity &>());
//! @brief A Health component can't be instantiated, it should be derived.
HealthComponent(const HealthComponent &) = default;
@@ -0,0 +1,26 @@
//
// Created by Zoe Roux on 5/31/21.
//
#include "TimerComponent.hpp"
#include <utility>
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<WAL::Entity &, WAL::Wal &> &callback)
: WAL::Component(entity),
ringIn(delay),
callback(callback)
{}
WAL::Component *TimerComponent::clone(WAL::Entity &entity) const
{
return new TimerComponent(entity, this->ringIn, this->callback);
}
}
@@ -0,0 +1,36 @@
//
// Created by Zoe Roux on 5/31/21.
//
#pragma once
#include <Component/Component.hpp>
#include <chrono>
#include <Wal.hpp>
#include "Models/Callback.hpp"
namespace BBM
{
//! @brief
class TimerComponent : public WAL::Component
{
public:
//! @brief The callback to call when the timer ring.
WAL::Callback<WAL::Entity &, WAL::Wal &> 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<WAL::Entity &, WAL::Wal &> &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;
};
}
+14 -9
View File
@@ -20,14 +20,19 @@ namespace BBM
const auto &wallPos = wall.getComponent<PositionComponent>();
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;
}
void MapGenerator::wallDestroyed(WAL::Entity &entity)
{
entity.scheduleDeletion();
}
const std::string MapGenerator::assetsPath = "./assets/";
@@ -134,7 +139,7 @@ namespace BBM
scene->addEntity("Breakable Block")
.addComponent<PositionComponent>(coords)
.addComponent<HealthComponent>(1)
.addComponent<HealthComponent>(1, &MapGenerator::wallDestroyed)
.addComponent<CollisionComponent>(WAL::Callback<WAL::Entity &, const WAL::Entity &>(), &MapGenerator::wallCollide, .75)
.addComponent<Drawable3DComponent, RAY3D::Model>(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng));
}
+1
View File
@@ -157,6 +157,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
+17 -8
View File
@@ -10,22 +10,26 @@
#include <Drawables/3D/Cube.hpp>
#include <Drawables/2D/Rectangle.hpp>
#include <TraceLog.hpp>
#include <System/Keyboard/KeyboardSystem.hpp>
#include <System/Controllable/ControllableSystem.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 <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>
#include "Component/Renderer/CameraComponent.hpp"
#include "Component/Renderer/Drawable3DComponent.hpp"
#include "Runner.hpp"
#include "Models/GameState.hpp"
#include <Model/ModelAnimations.hpp>
#include <Component/Animator/AnimatorComponent.hpp>
#include <System/Timer/TimerSystem.hpp>
#include <System/BombHolder/BombHolderSystem.hpp>
#include <System/Event/EventSystem.hpp>
#include <System/Health/HealthSystem.hpp>
#include <System/Animator/AnimatorSystem.hpp>
#include <Component/Renderer/Drawable2DComponent.hpp>
#include <Component/Animator/AnimatorComponent.hpp>
#include "Component/Animation/AnimationsComponent.hpp"
#include "System/Animation/AnimationsSystem.hpp"
#include "Component/Shaders/ShaderComponent.hpp"
@@ -48,9 +52,13 @@ namespace BBM
void addSystems(WAL::Wal &wal)
{
wal.addSystem<KeyboardSystem>()
wal.addSystem<TimerSystem>()
.addSystem<KeyboardSystem>()
.addSystem<GamepadSystem>()
.addSystem<ControllableSystem>()
.addSystem<BombHolderSystem>()
.addSystem<EventSystem>()
.addSystem<HealthSystem>()
.addSystem<CollisionSystem>()
.addSystem<MovableSystem>();
}
@@ -77,6 +85,7 @@ namespace BBM
.addComponent<AnimationsComponent>(RAY::ModelAnimations("assets/player/player.iqm"), 3)
.addComponent<CollisionComponent>(1)
.addComponent<MovableComponent>()
.addComponent<BombHolderComponent>()
.addComponent<HealthComponent>(1, [](WAL::Entity &entity) {
auto &animation = entity.getComponent<AnimationsComponent>();
animation.setAnimIndex(5);
@@ -0,0 +1,67 @@
//
// Created by Zoe Roux on 5/31/21.
//
#include "Component/Timer/TimerComponent.hpp"
#include "System/Event/EventSystem.hpp"
#include "Component/Renderer/Drawable3DComponent.hpp"
#include "BombHolderSystem.hpp"
#include "Component/Health/HealthComponent.hpp"
using namespace std::chrono_literals;
namespace RAY3D = RAY::Drawables::Drawables3D;
namespace BBM
{
std::chrono::nanoseconds BombHolderSystem::explosionTimer = 3s;
float BombHolderSystem::explosionRadius = 3;
BombHolderSystem::BombHolderSystem(WAL::Wal &wal)
: System(wal)
{}
void BombHolderSystem::_bombExplosion(WAL::Entity &bomb, WAL::Wal &wal)
{
bomb.scheduleDeletion();
auto &bombPosition = bomb.getComponent<PositionComponent>();
wal.getSystem<EventSystem>().dispatchEvent([&bombPosition](WAL::Entity &entity){
auto *health = entity.tryGetComponent<HealthComponent>();
auto *pos = entity.tryGetComponent<PositionComponent>();
if (!health || !pos)
return;
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);
});
}
void BombHolderSystem::_spawnBomb(Vector3f position)
{
this->_wal.scene->scheduleNewEntity("Bomb")
.addComponent<PositionComponent>(position)
.addComponent<TimerComponent>(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion)
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/bombs/bomb.obj",
std::make_pair(MAP_DIFFUSE, "assets/bombs/bomb_normal.png"));
}
void BombHolderSystem::onUpdate(WAL::ViewEntity<PositionComponent, BombHolderComponent, ControllableComponent> &entity, std::chrono::nanoseconds dtime)
{
auto &holder = entity.get<BombHolderComponent>();
auto &position = entity.get<PositionComponent>();
auto &controllable = entity.get<ControllableComponent>();
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++;
}
}
}
}
@@ -0,0 +1,43 @@
//
// Created by Zoe Roux on 5/31/21.
//
#pragma once
#include <System/System.hpp>
#include <Wal.hpp>
#include "Models/Vector3.hpp"
#include "Component/Position/PositionComponent.hpp"
#include "Component/BombHolder/BombHolderComponent.hpp"
#include "Component/Controllable/ControllableComponent.hpp"
namespace BBM
{
//! @brief The system that allow one to place bombs.
class BombHolderSystem : public WAL::System<PositionComponent, BombHolderComponent, ControllableComponent>
{
private:
//! @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, 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::ViewEntity<PositionComponent, BombHolderComponent, ControllableComponent> &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;
};
}
+28
View File
@@ -0,0 +1,28 @@
//
// Created by Zoe Roux on 6/1/21.
//
#include "EventSystem.hpp"
namespace BBM
{
EventSystem::EventSystem(WAL::Wal &wal)
: System(wal)
{}
void EventSystem::dispatchEvent(const std::function<void(WAL::Entity &)> &event)
{
this->_events.emplace_back(event);
}
void EventSystem::onUpdate(WAL::ViewEntity<> &entity, std::chrono::nanoseconds)
{
for (auto &event : this->_events)
event(entity);
}
void EventSystem::onSelfUpdate()
{
this->_events.clear();
}
}
+36
View File
@@ -0,0 +1,36 @@
//
// Created by Zoe Roux on 6/1/21.
//
#pragma once
#include <System/System.hpp>
#include <vector>
#include <functional>
namespace BBM
{
class EventSystem : public WAL::System<>
{
private:
//! @brief The list of events that occurred in the last update.
std::vector<std::function<void (WAL::Entity &)>> _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<void (WAL::Entity &)>& event);
//! @inherit
void onUpdate(WAL::ViewEntity<> &entity, std::chrono::nanoseconds dtime) override;
//! @inherit
void onSelfUpdate() override;
//! @brief A default constructor
explicit EventSystem(WAL::Wal &wal);
//! @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;
};
}
+2 -2
View File
@@ -16,7 +16,7 @@ namespace BBM
: System(wal)
{}
void KeyboardSystem::onFixedUpdate(WAL::ViewEntity<KeyboardComponent, ControllableComponent> &entity)
void KeyboardSystem::onUpdate(WAL::ViewEntity<KeyboardComponent, ControllableComponent> &entity, std::chrono::nanoseconds)
{
const auto &keyboard = entity.get<KeyboardComponent>();
auto &controllable = entity.get<ControllableComponent>();
@@ -28,7 +28,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;
+1 -1
View File
@@ -17,7 +17,7 @@ namespace BBM
{
public:
//! @inherit
void onFixedUpdate(WAL::ViewEntity<KeyboardComponent, ControllableComponent> &entity) override;
void onUpdate(WAL::ViewEntity<KeyboardComponent, ControllableComponent> &entity, std::chrono::nanoseconds) override;
//! @brief A default constructor
explicit KeyboardSystem(WAL::Wal &wal);
+25
View File
@@ -0,0 +1,25 @@
//
// 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::Wal &wal)
: System(wal)
{}
void TimerSystem::onUpdate(WAL::ViewEntity<TimerComponent> &entity, std::chrono::nanoseconds dtime)
{
auto &timer = entity.get<TimerComponent>();
timer.ringIn -= dtime;
if (timer.ringIn <= 0ns) {
timer.setDisable(true);
timer.callback(entity, this->_wal);
}
}
}
+28
View File
@@ -0,0 +1,28 @@
//
// Created by Zoe Roux on 5/31/21.
//
#pragma once
#include <System/System.hpp>
#include <Wal.hpp>
#include <Component/Timer/TimerComponent.hpp>
namespace BBM
{
class TimerSystem : public WAL::System<TimerComponent>
{
public:
//! @inherit
void onUpdate(WAL::ViewEntity<TimerComponent> &entity, std::chrono::nanoseconds dtime) override;
//! @brief A default constructor
TimerSystem(WAL::Wal &);
//! @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;
};
}
+27
View File
@@ -50,6 +50,33 @@ TEST_CASE("View cache", "[View]")
REQUIRE(&view == &scene.view<PositionComponent>());
}
TEST_CASE("View add entity", "[View]")
{
Scene scene;
auto &entity = scene.addEntity("player")
.addComponent<PositionComponent>()
.addComponent<ControllableComponent>();
REQUIRE(scene.view<PositionComponent>().size() == 1);
scene.scheduleNewEntity("test")
.addComponent<PositionComponent>();
scene.applyChanges();
REQUIRE(scene.view<PositionComponent>().size() == 2);
}
TEST_CASE("View remove entity", "[View]")
{
Scene scene;
auto &entity = scene.addEntity("player")
.addComponent<PositionComponent>()
.addComponent<ControllableComponent>();
REQUIRE(scene.view<PositionComponent>().size() == 1);
entity.scheduleDeletion();
scene.applyChanges();
REQUIRE(scene.view<PositionComponent>().size() == 0);
for (auto &it : scene.view<PositionComponent>())
REQUIRE(false);
}
TEST_CASE("View cache switch", "[View]")
{
Scene scene;