mirror of
https://github.com/zoriya/Bomberman.git
synced 2026-06-02 02:05:25 +00:00
Merge branch 'develop' of github.com:AnonymusRaccoon/Bomberman into shader_non_broken
# Conflicts: # CMakeLists.txt # sources/Runner/Runner.cpp
This commit is contained in:
+16
-5
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user