From 65589fbdcdc7be47279cd92267ef48fe2d5abafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9au?= <theau.baton@etu.univ-amu.fr> Date: Thu, 23 Jan 2025 17:27:57 +0100 Subject: [PATCH] Add collision to player --- source/engine/physic/front/engine/Engine.cpp | 15 +++++++++ source/engine/physic/front/engine/Engine.hpp | 2 ++ .../engine/physic/front/object/Tangible.hpp | 6 ++-- source/game/Game.cpp | 4 +-- source/game/back/object/Player.cpp | 11 ++++--- source/game/back/object/Player.hpp | 5 ++- source/game/front/profile/PlayerKeys.cpp | 32 +++++++++++++++---- source/game/front/profile/PlayerKeys.hpp | 3 +- source/kernel/back/component/Physical.hpp | 9 ++++++ .../kernel/front/component/physic/Fixed.cpp | 2 +- .../kernel/front/component/physic/Movable.cpp | 2 +- .../front/component/physic/TileArray.cpp | 12 ++++++- .../front/component/physic/TileArray.hpp | 2 ++ 13 files changed, 84 insertions(+), 21 deletions(-) diff --git a/source/engine/physic/front/engine/Engine.cpp b/source/engine/physic/front/engine/Engine.cpp index 764b163..480db59 100644 --- a/source/engine/physic/front/engine/Engine.cpp +++ b/source/engine/physic/front/engine/Engine.cpp @@ -65,6 +65,21 @@ namespace megu { } } + bool PhysicEngine::makeCollision(const SquareBox & box, Priority priority) const { + for(const auto & source : this->_statics.at(priority)) { + if(source.get().isColliding(box)) { + return true; + } + } + + for(const auto & source : this->_dynamic.at(priority)) { + if(source.get().isColliding(box)) { + return true; + } + } + return false; + } + std::optional<std::reference_wrapper<const Tangible>> PhysicEngine::get(const Identifiable & id) const { for(auto & [priotiy, objects] : this->_statics) { for(auto & object : objects) { diff --git a/source/engine/physic/front/engine/Engine.hpp b/source/engine/physic/front/engine/Engine.hpp index 23b08fc..ae19a1b 100644 --- a/source/engine/physic/front/engine/Engine.hpp +++ b/source/engine/physic/front/engine/Engine.hpp @@ -28,6 +28,8 @@ namespace megu { void step(double); void step(double, Priority); + bool makeCollision(const SquareBox &, Priority) const; + std::optional<std::reference_wrapper<const Tangible>> get(const Identifiable &) const; inline void clearCollision() {this->_collisions.clear();} diff --git a/source/engine/physic/front/object/Tangible.hpp b/source/engine/physic/front/object/Tangible.hpp index 28a0096..9cc4d73 100644 --- a/source/engine/physic/front/object/Tangible.hpp +++ b/source/engine/physic/front/object/Tangible.hpp @@ -24,11 +24,11 @@ namespace megu { inline void move(const Direction & direction) {this->_box.move(direction);} inline void move(float x, float y, float z = 0.f) {return this->move(Direction(x, y, z));} - bool isColliding(const Tangible &) const; - bool isColliding(const SquareBox &) const; + virtual bool isColliding(const Tangible &) const; + virtual bool isColliding(const SquareBox &) const; bool operator==(const Tangible &) const; - //bool operator!=(const Tangible &) const; + using UpdateLambda = std::function<void(double)>; diff --git a/source/game/Game.cpp b/source/game/Game.cpp index eb15609..8a14bbf 100644 --- a/source/game/Game.cpp +++ b/source/game/Game.cpp @@ -33,9 +33,9 @@ namespace megu::game { Terrain terrain(0.f, 0.f, 32.f, 32.f, "assets/tilemap.png", 4, 4, 32.f, 16); - terrain.setTileEvent(1, new TileSolide(32.f)); + terrain.setTileEvent(2, new TileSolide(32.f)); terrain.setValue(1, 1, 1); - terrain.setValue(0, 1, 2); + terrain.setValue(1, 0, 2); Level level("STZ"); diff --git a/source/game/back/object/Player.cpp b/source/game/back/object/Player.cpp index d77418f..4371a1d 100644 --- a/source/game/back/object/Player.cpp +++ b/source/game/back/object/Player.cpp @@ -8,6 +8,7 @@ namespace megu::game { : kernel::PropsPlayable(this->_sprite, this->_movable), GameProps(this), _sprite(path), _movable(x, y, w, h) { this->_sprite.setPosition({x, y}); this->_sprite.setLayerObject(2); + this->_movable.setLayer(2); } void Player::move(float x, float y) { @@ -16,7 +17,7 @@ namespace megu::game { } void Player::setup(kernel::Kernel & kernel, Level & level) { - this->setControl(kernel.window(), new PlayerKeyProfile(*this)); + this->setControl(kernel.window(), new PlayerKeyProfile(*this, kernel)); this->_sprite.setFrame({0.f, 0.f, 16.f, 16.f}); this->_sprite.setSize({32.f, 32.f}); @@ -33,9 +34,9 @@ namespace megu::game { }); } - void Player::on(const kernel::Prop &, const Event & event) { + void Player::on(const kernel::Prop & props, const Event & event) { if((event & Event::Type::SOLID) != 0) { - this->onSolide(event); + this->onSolide(props); } if((event & Event::Type::DAMAGE) != 0) { @@ -60,7 +61,7 @@ namespace megu::game { std::cout << "I take " << b.get(0).value_or(0) << " damage !" << std::endl; } - void Player::onSolide(const Event &) { - std::cout << "Player Got Solide !" << std::endl; + void Player::onSolide(const kernel::Prop & props) { + } } \ No newline at end of file diff --git a/source/game/back/object/Player.hpp b/source/game/back/object/Player.hpp index f97e264..febcc85 100644 --- a/source/game/back/object/Player.hpp +++ b/source/game/back/object/Player.hpp @@ -20,7 +20,10 @@ namespace megu::game { std::optional<Event> on() const override; void onDamage(const Event &); - void onSolide(const Event &); + void onSolide(const kernel::Prop &); + + kernel::Movable & getPhysic() {return this->_movable;} + kernel::Sprite & getGraphic() {return this->_sprite;} private: kernel::Sprite _sprite; diff --git a/source/game/front/profile/PlayerKeys.cpp b/source/game/front/profile/PlayerKeys.cpp index ffeafb6..1f33001 100644 --- a/source/game/front/profile/PlayerKeys.cpp +++ b/source/game/front/profile/PlayerKeys.cpp @@ -1,24 +1,44 @@ #include "PlayerKeys.hpp" namespace megu::game { - PlayerKeyProfile::PlayerKeyProfile(Player & player) - : _player(player) {} + PlayerKeyProfile::PlayerKeyProfile(Player & player, kernel::Kernel & kernel) + : _player(player), _kernel(kernel) {} void PlayerKeyProfile::on(Key key, int code, Action action, Mod mode) { if(key == Keyboard::Key::ARROW_UP) { - this->_player.move(0.f, 0.5f); + SquareBox box = this->_player.getPhysic().getBox(); + box.move({0.f, 1.f, 0.f}); + + if(!this->_kernel.getPhysicEngine().get().makeCollision(box, 0)) { + this->_player.move(0.f, 1.f); + } } if(key == Keyboard::Key::ARROW_DOWN) { - this->_player.move(0.f, -0.5f); + SquareBox box = this->_player.getPhysic().getBox(); + box.move({0.f, -1.f, 0.f}); + + if(!this->_kernel.getPhysicEngine().get().makeCollision(box, 0)) { + this->_player.move(0.f, -1.f); + } } if(key == Keyboard::Key::ARROW_LEFT) { - this->_player.move(-0.5f, 0.f); + SquareBox box = this->_player.getPhysic().getBox(); + box.move({-1.f, 0.f, 0.f}); + + if(!this->_kernel.getPhysicEngine().get().makeCollision(box, 0)) { + this->_player.move(-1.f, 0.f); + } } if(key == Keyboard::Key::ARROW_RIGHT) { - this->_player.move(0.5f, 0.f); + SquareBox box = this->_player.getPhysic().getBox(); + box.move({1.f, 0.f, 0.f}); + + if(!this->_kernel.getPhysicEngine().get().makeCollision(box, 0)) { + this->_player.move(1.f, 0.f); + } } } } \ No newline at end of file diff --git a/source/game/front/profile/PlayerKeys.hpp b/source/game/front/profile/PlayerKeys.hpp index 47b5301..8acb995 100644 --- a/source/game/front/profile/PlayerKeys.hpp +++ b/source/game/front/profile/PlayerKeys.hpp @@ -8,11 +8,12 @@ namespace megu::game { class PlayerKeyProfile : public Keyboard { public: - PlayerKeyProfile(Player &); + PlayerKeyProfile(Player &, kernel::Kernel &); virtual void on(Key, int, Action, Mod); private: Player & _player; + kernel::Kernel & _kernel; }; } \ No newline at end of file diff --git a/source/kernel/back/component/Physical.hpp b/source/kernel/back/component/Physical.hpp index 7828b34..7701eb4 100644 --- a/source/kernel/back/component/Physical.hpp +++ b/source/kernel/back/component/Physical.hpp @@ -4,13 +4,22 @@ #include <functional> #include <utility/Identifiable.hpp> +#include <engine/utility/Priority.hpp> namespace megu::kernel { template <class Pe> class Physical : public Component<Pe> { public: + inline Physical(Priority p = 0) + : _layer(p) {} + virtual void on_collide(Kernel &, Pe &, Identifiable &, Physical &, double) = 0; using CollideLambda = std::function<void(Kernel &, Pe &, Identifiable &, Physical &, double)>; + inline void setLayer(Priority p) {this->_layer = p;} + inline Priority getLayer() const {return this->_layer;} + + private: + Priority _layer; }; } \ No newline at end of file diff --git a/source/kernel/front/component/physic/Fixed.cpp b/source/kernel/front/component/physic/Fixed.cpp index 1b0f4ca..fcaa667 100644 --- a/source/kernel/front/component/physic/Fixed.cpp +++ b/source/kernel/front/component/physic/Fixed.cpp @@ -19,7 +19,7 @@ namespace megu::kernel { } void Fixed::apply(Kernel & kernel, PhysicEngine & engine) { - engine.get().push(0, *this); + engine.get().push(this->getLayer(), *this); } void Fixed::unapply(Kernel & kernel, PhysicEngine & engine) { diff --git a/source/kernel/front/component/physic/Movable.cpp b/source/kernel/front/component/physic/Movable.cpp index a48eae0..c9aeaf2 100644 --- a/source/kernel/front/component/physic/Movable.cpp +++ b/source/kernel/front/component/physic/Movable.cpp @@ -17,7 +17,7 @@ namespace megu::kernel { } void Movable::apply(Kernel & kernel, PhysicEngine & engine) { - engine.get().push(0, *this); + engine.get().push(this->getLayer(), *this); } void Movable::unapply(Kernel & kernel, PhysicEngine & engine) { diff --git a/source/kernel/front/component/physic/TileArray.cpp b/source/kernel/front/component/physic/TileArray.cpp index 4dd9bc5..1ce7961 100644 --- a/source/kernel/front/component/physic/TileArray.cpp +++ b/source/kernel/front/component/physic/TileArray.cpp @@ -45,6 +45,16 @@ namespace megu::kernel { } } + bool TileArray::isColliding(const SquareBox & box) const { + for(auto & [positon, tile] : this->_tiles) { + SquareBox tbox = SquareBox(positon, tile.get().getBox().dimension()); + if(box.intersect(tbox)) { + return true; + } + } + return false; + } + void TileArray::update_physic(double time) const { if(this->_update != nullptr) { this->_update(time); @@ -52,7 +62,7 @@ namespace megu::kernel { } void TileArray::apply(Kernel & kernel, PhysicEngine & engine) { - engine.get().push(0, *this); + engine.get().push(this->getLayer(), *this); } void TileArray::unapply(Kernel & kernel, PhysicEngine & engine) { diff --git a/source/kernel/front/component/physic/TileArray.hpp b/source/kernel/front/component/physic/TileArray.hpp index a3ade2b..418d8d0 100644 --- a/source/kernel/front/component/physic/TileArray.hpp +++ b/source/kernel/front/component/physic/TileArray.hpp @@ -27,6 +27,8 @@ namespace megu::kernel { void unapply(Kernel & k, PhysicEngine &) override; void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override; + virtual bool isColliding(const SquareBox &) const override; + private: std::map<Position, std::reference_wrapper<Tile>> _tiles; TileCollideLambda _collide; -- GitLab