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