diff --git a/source/game/Game.cpp b/source/game/Game.cpp index badff2fce4c12ed25a9e8f2806c2781f871ad2f5..0b838bb17b94bfd3f0f76ea8d3482981ea2fb2d5 100644 --- a/source/game/Game.cpp +++ b/source/game/Game.cpp @@ -5,6 +5,7 @@ #include <game/back/object/Player.hpp> #include <game/back/object/Enemy.hpp> +#include <game/back/object/Level.hpp> #include <game/object/Test.hpp> #include <game/utility/FrameCouter.hpp> @@ -28,25 +29,25 @@ namespace megu::game { Player player(16, 16, 16, 16, path); Enemy enemy(64, 64, 16, 16, path); - - player.setup(kernel); - enemy.setup(kernel); - std::cout << "..." << std::endl; + Level level("STZ"); + level.add(&player); + level.add(&enemy); + - player.apply(kernel); - enemy.apply(kernel); + player.setup(kernel, level); + player.apply(kernel); - //kernel.remove(&object); + enemy.setup(kernel, level); + enemy.apply(kernel); + + std::cout << "..." << std::endl; while(window.isOpen()) { counter.count(Window::Time()); window.pollEvents(); kernel.step(); } - - player.destroy(kernel); - enemy.destroy(kernel); } catch(std::exception & error) { std::cerr << "[Error] : " << error.what() << std::endl; diff --git a/source/game/back/GameObject.hpp b/source/game/back/GameObject.hpp index 29ec8a7343198b83752630b46d4b9df8e7ebd9e9..d587ea1cb39eb65b1632ab2487101386526b0cf0 100644 --- a/source/game/back/GameObject.hpp +++ b/source/game/back/GameObject.hpp @@ -1,12 +1,30 @@ #pragma once #include <kernel/front/Kernel.hpp> +#include <game/back/message/Behavior.hpp> namespace megu::game { + class Level; + class GameObject { public: - virtual void setup(kernel::Kernel &) = 0; - virtual void destroy(kernel::Kernel &) = 0; + virtual void setup(kernel::Kernel &, Level &) = 0; + virtual void destroy(kernel::Kernel &, Level &) = 0; virtual void apply(kernel::Kernel &) = 0; }; + + class GameProps : public GameObject { + public: + GameProps(kernel::Prop * prop) + : _props(prop) {} + + virtual void on(const Behavior &) = 0; + virtual std::optional<Behavior> on() const = 0; + + inline kernel::Prop * get() {return this->_props;} + + private: + kernel::Prop * _props; + + }; } \ No newline at end of file diff --git a/source/game/back/message/Behavior.cpp b/source/game/back/message/Behavior.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fe8d2e05c83ec44077b1217fd5d5362958f557e --- /dev/null +++ b/source/game/back/message/Behavior.cpp @@ -0,0 +1,18 @@ +#include "Behavior.hpp" + +namespace megu::game { + Behavior::Behavior(const kernel::Prop & author, uint32_t type) + : _type(type), _stats(author) {} + + uint32_t Behavior::get(uint32_t key) const { + return this->_stats.get(key); + } + + void Behavior::set(uint32_t key, uint32_t value) { + this->_stats.set(key, value); + } + + uint32_t Behavior::operator&(const uint32_t & type) const { + return this->_type & type; + } +} \ No newline at end of file diff --git a/source/game/back/message/Behavior.hpp b/source/game/back/message/Behavior.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6a6dce2be8438016fa10415d753ebaf69ae789ba --- /dev/null +++ b/source/game/back/message/Behavior.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "StatsAlterator.hpp" + +namespace megu::game { + class Behavior { + public: + enum Type : uint32_t { + SOLID = 1, + DAMAGE = 2, + }; + + Behavior() = delete; + Behavior(const kernel::Prop &, uint32_t); + + uint32_t get(uint32_t) const; + void set(uint32_t, uint32_t); + + + uint32_t operator&(const uint32_t &) const; + + private: + uint32_t _type; + StatsAlterator _stats; + }; +} + + + \ No newline at end of file diff --git a/source/game/back/message/StatsAlterator.cpp b/source/game/back/message/StatsAlterator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ea95898c790b6c76fb564f4b986d70280f70370 --- /dev/null +++ b/source/game/back/message/StatsAlterator.cpp @@ -0,0 +1,31 @@ +#include "StatsAlterator.hpp" + +namespace megu::game { + StatsAlterator::StatsAlterator(const kernel::Prop & author) + : _author(author) {} + + uint32_t StatsAlterator::get(uint32_t key) const { + if(this->_stats.contains(key)) { + return this->_stats.at(key); + } + return 0; + } + + void StatsAlterator::set(uint32_t key, uint32_t value) { + this->_stats[key] = value; + } + + const uint32_t & StatsAlterator::operator[](const uint32_t & key) const { + if(this->_stats.contains(key)) { + return this->_stats.at(key); + } + throw std::runtime_error("Cannot get stats value"); + } + + uint32_t & StatsAlterator::operator[](const uint32_t & key) { + if(this->_stats.contains(key)) { + return this->_stats.at(key); + } + throw std::runtime_error("Cannot get stats value"); + } +} \ No newline at end of file diff --git a/source/game/back/message/StatsAlterator.hpp b/source/game/back/message/StatsAlterator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f8ceaf528affb73e1860d91472deb66cd08d12f3 --- /dev/null +++ b/source/game/back/message/StatsAlterator.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include <kernel/front/props/Props.hpp> + +namespace megu::game { + class StatsAlterator { + public: + StatsAlterator() = delete; + StatsAlterator(const kernel::Prop &); + + uint32_t get(uint32_t) const; + void set(uint32_t, uint32_t); + + const uint32_t & operator[](const uint32_t &) const; + uint32_t & operator[](const uint32_t &); + + private: + std::map<uint32_t, uint32_t> _stats; + const kernel::Prop & _author; + }; +} \ No newline at end of file diff --git a/source/game/back/object/Enemy.cpp b/source/game/back/object/Enemy.cpp index f635637b58aa13101f854d84a643f1593a240d3f..b8f416a014d45fc6d26ec874c3bab4f1553d307d 100644 --- a/source/game/back/object/Enemy.cpp +++ b/source/game/back/object/Enemy.cpp @@ -4,7 +4,7 @@ namespace megu::game { Enemy::Enemy(float x, float y, float w, float h, std::filesystem::path & path) - : kernel::PropsDynamic(this->_sprite, this->_movable), _sprite(path), _movable(x, y, w, h) { + : kernel::PropsDynamic(this->_sprite, this->_movable), GameProps(this), _sprite(path), _movable(x, y, w, h) { this->_sprite.setPosition({x, y}); } @@ -13,21 +13,48 @@ namespace megu::game { this->_movable.move(x, y); } - void Enemy::setup(kernel::Kernel &) { + void Enemy::setup(kernel::Kernel & kernel, Level & level) { this->_sprite.setFrame({0.f, 0.f, 51.f, 98.f}); this->_sprite.setSize({51.f, 98.f}); - this->_movable.setCollideLambda([this](kernel::Kernel & kernel, const kernel::PhysicEngine &, const megu::kernel::Physical<kernel::PhysicEngine> &, double) { - std::cout << "Enemy Collide !" << std::endl; - kernel.remove(this); + this->_movable.setCollideLambda([this, &level](kernel::Kernel &, kernel::PhysicEngine &, Identifiable & id, kernel::Physical<kernel::PhysicEngine> & comp, double) { + auto event = level.get(id)->on(); + if(event.has_value()) { + this->on(event.value()); + } }); } - void Enemy::destroy(kernel::Kernel &) { + void Enemy::on(const Behavior & event) { + if(event & Behavior::Type::SOLID) { + this->onSolide(event); + } + + if(event & Behavior::Type::DAMAGE) { + this->onDamage(event); + } + } + + std::optional<Behavior> Enemy::on() const { + Behavior b(*this, Behavior::DAMAGE); + b.set(0, 10); + + return b; + } + + void Enemy::destroy(kernel::Kernel & kernel, Level & level) { } void Enemy::apply(kernel::Kernel & kernel) { kernel.add(this); } + + void Enemy::onDamage(const Behavior &) { + std::cout << "Enemy Got Damage !" << std::endl; + } + + void Enemy::onSolide(const Behavior &) { + std::cout << "Enemy Got Solide !" << std::endl; + } } \ No newline at end of file diff --git a/source/game/back/object/Enemy.hpp b/source/game/back/object/Enemy.hpp index f3d240d3eddd6e69ee36db46f3f0489c1947286c..7de282494d0d9df9e47bf49374cea0889a6cdc37 100644 --- a/source/game/back/object/Enemy.hpp +++ b/source/game/back/object/Enemy.hpp @@ -2,19 +2,26 @@ #include <game/back/GameObject.hpp> #include <kernel/front/props/PropsDynamic.hpp> +#include <game/back/object/Level.hpp> namespace megu::game { - class Enemy : public kernel::PropsDynamic, public GameObject { + class Enemy : public kernel::PropsDynamic, public GameProps { public: Enemy(float, float, float, float, std::filesystem::path &); void move(float, float); - void setup(kernel::Kernel &) override; - void destroy(kernel::Kernel &) override; + void setup(kernel::Kernel &, Level &) override; + void destroy(kernel::Kernel &, Level &) override; void apply(kernel::Kernel &) override; + void on(const Behavior &) override; + std::optional<Behavior> on() const override; + + void onDamage(const Behavior &); + void onSolide(const Behavior &); + private: kernel::Sprite _sprite; kernel::Movable _movable; diff --git a/source/game/back/object/Level.cpp b/source/game/back/object/Level.cpp index 844932b05929965e4462f7ee6bfae568a26b0af5..8dc9f55502095e848a5ea5388931ca20c50a73db 100644 --- a/source/game/back/object/Level.cpp +++ b/source/game/back/object/Level.cpp @@ -2,17 +2,29 @@ namespace megu::game { Level::Level(const std::string & name) - : _name(name) {} + : _name(name) {} + + GameProps * Level::get(Identifiable & id) const { + return this->_objecs.at(id.id()); + } + + void Level::add(GameProps * prop) { + this->_objecs.insert({prop->get()->id(), prop}); + } void Level::apply(kernel::Kernel & kernel) { for(auto & [id, prop] : this->_objecs) { - kernel.add(prop); + kernel.add(prop->get()); } } - void Level::destroy(kernel::Kernel & kernel) { + void Level::setup(kernel::Kernel & kernel, Level & level) { + + } + + void Level::destroy(kernel::Kernel & kernel, Level & level) { for(auto & [id, prop] : this->_objecs) { - kernel.remove(prop); + kernel.remove(prop->get()); } } } \ No newline at end of file diff --git a/source/game/back/object/Level.hpp b/source/game/back/object/Level.hpp index 7e7a1eb2e63610b252605a87ccf6fd54bb14207d..3f047c9d8965ea52c0c37ee71e22360a3c0f9a96 100644 --- a/source/game/back/object/Level.hpp +++ b/source/game/back/object/Level.hpp @@ -5,17 +5,21 @@ namespace megu::game { class Level : public GameObject { - private: + public: Level(const std::string &); inline const std::string & name() const {return this->_name;} - + + void add(GameProps *); + + GameProps * get(Identifiable &) const; + virtual void apply(kernel::Kernel &) override final; - virtual void destroy(kernel::Kernel &) override final; + virtual void setup(kernel::Kernel &, Level &) override; + virtual void destroy(kernel::Kernel &, Level &) override final; - public: + private: std::string _name; - std::map<size_t, kernel::Prop *> _objecs; - + std::map<size_t, GameProps *> _objecs; }; } \ No newline at end of file diff --git a/source/game/back/object/Player.cpp b/source/game/back/object/Player.cpp index 6e0164402b7ed2e51edacf766d7d871cee1fefed..df16c72a6b6b1754435a1d13757d4c22147d99c4 100644 --- a/source/game/back/object/Player.cpp +++ b/source/game/back/object/Player.cpp @@ -1,10 +1,11 @@ #include "Player.hpp" #include <game/front/profile/PlayerKeys.hpp> +#include <game/back/object/Level.hpp> namespace megu::game { Player::Player(float x, float y, float w, float h, std::filesystem::path & path) - : kernel::PropsPlayable(this->_sprite, this->_movable), _sprite(path), _movable(x, y, w, h) { + : kernel::PropsPlayable(this->_sprite, this->_movable), GameProps(this), _sprite(path), _movable(x, y, w, h) { this->_sprite.setPosition({x, y}); } @@ -13,22 +14,48 @@ namespace megu::game { this->_movable.move(x, y); } - void Player::setup(kernel::Kernel & kernel) { + void Player::setup(kernel::Kernel & kernel, Level & level) { this->setControl(kernel.window(), new PlayerKeyProfile(*this)); this->_sprite.setFrame({0.f, 0.f, 51.f, 98.f}); this->_sprite.setSize({51.f, 98.f}); - this->_movable.setCollideLambda([](kernel::Kernel &, const kernel::PhysicEngine &, const megu::kernel::Physical<kernel::PhysicEngine> &, double) { - std::cout << "Player Collide !" << std::endl; + this->_movable.setCollideLambda([this, &level](kernel::Kernel &, kernel::PhysicEngine &, Identifiable & id, kernel::Physical<kernel::PhysicEngine> & comp, double) { + auto event = level.get(id)->on(); + if(event.has_value()) { + this->on(event.value()); + } }); } - void Player::destroy(kernel::Kernel &) { + void Player::on(const Behavior & event) { + if((event & Behavior::Type::SOLID) != 0) { + this->onSolide(event); + } + + if((event & Behavior::Type::DAMAGE) != 0) { + this->onDamage(event); + } + } + + std::optional<Behavior> Player::on() const { + return {}; + } + + void Player::destroy(kernel::Kernel & kernel, Level & level) { } void Player::apply(kernel::Kernel & kernel) { kernel.add(this); } + + void Player::onDamage(const Behavior & b) { + std::cout << "Player Got Damage !" << std::endl; + std::cout << "I take " << b.get(0) << " damage !" << std::endl; + } + + void Player::onSolide(const Behavior &) { + std::cout << "Player Got Solide !" << std::endl; + } } \ No newline at end of file diff --git a/source/game/back/object/Player.hpp b/source/game/back/object/Player.hpp index 74c7be8b38cdbd298d0e83e3654752282344cd36..8fa5deaf930922495643e29703b8f0c18530109c 100644 --- a/source/game/back/object/Player.hpp +++ b/source/game/back/object/Player.hpp @@ -2,19 +2,26 @@ #include <kernel/front/props/PropsPlayable.hpp> #include <game/back/GameObject.hpp> +#include <game/back/object/Level.hpp> namespace megu::game { - class Player : public kernel::PropsPlayable, public GameObject { + class Player : public kernel::PropsPlayable, public GameProps { public: Player(float x, float y, float w, float h, std::filesystem::path &); void move(float, float); - void setup(kernel::Kernel &) override; - void destroy(kernel::Kernel &) override; + void setup(kernel::Kernel &, Level &) override; + void destroy(kernel::Kernel &, Level &) override; void apply(kernel::Kernel &) override; + void on(const Behavior &) override; + std::optional<Behavior> on() const override; + + void onDamage(const Behavior &); + void onSolide(const Behavior &); + private: kernel::Sprite _sprite; kernel::Movable _movable; diff --git a/source/kernel/back/component/Physical.hpp b/source/kernel/back/component/Physical.hpp index 3db5579ec82d7baecf8d95b92177745213a04a90..7828b34d5e95e03b99c18f9f7c7d13977b03bfa3 100644 --- a/source/kernel/back/component/Physical.hpp +++ b/source/kernel/back/component/Physical.hpp @@ -9,8 +9,8 @@ namespace megu::kernel { template <class Pe> class Physical : public Component<Pe> { public: - virtual void on_collide(Kernel &, const Pe &, Physical &, double) = 0; + virtual void on_collide(Kernel &, Pe &, Identifiable &, Physical &, double) = 0; - using CollideLambda = std::function<void(Kernel &, const Pe &, const Physical &, double)>; + using CollideLambda = std::function<void(Kernel &, Pe &, Identifiable &, Physical &, double)>; }; } \ No newline at end of file diff --git a/source/kernel/front/Kernel.cpp b/source/kernel/front/Kernel.cpp index 8e66ea92fb3022de8c6a1c65af9a6fdb41fffbf5..59c942825165b1a4f735c27a083499b1cb197838 100644 --- a/source/kernel/front/Kernel.cpp +++ b/source/kernel/front/Kernel.cpp @@ -54,4 +54,23 @@ namespace megu::kernel { this->_props.erase(props->id()); } + + Prop * Kernel::get(const Prop::Physical_Component & pc) { + for(auto & [id, props] : this->_props) { + if(props->getPhysicComponent()->id() == pc.id()) { + return props; + } + } + return nullptr; + } + + + Prop * Kernel::get(const Prop::Graphical_Component & gc) { + for(auto & [id, props] : this->_props) { + if(props->getGraphicComponent()->id() == gc.id()) { + return props; + } + } + return nullptr; + } } \ No newline at end of file diff --git a/source/kernel/front/Kernel.hpp b/source/kernel/front/Kernel.hpp index e7e7f047c20ad34b87d253b4ed7fad70cbd1ea9c..0593c91ebe451cde6e81eabfbc8f2222ca21f0ca 100644 --- a/source/kernel/front/Kernel.hpp +++ b/source/kernel/front/Kernel.hpp @@ -29,6 +29,9 @@ namespace megu::kernel { inline Window & window() {return this->_window;} + Prop * get(const Prop::Physical_Component &); + Prop * get(const Prop::Graphical_Component &); + private: Window & _window; diff --git a/source/kernel/front/component/physic/Fixed.cpp b/source/kernel/front/component/physic/Fixed.cpp index 8964777a9f1dbb77cdcebe6aaebf7d0a2a9c295c..a887afd090ad8f1f811536d509d7548a10a19dc4 100644 --- a/source/kernel/front/component/physic/Fixed.cpp +++ b/source/kernel/front/component/physic/Fixed.cpp @@ -12,9 +12,9 @@ namespace megu::kernel { } } - void Fixed::on_collide(Kernel & kernel, const PhysicEngine & engine, Physical & physical, double time) { + void Fixed::on_collide(Kernel & kernel, PhysicEngine & engine, Identifiable & id, Physical & physical, double time) { if(this->_collide != nullptr) { - this->_collide(kernel, engine, physical, time); + this->_collide(kernel, engine, id, physical, time); } } diff --git a/source/kernel/front/component/physic/Fixed.hpp b/source/kernel/front/component/physic/Fixed.hpp index 232084ab72cbfbac051dfde9c23f1baff42dd062..7ef7041dd979575d8785f9ded64c2258486f70eb 100644 --- a/source/kernel/front/component/physic/Fixed.hpp +++ b/source/kernel/front/component/physic/Fixed.hpp @@ -13,7 +13,7 @@ namespace megu::kernel { Fixed(float x, float y, float w, float h); void update_physic(double) const override; - void on_collide(Kernel &, const PhysicEngine &, Physical &, double) override; + void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override; void apply(Kernel & k, PhysicEngine &) override; void unapply(Kernel & k, PhysicEngine &) override; diff --git a/source/kernel/front/component/physic/FixedArray.cpp b/source/kernel/front/component/physic/FixedArray.cpp index 5e5602dfe943dd4c3f445694b1a38b2677a5fd85..a0b61a78d87b2d8220e57b71e017bd8cebaf1129 100644 --- a/source/kernel/front/component/physic/FixedArray.cpp +++ b/source/kernel/front/component/physic/FixedArray.cpp @@ -22,11 +22,11 @@ namespace megu::kernel { this->_tangibles.erase(position); } - void FixedArray::on_collide(Kernel & kernel, const PhysicEngine & engine, Physical & physical, double time) { + void FixedArray::on_collide(Kernel & kernel, PhysicEngine & engine, Identifiable & id, Physical & physical, double time) { auto & tangible = engine.get(physical); for(auto & [position, fixed] : this->_tangibles) { if(fixed.isColliding(tangible)) { - physical.on_collide(kernel, engine, fixed, time); + physical.on_collide(kernel, engine, id, fixed, time); } } } diff --git a/source/kernel/front/component/physic/FixedArray.hpp b/source/kernel/front/component/physic/FixedArray.hpp index 9f04d44a9c46a74331615647dc96c19ce72d4199..73f1dae84b17c81ad3502ca42f30a1ef4c8161da 100644 --- a/source/kernel/front/component/physic/FixedArray.hpp +++ b/source/kernel/front/component/physic/FixedArray.hpp @@ -20,7 +20,7 @@ namespace megu::kernel { void setUpdateLambda(UpdateLambda); void update_physic(double) const override; - void on_collide(Kernel &, const PhysicEngine &, Physical &, double) override; + void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override; void apply(Kernel & k, PhysicEngine &) override; void unapply(Kernel & k, PhysicEngine &) override; diff --git a/source/kernel/front/component/physic/Movable.cpp b/source/kernel/front/component/physic/Movable.cpp index ac592e601962466e8a3acdb0d4b7cd1c0827f520..df0eef580b11262e8980a4dbaafe8a2bb19595d1 100644 --- a/source/kernel/front/component/physic/Movable.cpp +++ b/source/kernel/front/component/physic/Movable.cpp @@ -10,9 +10,9 @@ namespace megu::kernel { } } - void Movable::on_collide(Kernel & kernel, const PhysicEngine & engine, Physical & physical, double time) { + void Movable::on_collide(Kernel & kernel, PhysicEngine & engine, Identifiable & id, Physical & physical, double time) { if(this->_collide != nullptr) { - this->_collide(kernel, engine, physical, time); + this->_collide(kernel, engine, id, physical, time); } } diff --git a/source/kernel/front/component/physic/Movable.hpp b/source/kernel/front/component/physic/Movable.hpp index f1cd9ff7ae544d81faddbc3e7edbc284d29b7a4e..bdb94e6deb1e6ab7e6efcb031757e84d4e164c24 100644 --- a/source/kernel/front/component/physic/Movable.hpp +++ b/source/kernel/front/component/physic/Movable.hpp @@ -13,7 +13,7 @@ namespace megu::kernel { Movable(float x, float y, float w, float h); void update_physic(double) override; - void on_collide(Kernel &, const PhysicEngine &, Physical &, double) override; + void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override; void apply(Kernel & k, PhysicEngine &) override; void unapply(Kernel & k, PhysicEngine &) override; diff --git a/source/kernel/front/resolver/PhysicResolver.cpp b/source/kernel/front/resolver/PhysicResolver.cpp index f2b5431512eda627e67c9591ed951330c7075c2c..593ab0a4a79b07dfa8325531ea3a79875d604d4b 100644 --- a/source/kernel/front/resolver/PhysicResolver.cpp +++ b/source/kernel/front/resolver/PhysicResolver.cpp @@ -1,5 +1,7 @@ #include "PhysicResolver.hpp" +#include <kernel/front/Kernel.hpp> + namespace megu::kernel { void PhysicResolver::resolve(Kernel & kernel, PhysicEngine & engine, double time) { auto & collisions = engine.get().collision(); @@ -9,7 +11,7 @@ namespace megu::kernel { auto target_comp = this->get(collision.target()); if(source_comp.has_value() && target_comp.has_value()) { - source_comp.value().get().on_collide(kernel, engine, target_comp.value().get(), time); + source_comp.value().get().on_collide(kernel, engine, *kernel.get(target_comp.value()), target_comp.value(), time); } }