From 7d4425d95fcbab970eb54ebcc99c0d82099a591a 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 00:29:44 +0100
Subject: [PATCH] Add Tilemap collision

---
 assets/player.png                             | Bin 0 -> 1386 bytes
 assets/player.png.old                         | Bin 0 -> 1524 bytes
 .../graphics/front/object/TileArray.cpp       |   4 +-
 .../graphics/front/object/TileArray.hpp       |   5 +-
 source/engine/physic/back/SquareBox.cpp       |  28 +++----
 source/engine/physic/back/SquareBox.hpp       |   2 -
 source/engine/physic/front/engine/Engine.cpp  |   1 +
 .../engine/physic/front/object/Tangible.cpp   |   6 ++
 .../engine/physic/front/object/Tangible.hpp   |   1 +
 source/game/Game.cpp                          |  28 ++++---
 source/game/back/GameObject.hpp               |  13 ++--
 source/game/back/message/Behavior.cpp         |  18 -----
 source/game/back/message/Behavior.hpp         |  29 --------
 source/game/back/message/Event.cpp            |  18 +++++
 source/game/back/message/Event.hpp            |  28 +++++++
 source/game/back/message/StatsAlterator.cpp   |  31 --------
 source/game/back/message/StatsAlterator.hpp   |  18 ++---
 source/game/back/message/StatsAlterator.tpp   |  21 ++++++
 source/game/back/object/Enemy.cpp             |  23 +++---
 source/game/back/object/Enemy.hpp             |  10 +--
 source/game/back/object/Level.cpp             |   9 ++-
 source/game/back/object/Level.hpp             |   2 +-
 source/game/back/object/Player.cpp            |  29 +++++---
 source/game/back/object/Player.hpp            |   8 +-
 source/game/back/object/Terrain.cpp           |  58 +++++++++++++++
 source/game/back/object/Terrain.hpp           |  32 ++++++++
 source/game/back/object/tile/Tile.cpp         |   6 ++
 source/game/back/object/tile/Tile.hpp         |  14 ++++
 source/game/back/object/tile/TileSolide.cpp   |  14 ++++
 source/game/back/object/tile/TileSolide.hpp   |  13 ++++
 source/game/front/profile/PlayerKeys.cpp      |   8 +-
 source/kernel/back/linker/UniqueLinker.tpp    |   6 +-
 source/kernel/front/Kernel.cpp                |   1 +
 .../front/component/graphic/TileMap.hpp       |   2 +-
 .../kernel/front/component/physic/Fixed.cpp   |   4 +-
 .../kernel/front/component/physic/Fixed.hpp   |   2 +-
 .../front/component/physic/FixedArray.cpp     |  55 --------------
 .../front/component/physic/FixedArray.hpp     |  32 --------
 .../kernel/front/component/physic/Movable.cpp |   4 +-
 .../kernel/front/component/physic/Movable.hpp |   2 +-
 source/kernel/front/component/physic/Tile.cpp |  26 +++++++
 source/kernel/front/component/physic/Tile.hpp |  16 ++++
 .../front/component/physic/TileArray.cpp      |  69 ++++++++++++++++++
 .../front/component/physic/TileArray.hpp      |  35 +++++++++
 source/kernel/front/props/PropsTileMap.cpp    |   2 +-
 source/kernel/front/props/PropsTileMap.hpp    |   6 +-
 46 files changed, 480 insertions(+), 259 deletions(-)
 create mode 100644 assets/player.png
 create mode 100644 assets/player.png.old
 delete mode 100644 source/game/back/message/Behavior.cpp
 delete mode 100644 source/game/back/message/Behavior.hpp
 create mode 100644 source/game/back/message/Event.cpp
 create mode 100644 source/game/back/message/Event.hpp
 delete mode 100644 source/game/back/message/StatsAlterator.cpp
 create mode 100644 source/game/back/message/StatsAlterator.tpp
 create mode 100644 source/game/back/object/Terrain.cpp
 create mode 100644 source/game/back/object/Terrain.hpp
 create mode 100644 source/game/back/object/tile/Tile.cpp
 create mode 100644 source/game/back/object/tile/Tile.hpp
 create mode 100644 source/game/back/object/tile/TileSolide.cpp
 create mode 100644 source/game/back/object/tile/TileSolide.hpp
 delete mode 100644 source/kernel/front/component/physic/FixedArray.cpp
 delete mode 100644 source/kernel/front/component/physic/FixedArray.hpp
 create mode 100644 source/kernel/front/component/physic/Tile.cpp
 create mode 100644 source/kernel/front/component/physic/Tile.hpp
 create mode 100644 source/kernel/front/component/physic/TileArray.cpp
 create mode 100644 source/kernel/front/component/physic/TileArray.hpp

diff --git a/assets/player.png b/assets/player.png
new file mode 100644
index 0000000000000000000000000000000000000000..c84d047f428c2c2dadeff99120314ec06d313048
GIT binary patch
literal 1386
zcmeAS@N?(olHy`uVBq!ia0y~yU~phyU@+idV_;xd=v^bvz`(#*9OUlAu<o49O9lo8
zmUKs7M+SzC{oH>NSs54@I14-?iy0XB4uCLY*0oMf1_qY@o-U3d8O~>CoW3YyD$<(X
z!NBgoFo9Wm)t<!HAso#ids3Z6rHc+QS}>e=;QsuVT;Z=*uP$EB5|0m!mfHI6^$Ww#
zzkh~R#5{=nkmvIE+q0e%pQ65Q&dFx_b8l_pncs_I-5XAytpELS`SJVr|Np7@{?c5U
z<$ui&=CfzcOXqOb?$EWkabNAg?fCsw-?`7r*KIsz_hn_-41Ym}))^fE-Qm_ZR>Yfp
zTeu;bA=;MZv%^#aG3INsi(P|R8kDxgXViRow&}+P;RD6X8MamF1aV(HV3Z!o;;_4q
zqy3R-f8fU-&!u1IwVl+s8Nt9A8RQ|tT5wzchS>!+y9eG~>kAL)GBL2EFm@-fU$JJ;
zo%}3M!7i>_!)B>NvzbKr{ER<_+qe!i32xb*r5rdzqjSDvkWHowgYkT8RuAETz$L!i
z54N4>5`SnEo%G&l;zQxbb><=RxBDHoebT7<C^NgmV+y~+?9SWGb`8Hy9l8Hc_ke?r
z#WzFsbxsTB`Lo(>ViI~Ieeijj%$x1+8N_;~)i!u{{*|1=zVVC2j|!~`#Xm$>eA{~?
z`aQ!M9j1j5Z0_>>+n=O-<-Pa7`sL3(Pp2m=E4wjial>X^o~mzm?<(5yZ@bO<VA|)Y
z>smf8WVjb5y=hZ5mnpkYQ6}q$f8H#N2hQ9N`Y2pw=XZO4p^2AG^7j7doXz58Y?YZG
zKAk#uzM)Eb_596tdqTI}KIUkA#k-@GVdsph&XDRwbz*Nk-^=K8f9SI9323l=@j94m
z#bZ15p!<pIZgus3Gk!GZSIb7Zn|E?_mikFqPAH$4`>i6xrAz*qOWY>^dXCohyvowA
z3$N}|d9(NbiDOlBHrjJEbZ3chysywqi`ja9!s*W<8zMWGGTn$z+OhSt*+#}Kw~kx;
ztL^q#cdJ~utsu`_r|Z4J_U!@}_gOM&GrGlWSpR>%fmWHq1MmOx3z;5l+Q4b>=oI4@
z!?yBuIeT4NbiXy!Db?63%~md){X>Ld`{MHb5)Uq2QukhQ{LH=NRHcwAC7v99Q-L25
zf`0qu-efz=?>m0@{L{`G*5@9l*BZ3BCuv@7E4<S7w@=sNi0f%PxnEBzDtT<Z%_7vU
z&R@@>9U*hYPU`oCCWmW*(ua~Cq}WYZQkul)@MibN&3_nk9JloMtuksj+2HxeOLS6)
z?n|);xw~@3i!zcXPjJ?9*vwqB)p!}J#vRVdvI*M~mw&Yol~<`d>pts9OI$(G(c|I$
z^~dWw{>Y!m^7?GTxbOFe<@GklpZDAMvAp2?{fcWHSFC<e!($t(Dr;7UM=zootEPWo
zW7}-4pvFImNkaQlP4@+}JB(M$wllOlL>e98UbSuSA;%zw4yF+K8S86ru_+$h{4@H2
zmXDO9Bv10>=)Vll(vBAEJPfc&c8`Acct(RYt3f-5kZXdHVx!31({>!JN3P~CP}tDC
z;NZ4f@9!~&vc$UHy?0>pMWtE$pQy3ANL9-z_XNA-7lypu(KMH7Ml$cQB{R-QhH(pA
zvTx7ye)N2;b%GdA#U$_59APzF&!$`ZH_Da=FFba?ioM`=x~ErA<i{r^jFJMA>@Ivd
zd1U|N_JD1+QxiY6p8mGOe$(A2GH=S`n+`A~9Ni&2VM0vHVy3rq&xPB!E`8*AM)5Hp
zV_SvOOpdQidz<gM*8CP+@afJZjZMXUz6|x(Z*VS-y>K`7!*|nn4QZm00uOdiWKh_w
zC>xzR!+D|Tf#3RqtRKomZ|%zxkNo=hTmSL>*EGL2_3u<~VPIfj@O1TaS?83{1OTJI
Be#Za+

literal 0
HcmV?d00001

diff --git a/assets/player.png.old b/assets/player.png.old
new file mode 100644
index 0000000000000000000000000000000000000000..70456833ec2e399ebc897d12cc6abd8f1423db91
GIT binary patch
literal 1524
zcmeAS@N?(olHy`uVBq!ia0y~yU~phyU@+idV_;xd=v^bvz`(#*9OUlAu<o49O9lo8
zmUKs7M+SzC{oH>NSs54@I14-?iy0XB4ude`@%$Aj3=FKDo-U3d8O~>Cot-LU&eM`E
z+bGf|+t$C!O0;!hNXgfWi6;_oNUn*L5D8&9IDekx&42frPo`~V5b!N3|N5tFb>(+6
z<Js{G?bf~Un0k2S{N!BIAO9Y{UcY^R-M=UO<#zvm{(k%Z{y&HBDxJ$Gr}K4q^F5CK
z*J2mLZB<()cF;9p$;Mov_xJZzd_Q+vfBxEy?UoA<*ZdXGIkJpnW5rd+#dQ~NI5Qm#
zWHA16wdBrk(MrDvsnbVxZ)?y~o0qurzK-!+@A^ecOI-rCWgXq^v)tLh=CH{JFaKcO
z<2R05e{|pVaZPh)TiTx|x$XIr`?7M}xS#EPACk<O<9&P9jZGcLbL$t#E?~2Jpe=jf
zf+?2Kpi-3Q{fsMoEH-mrf9Sp|A9Z@k=hiomtNQMzG_sjWgwM~o!=u|^*%-ij>-cV^
ziUX|4=hjSEy~sf9<oN`_dJU!<KV|w3XdOH&t}A?Dkw>&%!|i=hJC5jezrV3t%m2rb
z9r8~<EMz_4n#lP~MdO(D|4kcPjjm1?zsskslys3HdA^gpL+#G~O%0o87a5#67*ii+
zC7-eSpUdhGwdq&PZ!av?e*L14Vf7uEDQso&Oz#cFb$>H_Xa8+&!Eep)R#Owv(r~nT
z`}Olln;FXfF{mlsJoQ3lzVh*!fb$Qo6nXn?k)82BE6uK0DYkUygGZ~+izWP8b?fBu
zRSe%myJws-s%!o6X3H;ulbfUNh~9B4n%JP#`NPsr*YojdrV44PqD|FO6PZ1C`fxKW
z6ZMhNO*mv6W%Ri)vi|5rt&d&dzkev+deu7DQI0t-?&{A-f$bZA?R<4O`sveKHW^NP
zTXqO+u>7y^#pSQei<56;<i#Hd?)^6@sdnqO28r*MGb`G6t`hD2ru}Ko1{1Tzv!Z*a
z9$7M#xpI2tOu1#QDIYJ-Iph56VZY*px*UnCH+s^)>L$LgT`o1d(DlA3gZNb~fqNf=
z)>MSWD^7o|y1=q?DQm^I`^<6Q-g8QdoGU%;`cd}TIXjnY{O%7_4s@x1`S_l5^-(>p
z9~bt!XD}8--eBqY@s#10#9{08IWbCyyuUQm8P)7xG)uX#{f7=ip8NZItUI<`S=EyE
z=8N2FEhhu*Lr%BXHXb<c`S8o}=D#-r9#>1upPl+f_W8$1-eiN$r7dlRA&39DaPQiY
zakKrR`tjM4Rnu}d_;$s|bM8wh7N|A(X3*qtEs*!2VS$#s$0aLEc7<P=f3)fubWi+x
zqoKt-gXf0IIv2&xjFTmd_om(crqHfv=4m;FRidn+{%zM=CXsh7XZZ|rZ)F<m9c6Eg
z{~V~cF;Q%e&Ev=M{rii;EN`*?-(N7N+B73cjx|p1!1ni<f@$$d%j-kjA1SfM9Deg6
zb@^T0b>9!Z5fhzYacnnJ)1r=qj^6)Io;Yq~IChH1-gSj<xkJXy&Q;lubeI~1-<qFd
zeZth_s;Ff5yvb&N1cSt*^F>R|M1}TzG(T9-#>vB@IPYakQn{RK@FuYYAEEnAJFh;n
z47;Ff_ndb@s$JjOoxig$oK?#b`c*2{GHur!53dC-&o}X3VtUkkHsRcbL|xD5S07y;
zU-#Vh=JQU=XFqx_6zbh#uHADu=ISER*%x0*_MgACOY-jg!?{i0-#tlxFm;XA35D<M
z|GOH}e{o%Tq4!~1bVI;D%Q@F4%-^kiAa}kxW8UjyCBNS`HM%m&M>!n&<F$^l#D=f8
z<Nn)*Hr2*XlZI_xdLQTi;pY>LVRrD27TMn%y=L>#n`cXQ9V!cv+A4c>@4{;n%Ns7r
zM0Bruef`VFgPw=9)<nH{v3cXA+tzdE7u~3})w#DjnNKv8QEulJzmF}el#a0eQr@v?
z*<G=wwJ)9>n*J-hJH`I;-x;T@Hi}-YG5&ZpFn8sQDf>?xWHqUAy)IE>{!#drm-D={
w3omB2tL(XJ==~tX|Hbpb*k?)qw%@k5cw$$6cj1+I1_lNOPgg&ebxsLQ0EExzdjJ3c

literal 0
HcmV?d00001

diff --git a/source/engine/graphics/front/object/TileArray.cpp b/source/engine/graphics/front/object/TileArray.cpp
index 475635b..78953d5 100644
--- a/source/engine/graphics/front/object/TileArray.cpp
+++ b/source/engine/graphics/front/object/TileArray.cpp
@@ -3,8 +3,8 @@
 #include <iostream>
 
 namespace megu {
-    TileArray::TileArray(const std::filesystem::path & path, size_t width, size_t height, float size, size_t lenght)
-    : _width(width), _height(height), _size(size) {
+    TileArray::TileArray(const std::filesystem::path & path, size_t width, size_t height, float tileSize, size_t lenght)
+    : _width(width), _height(height), _tileSize(tileSize) {
         megu::TextureBuffer buffer(path);
         this->_texture.store(buffer);
 
diff --git a/source/engine/graphics/front/object/TileArray.hpp b/source/engine/graphics/front/object/TileArray.hpp
index c4191dc..b8862f5 100644
--- a/source/engine/graphics/front/object/TileArray.hpp
+++ b/source/engine/graphics/front/object/TileArray.hpp
@@ -27,7 +27,8 @@ namespace megu {
 
             inline size_t width() const {return this->_width;}
             inline size_t height() const {return this->_height;}
-            inline float size() const {return this->_size;}
+            inline float getTileSize() const {return this->_tileSize;}
+            inline const Vec3 & getSize() const {return this->_transformation.scaling();}
 
             inline void setUv(size_t x, size_t y, const glm::vec4 & uv) {this->_uvs[y][x] = uv;}
 
@@ -41,7 +42,7 @@ namespace megu {
             Transformable _transformation;
             Texture _texture;
             size_t _width, _height;
-            float _size;
+            float _tileSize;
             std::vector<std::vector<glm::vec4>> _uvs;
     };
 }
\ No newline at end of file
diff --git a/source/engine/physic/back/SquareBox.cpp b/source/engine/physic/back/SquareBox.cpp
index a8b4575..13927a5 100644
--- a/source/engine/physic/back/SquareBox.cpp
+++ b/source/engine/physic/back/SquareBox.cpp
@@ -1,5 +1,7 @@
 #include "SquareBox.hpp"
 
+#include <iostream>
+
 namespace megu {
     SquareBox::SquareBox(const Position & position, const Dimension & dimension) 
     : _position(position), _dimension(dimension) {}
@@ -31,21 +33,21 @@ namespace megu {
         this->_position.move(direction.x(), direction.y(), direction.z());
     }
 
-    bool SquareBox::contain(const Position & position) const {
-        if(position >= this->_position && position <= (this->_position + Position(this->_dimension))) {
-            return true;
-        }
-        return false;
-    }
+    bool SquareBox::intersect(const SquareBox & squareBox) const {
+        const Position & a = squareBox.position();
+        const Dimension & as = squareBox.dimension();
+        const Position & b = this->_position;
+        const Dimension & bs = this->_dimension;
 
-    bool SquareBox::intersect(const SquareBox & SquareBox) const {
-        const Cube cube = SquareBox.asCube();
-        for(const auto & position : cube) {
-            if(this->contain(position)) {
-                return true; 
-            }
+        bool x = std::max(a.x(), b.x()) < std::min(a.x() + as.x, b.x() + bs.x);
+        bool y = std::max(a.y(), b.y()) < std::min(a.y() + as.y, b.y() + bs.y);
+
+        bool z = true;
+        if(a.z() != 0 && b.z() != 0) {
+            z = std::max(a.z(), b.z()) < std::min(a.z() + as.z, b.z() + bs.z);
         }
-        return false;
+
+        return x && y && z;
     }
 
     bool SquareBox::operator==(const SquareBox & squareBox) const {
diff --git a/source/engine/physic/back/SquareBox.hpp b/source/engine/physic/back/SquareBox.hpp
index aa2e7df..47afd29 100644
--- a/source/engine/physic/back/SquareBox.hpp
+++ b/source/engine/physic/back/SquareBox.hpp
@@ -28,8 +28,6 @@ namespace megu {
             Cube asCube() const;
 
             void move(const Direction &);
-
-            bool contain(const Position &) const;
             bool intersect(const SquareBox &) const;
 
             bool operator==(const SquareBox &) const;
diff --git a/source/engine/physic/front/engine/Engine.cpp b/source/engine/physic/front/engine/Engine.cpp
index d32f1b3..764b163 100644
--- a/source/engine/physic/front/engine/Engine.cpp
+++ b/source/engine/physic/front/engine/Engine.cpp
@@ -53,6 +53,7 @@ namespace megu {
             for(auto & target : this->_statics[priority]) {
                 if(source.get().isColliding(target)) {
                     this->_collisions.insert(Collision(source, target));
+                    this->_collisions.insert(Collision(target, source));
                 }
             }
 
diff --git a/source/engine/physic/front/object/Tangible.cpp b/source/engine/physic/front/object/Tangible.cpp
index eb6b3df..5915036 100644
--- a/source/engine/physic/front/object/Tangible.cpp
+++ b/source/engine/physic/front/object/Tangible.cpp
@@ -1,5 +1,7 @@
 #include "Tangible.hpp"
 
+#include <iostream>
+
 namespace megu {
     Tangible::Tangible(const Position & position, const Dimension & dimension) 
     : _box(position, dimension) {}
@@ -11,6 +13,10 @@ namespace megu {
         return false;
     }
 
+    bool Tangible::isColliding(const SquareBox & box) const {
+        return this->_box.intersect(box);
+    }
+
     bool Tangible::operator==(const Tangible & entity) const {
         return this->_box == entity._box;
     }
diff --git a/source/engine/physic/front/object/Tangible.hpp b/source/engine/physic/front/object/Tangible.hpp
index 8345cf5..28a0096 100644
--- a/source/engine/physic/front/object/Tangible.hpp
+++ b/source/engine/physic/front/object/Tangible.hpp
@@ -25,6 +25,7 @@ namespace megu {
             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;
 
             bool operator==(const Tangible &) const;
             //bool operator!=(const Tangible &) const;
diff --git a/source/game/Game.cpp b/source/game/Game.cpp
index 0b838bb..eb15609 100644
--- a/source/game/Game.cpp
+++ b/source/game/Game.cpp
@@ -6,6 +6,8 @@
 #include <game/back/object/Player.hpp>
 #include <game/back/object/Enemy.hpp>
 #include <game/back/object/Level.hpp>
+#include <game/back/object/Terrain.hpp>
+#include <game/back/object/tile/TileSolide.hpp>
 #include <game/object/Test.hpp>
 
 #include <game/utility/FrameCouter.hpp>
@@ -23,23 +25,31 @@ namespace megu::game {
             FrameCounter counter;
 
             kernel::Kernel kernel(window);
-            auto path = std::filesystem::path("assets/textures/Neera.png");
-            megu::game::Object object(path);
-            //kernel.add(&object);
-            
-            Player player(16, 16, 16, 16, path);
+            auto path = std::filesystem::path("assets/player.png");
+            //megu::game::Object object(path);
+                        
+            Player player(0, 0, 32, 32, path);
             Enemy enemy(64, 64, 16, 16, path);
 
+            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.setValue(1, 1, 1);
+            terrain.setValue(0, 1, 2);
+
             Level level("STZ");
-            level.add(&player);
-            level.add(&enemy);
 
+            terrain.setup(kernel, level);
+            terrain.apply(kernel);
+            
+            //level.add(&enemy);
 
+            level.add(&player);
             player.setup(kernel, level);
             player.apply(kernel);
 
-            enemy.setup(kernel, level);
-            enemy.apply(kernel);
+            //enemy.setup(kernel, level);
+            //enemy.apply(kernel);
 
             std::cout << "..." << std::endl;
 
diff --git a/source/game/back/GameObject.hpp b/source/game/back/GameObject.hpp
index d587ea1..72aa6e9 100644
--- a/source/game/back/GameObject.hpp
+++ b/source/game/back/GameObject.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 #include <kernel/front/Kernel.hpp>
-#include <game/back/message/Behavior.hpp>
+#include <game/back/message/Event.hpp>
 
 namespace megu::game {
     class Level;
@@ -13,14 +13,17 @@ namespace megu::game {
             virtual void apply(kernel::Kernel &) = 0;
     };
 
-    class GameProps : public GameObject {
+    class GameEvent {
+        public:
+            virtual void on(const kernel::Prop &, const Event &) = 0;
+            virtual std::optional<Event> on() const = 0;
+    };
+
+    class GameProps : public GameObject, public GameEvent {
         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:
diff --git a/source/game/back/message/Behavior.cpp b/source/game/back/message/Behavior.cpp
deleted file mode 100644
index 8fe8d2e..0000000
--- a/source/game/back/message/Behavior.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#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
deleted file mode 100644
index 6a6dce2..0000000
--- a/source/game/back/message/Behavior.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#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/Event.cpp b/source/game/back/message/Event.cpp
new file mode 100644
index 0000000..f7fdd7e
--- /dev/null
+++ b/source/game/back/message/Event.cpp
@@ -0,0 +1,18 @@
+#include "Event.hpp"
+
+namespace megu::game {
+    Event::Event(uint32_t type)
+    : _type(type) {}
+
+    std::optional<uint32_t> Event::get(size_t key) const {
+        return this->_stats.get(key);
+    }
+
+    void Event::set(size_t key, uint32_t value) {
+        this->_stats.set(key, value);
+    }
+
+    bool Event::operator&(const uint32_t & type) const {
+        return (this->_type & type) != 0;
+    }
+}
\ No newline at end of file
diff --git a/source/game/back/message/Event.hpp b/source/game/back/message/Event.hpp
new file mode 100644
index 0000000..889bccb
--- /dev/null
+++ b/source/game/back/message/Event.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "StatsAlterator.hpp"
+
+namespace megu::game {
+    class Event {
+        public:
+            enum Type : uint32_t {
+                SOLID  = 1,
+                DAMAGE = 2,
+            };
+
+            Event() = delete;
+            Event(uint32_t);
+
+            std::optional<uint32_t> get(size_t) const;
+            void set(size_t, uint32_t);
+
+            bool operator&(const uint32_t &) const;
+
+        private:
+            uint32_t _type;
+            StatsAlterator<uint32_t> _stats;
+    };
+}
+
+    
+    
\ No newline at end of file
diff --git a/source/game/back/message/StatsAlterator.cpp b/source/game/back/message/StatsAlterator.cpp
deleted file mode 100644
index 4ea9589..0000000
--- a/source/game/back/message/StatsAlterator.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#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
index f8ceaf5..e4acfc4 100644
--- a/source/game/back/message/StatsAlterator.hpp
+++ b/source/game/back/message/StatsAlterator.hpp
@@ -3,19 +3,19 @@
 #include <kernel/front/props/Props.hpp>
 
 namespace megu::game {
+    template <class D>
     class StatsAlterator {
         public:
-            StatsAlterator() = delete;
-            StatsAlterator(const kernel::Prop &);
+            StatsAlterator() = default;
 
-            uint32_t get(uint32_t) const;
-            void set(uint32_t, uint32_t);
+            std::optional<D> get(size_t) const;
+            void set(size_t, D);
 
-            const uint32_t & operator[](const uint32_t &) const;
-            uint32_t & operator[](const uint32_t &);
+            std::optional<D> operator[](size_t) const;
             
         private:
-            std::map<uint32_t, uint32_t> _stats;
-            const kernel::Prop & _author;
+            std::map<size_t, D> _stats;
     };
-}
\ No newline at end of file
+}
+
+#include "StatsAlterator.tpp"
\ No newline at end of file
diff --git a/source/game/back/message/StatsAlterator.tpp b/source/game/back/message/StatsAlterator.tpp
new file mode 100644
index 0000000..155e4e3
--- /dev/null
+++ b/source/game/back/message/StatsAlterator.tpp
@@ -0,0 +1,21 @@
+#include "StatsAlterator.hpp"
+
+namespace megu::game {
+    template <class D>
+    std::optional<D> StatsAlterator<D>::get(size_t key) const {
+        if(this->_stats.contains(key)) {
+            return this->_stats.at(key);
+        }
+        return {};
+    }
+
+    template <class D>
+    void StatsAlterator<D>::set(size_t key, D value) {
+        this->_stats[key] = value;
+    }
+
+    template <class D>
+    std::optional<D> StatsAlterator<D>::operator[](size_t key) const {
+        return this->get(key);
+    }
+}
\ No newline at end of file
diff --git a/source/game/back/object/Enemy.cpp b/source/game/back/object/Enemy.cpp
index b8f416a..5e93f2b 100644
--- a/source/game/back/object/Enemy.cpp
+++ b/source/game/back/object/Enemy.cpp
@@ -18,25 +18,28 @@ namespace megu::game {
         this->_sprite.setSize({51.f, 98.f});
 
         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());
+            auto object = level.get(id);
+            if(object.has_value()) {
+                auto event = object->get().on();
+                if(event.has_value()) {
+                    this->on(*object->get().get(), event.value());
+                }  
             }
         });
     }
 
-    void Enemy::on(const Behavior & event) {
-        if(event & Behavior::Type::SOLID) {
+    void Enemy::on(const kernel::Prop &, const Event & event) {
+        if(event & Event::Type::SOLID) {
             this->onSolide(event);
         }
 
-        if(event & Behavior::Type::DAMAGE) {
+        if(event & Event::Type::DAMAGE) {
             this->onDamage(event);
         }
     }
 
-    std::optional<Behavior> Enemy::on() const {
-        Behavior b(*this, Behavior::DAMAGE);
+    std::optional<Event> Enemy::on() const {
+        Event b(Event::DAMAGE);
         b.set(0, 10);
 
         return b;
@@ -50,11 +53,11 @@ namespace megu::game {
         kernel.add(this);
     }
 
-    void Enemy::onDamage(const Behavior &) {
+    void Enemy::onDamage(const Event &) {
         std::cout << "Enemy Got Damage !" << std::endl;
     }
 
-    void Enemy::onSolide(const Behavior &) {
+    void Enemy::onSolide(const Event &) {
         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 7de2824..89bacf9 100644
--- a/source/game/back/object/Enemy.hpp
+++ b/source/game/back/object/Enemy.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
-#include <game/back/GameObject.hpp>
 #include <kernel/front/props/PropsDynamic.hpp>
+#include <game/back/GameObject.hpp>
 #include <game/back/object/Level.hpp>
 
 namespace megu::game {
@@ -16,11 +16,11 @@ namespace megu::game {
 
             void apply(kernel::Kernel &) override;
 
-            void on(const Behavior &) override;
-            std::optional<Behavior> on() const override;
+            void on(const kernel::Prop &, const Event &) override;
+            std::optional<Event> on() const override;
 
-            void onDamage(const Behavior &);
-            void onSolide(const Behavior &); 
+            void onDamage(const Event &);
+            void onSolide(const Event &); 
 
         private:
             kernel::Sprite _sprite;
diff --git a/source/game/back/object/Level.cpp b/source/game/back/object/Level.cpp
index 8dc9f55..5fbbcfd 100644
--- a/source/game/back/object/Level.cpp
+++ b/source/game/back/object/Level.cpp
@@ -4,8 +4,13 @@ namespace megu::game {
     Level::Level(const std::string & name)
     :  _name(name) {}
 
-    GameProps * Level::get(Identifiable & id) const {
-        return this->_objecs.at(id.id());
+    std::optional<std::reference_wrapper<GameProps>> Level::get(Identifiable & id) const {
+        for(auto it = this->_objecs.begin(); it != this->_objecs.end(); ++it) {
+            if(it->first == id) {
+                return *it->second;
+            }
+        }
+        return {};
     }
 
     void Level::add(GameProps * prop) {
diff --git a/source/game/back/object/Level.hpp b/source/game/back/object/Level.hpp
index 3f047c9..f82e2a9 100644
--- a/source/game/back/object/Level.hpp
+++ b/source/game/back/object/Level.hpp
@@ -12,7 +12,7 @@ namespace megu::game {
 
             void add(GameProps *);
 
-            GameProps * get(Identifiable &) const;
+            std::optional<std::reference_wrapper<GameProps>> get(Identifiable &) const;
 
             virtual void apply(kernel::Kernel &) override final;
             virtual void setup(kernel::Kernel &, Level &) override;
diff --git a/source/game/back/object/Player.cpp b/source/game/back/object/Player.cpp
index df16c72..d77418f 100644
--- a/source/game/back/object/Player.cpp
+++ b/source/game/back/object/Player.cpp
@@ -7,6 +7,7 @@ namespace megu::game {
     Player::Player(float x, float y, float w, float h, std::filesystem::path & path)
     : kernel::PropsPlayable(this->_sprite, this->_movable), GameProps(this), _sprite(path), _movable(x, y, w, h) {
         this->_sprite.setPosition({x, y});
+        this->_sprite.setLayerObject(2);
     }
 
     void Player::move(float x, float y) {
@@ -17,28 +18,32 @@ namespace megu::game {
     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->_sprite.setFrame({0.f, 0.f, 16.f, 16.f});
+        this->_sprite.setSize({32.f, 32.f});
 
         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());
+            auto object = level.get(id);
+
+            if(object.has_value()) {
+                auto event = object.value().get().on();  
+                if(event.has_value()) {
+                    this->on(*object.value().get().get(), event.value());
+                }
             }
         });
     }
 
-    void Player::on(const Behavior & event) {
-        if((event & Behavior::Type::SOLID) != 0) {
+    void Player::on(const kernel::Prop &, const Event & event) {
+        if((event & Event::Type::SOLID) != 0) {
             this->onSolide(event);
         }
 
-        if((event & Behavior::Type::DAMAGE) != 0) {
+        if((event & Event::Type::DAMAGE) != 0) {
             this->onDamage(event);
         }
     }
 
-    std::optional<Behavior> Player::on() const {
+    std::optional<Event> Player::on() const {
         return {};
     }
 
@@ -50,12 +55,12 @@ namespace megu::game {
         kernel.add(this);
     }
 
-    void Player::onDamage(const Behavior & b) {
+    void Player::onDamage(const Event & b) {
         std::cout << "Player Got Damage !" << std::endl;
-        std::cout << "I take " << b.get(0) << " damage !" << std::endl;
+        std::cout << "I take " << b.get(0).value_or(0) << " damage !" << std::endl;
     }
 
-    void Player::onSolide(const Behavior &) {
+    void Player::onSolide(const Event &) {
         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 8fa5dea..f97e264 100644
--- a/source/game/back/object/Player.hpp
+++ b/source/game/back/object/Player.hpp
@@ -16,11 +16,11 @@ namespace megu::game {
 
             void apply(kernel::Kernel &) override;
 
-            void on(const Behavior &) override;
-            std::optional<Behavior> on() const override;
+            void on(const kernel::Prop &, const Event &) override;
+            std::optional<Event> on() const override;
 
-            void onDamage(const Behavior &);
-            void onSolide(const Behavior &); 
+            void onDamage(const Event &);
+            void onSolide(const Event &); 
 
         private:
             kernel::Sprite _sprite;
diff --git a/source/game/back/object/Terrain.cpp b/source/game/back/object/Terrain.cpp
new file mode 100644
index 0000000..dceb37e
--- /dev/null
+++ b/source/game/back/object/Terrain.cpp
@@ -0,0 +1,58 @@
+#include "Terrain.hpp"
+
+#include <game/back/object/Level.hpp>
+
+namespace megu::game {
+    Terrain::Terrain(float x, float y, float w, float h, const std::filesystem::path & path, size_t r, size_t c , float size, size_t tileSize)
+    : PropsTileMap(this->_graphic, this->_physic), GameProps(this), _graphic(path, r, c, size, tileSize), _physic(x, y, r * w, c * h) {
+        //! Taille Pour 1 tile !
+        this->_graphic.setSize({w, h});
+    }
+
+    void Terrain::setValue(size_t x, size_t y, size_t value) {
+        this->_graphic.setValue(x, y, value);
+        if(this->_event.contains(value)) {
+            this->_physic.push({static_cast<float>(x) * this->_graphic.getSize().x, (this->_graphic.getSize().y * (this->_graphic.height()- 1)) - static_cast<float>(y) * this->_graphic.getSize().y}, *this->_event[value]);
+        }
+    }
+
+    void Terrain::setTileEvent(size_t id, Tile * tile) {
+        this->_event[id] = std::shared_ptr<Tile>(tile);
+    }
+
+    void Terrain::setup(kernel::Kernel & kernel, Level & level) {
+        this->_physic.setCollideLambda([this, &level](kernel::Kernel &, kernel::PhysicEngine &, Identifiable & id, kernel::Tile & tile, double) {
+            auto it = this->_event.begin();
+            for(; it != this->_event.end(); ++it) {
+                if(*it->second == tile) {
+                    break;
+                }
+            }
+
+            if(it != this->_event.end()) {
+                auto object = level.get(id);
+                auto event = it->second->on();
+                
+                if(event.has_value() && object.has_value()) {
+                    object.value().get().on(*this, event.value());
+                }
+            }
+        });
+    }
+
+    void Terrain::destroy(kernel::Kernel & kernel, Level & level) {
+        this->_event.clear();
+    }
+
+    void Terrain::apply(kernel::Kernel & kernel) {
+        kernel.add(this);
+    }
+
+    void Terrain::on(const kernel::Prop &, const Event & event) {
+        // The terrain itself don't react.
+    }
+
+    std::optional<Event> Terrain::on() const {
+        return {};
+    }
+}
\ No newline at end of file
diff --git a/source/game/back/object/Terrain.hpp b/source/game/back/object/Terrain.hpp
new file mode 100644
index 0000000..8fa99ec
--- /dev/null
+++ b/source/game/back/object/Terrain.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <kernel/front/props/PropsTileMap.hpp>
+#include <kernel/front/component/physic/TileArray.hpp>
+#include <kernel/front/component/graphic/TileMap.hpp>
+
+#include <game/back/GameObject.hpp>
+#include <game/back/object/tile/Tile.hpp>
+
+namespace megu::game {
+    class Terrain : public kernel::PropsTileMap, public GameProps {
+        public:
+            Terrain() = delete;
+            Terrain(float, float, float, float, const std::filesystem::path &, size_t, size_t, float, size_t);
+
+            void setValue(size_t, size_t, size_t);
+            void setTileEvent(size_t, Tile *);
+
+            void setup(kernel::Kernel &, Level &) override;
+            void destroy(kernel::Kernel &, Level &) override;
+            void apply(kernel::Kernel &) override;
+
+            void on(const kernel::Prop &, const Event &) override;
+            std::optional<Event> on() const override;
+
+        private:
+            kernel::Tilemap _graphic;
+            kernel::TileArray _physic;
+            std::map<size_t, std::shared_ptr<Tile>> _event;
+
+    };
+}
\ No newline at end of file
diff --git a/source/game/back/object/tile/Tile.cpp b/source/game/back/object/tile/Tile.cpp
new file mode 100644
index 0000000..e255187
--- /dev/null
+++ b/source/game/back/object/tile/Tile.cpp
@@ -0,0 +1,6 @@
+#include "Tile.hpp"
+
+namespace megu::game {
+    Tile::Tile(float d)
+    : kernel::Tile(0, 0, d) {}
+}
\ No newline at end of file
diff --git a/source/game/back/object/tile/Tile.hpp b/source/game/back/object/tile/Tile.hpp
new file mode 100644
index 0000000..ec35a38
--- /dev/null
+++ b/source/game/back/object/tile/Tile.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <kernel/front/component/physic/Tile.hpp>
+#include <game/back/GameObject.hpp>
+
+#include <iostream>
+
+namespace megu::game {
+    class Tile : public kernel::Tile, public GameEvent {
+        public:
+            Tile() = delete;
+            Tile(float d);
+    };
+}
\ No newline at end of file
diff --git a/source/game/back/object/tile/TileSolide.cpp b/source/game/back/object/tile/TileSolide.cpp
new file mode 100644
index 0000000..91d1ae7
--- /dev/null
+++ b/source/game/back/object/tile/TileSolide.cpp
@@ -0,0 +1,14 @@
+#include "TileSolide.hpp"
+
+namespace megu::game {
+    TileSolide::TileSolide(float d) 
+    : Tile(d) {}
+
+    void TileSolide::on(const kernel::Prop &, const Event &) {
+        //...
+    }
+
+    std::optional<Event> TileSolide::on() const {
+        return Event(Event::Type::SOLID);
+    }
+}
\ No newline at end of file
diff --git a/source/game/back/object/tile/TileSolide.hpp b/source/game/back/object/tile/TileSolide.hpp
new file mode 100644
index 0000000..84424f2
--- /dev/null
+++ b/source/game/back/object/tile/TileSolide.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "Tile.hpp" 
+
+namespace megu::game {
+    class TileSolide : public Tile {
+        public:
+            TileSolide(float d);
+
+            void on(const kernel::Prop &, const Event &) override;
+            std::optional<Event> on() const override;
+    }; 
+}
\ No newline at end of file
diff --git a/source/game/front/profile/PlayerKeys.cpp b/source/game/front/profile/PlayerKeys.cpp
index 3d835a9..ffeafb6 100644
--- a/source/game/front/profile/PlayerKeys.cpp
+++ b/source/game/front/profile/PlayerKeys.cpp
@@ -6,19 +6,19 @@ namespace megu::game {
 
     void PlayerKeyProfile::on(Key key, int code, Action action, Mod mode) {
         if(key == Keyboard::Key::ARROW_UP) {
-            this->_player.move(0.f, 1.f);
+            this->_player.move(0.f, 0.5f);
         }
 
         if(key == Keyboard::Key::ARROW_DOWN) {
-            this->_player.move(0.f, -1.f);
+            this->_player.move(0.f, -0.5f);
         }
 
         if(key == Keyboard::Key::ARROW_LEFT) {
-            this->_player.move(-1.f, 0.f);
+            this->_player.move(-0.5f, 0.f);
         }
 
         if(key == Keyboard::Key::ARROW_RIGHT) {
-            this->_player.move(1.f, 0.f);
+            this->_player.move(0.5f, 0.f);
         }
     }
 }
\ No newline at end of file
diff --git a/source/kernel/back/linker/UniqueLinker.tpp b/source/kernel/back/linker/UniqueLinker.tpp
index 907a106..4a83e21 100644
--- a/source/kernel/back/linker/UniqueLinker.tpp
+++ b/source/kernel/back/linker/UniqueLinker.tpp
@@ -20,8 +20,8 @@ namespace megu::kernel {
         this->_delete.clear();
 
         for(auto & [layer, object] : this->_await) {
-            this->_stored.insert({layer, object});
-            size_t id = engine.get().push<T>(layer.layer, layer.object, this->_stored[layer], this->_module.get());
+            this->_stored.insert({layer, {object, 0}});
+            size_t id = engine.get().push<T>(layer.layer, layer.object, this->_stored.at(layer).first.get(), this->_module.get());
             this->_ids[layer] = id;
         }
 
@@ -31,7 +31,7 @@ namespace megu::kernel {
     template <class T>
     void UniqueGraphicLinker<T>::unlink(T & object) {
         for(auto & [layer, obj] : this->_stored) {
-            if(&(obj.get()) == &object) {
+            if(&(obj.first.get()) == &object) {
                 this->_delete.insert(layer);
             }
         }
diff --git a/source/kernel/front/Kernel.cpp b/source/kernel/front/Kernel.cpp
index 59c9428..b69022e 100644
--- a/source/kernel/front/Kernel.cpp
+++ b/source/kernel/front/Kernel.cpp
@@ -27,6 +27,7 @@ namespace megu::kernel {
     void Kernel::add(Prop * props) {
         this->_props[props->id()] = props;
         auto * pComponent = props->getPhysicComponent();
+
         if(pComponent != nullptr) {
             this->_pEngine.add(*this, *pComponent);
             this->_pResolver.add(*pComponent);
diff --git a/source/kernel/front/component/graphic/TileMap.hpp b/source/kernel/front/component/graphic/TileMap.hpp
index 6d6ad9d..648bedd 100644
--- a/source/kernel/front/component/graphic/TileMap.hpp
+++ b/source/kernel/front/component/graphic/TileMap.hpp
@@ -11,7 +11,7 @@
 #include <engine/graphics/front/module/TileArray_Module.hpp> 
 
 namespace megu::kernel {
-    class Tilemap : public Graphical<GraphicEngine>, public TileArray {
+    class Tilemap : public Graphical<GraphicEngine>, public megu::TileArray {
         public:
             struct TilePosition {
                 size_t x = 0;
diff --git a/source/kernel/front/component/physic/Fixed.cpp b/source/kernel/front/component/physic/Fixed.cpp
index a887afd..1b0f4ca 100644
--- a/source/kernel/front/component/physic/Fixed.cpp
+++ b/source/kernel/front/component/physic/Fixed.cpp
@@ -3,8 +3,8 @@
 #include <kernel/front/Kernel.hpp>
 
 namespace megu::kernel {
-    Fixed::Fixed(float x, float y, float w, float h)
-    : TangibleStatic(Position(x, y), Dimension(w, h, 0.f)) {} 
+    Fixed::Fixed(float x, float y, float w, float h, CollideLambda cl, UpdateLambda ul)
+    : TangibleStatic(Position(x, y), Dimension(w, h, 0.f)), _collide(cl), _update(ul) {} 
 
     void Fixed::update_physic(double time) const {
         if(this->_update != nullptr) {
diff --git a/source/kernel/front/component/physic/Fixed.hpp b/source/kernel/front/component/physic/Fixed.hpp
index 7ef7041..22fe2dd 100644
--- a/source/kernel/front/component/physic/Fixed.hpp
+++ b/source/kernel/front/component/physic/Fixed.hpp
@@ -10,7 +10,7 @@
 namespace megu::kernel {
     class Fixed : public TangibleStatic, public Physical<PhysicEngine> {
         public:
-            Fixed(float x, float y, float w, float h);
+            Fixed(float x, float y, float w, float h, CollideLambda = nullptr, UpdateLambda = nullptr);
 
             void update_physic(double) const override;
             void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override;
diff --git a/source/kernel/front/component/physic/FixedArray.cpp b/source/kernel/front/component/physic/FixedArray.cpp
deleted file mode 100644
index a0b61a7..0000000
--- a/source/kernel/front/component/physic/FixedArray.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "FixedArray.hpp"
-
-#include <kernel/front/Kernel.hpp>
-
-namespace megu::kernel {
-    std::optional<std::reference_wrapper<const TangibleStatic>> FixedArray::at(const Position & position) const {
-        if(this->_tangibles.contains(position)) {
-            return this->_tangibles.at(position);
-        }
-        return {};
-    }
-
-    void FixedArray::push(const Fixed & tangible) {
-        this->_tangibles.insert({tangible.getPosition(), tangible});
-    }
-
-    void FixedArray::erase(const Fixed & tangible) {
-        this->_tangibles.erase(tangible.getPosition());
-    }
-
-    void FixedArray::erase(const Position & position) {
-        this->_tangibles.erase(position);
-    }
-
-    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, id, fixed, time);
-            }
-        }
-    }
-
-    void FixedArray::update_physic(double time) const {
-        if(this->_update != nullptr) {
-            this->_update(time);
-        }
-    }
-
-    void FixedArray::apply(Kernel & kernel, PhysicEngine & engine) {
-        engine.get().push(0, *this);
-    }
-
-    void FixedArray::unapply(Kernel & kernel, PhysicEngine & engine) {
-        engine.get().remove(*this);
-    }
-
-    void FixedArray::setCollideLambda(CollideLambda lambda) {
-        this->_collide = lambda;
-    }
-
-    void FixedArray::setUpdateLambda(UpdateLambda lambda) {
-        this->_update = lambda;
-    }
-}
\ No newline at end of file
diff --git a/source/kernel/front/component/physic/FixedArray.hpp b/source/kernel/front/component/physic/FixedArray.hpp
deleted file mode 100644
index 73f1dae..0000000
--- a/source/kernel/front/component/physic/FixedArray.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <kernel/back/component/Physical.hpp>
-#include <kernel/back/engine/PhysicEngine.hpp>
-#include <vector>
-#include <functional>
-
-#include "Fixed.hpp"
-
-namespace megu::kernel {
-    class FixedArray : public Physical<PhysicEngine>, public TangibleStatic {
-        public:
-            std::optional<std::reference_wrapper<const TangibleStatic>> at(const Position &) const;
-
-            void push(const Fixed &);
-            void erase(const Fixed &);
-            void erase(const Position &);
-        
-            void setCollideLambda(CollideLambda);
-            void setUpdateLambda(UpdateLambda);
-
-            void update_physic(double) const override;
-            void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override;
-            void apply(Kernel & k, PhysicEngine &) override;
-            void unapply(Kernel & k, PhysicEngine &) override;
-
-        private:
-            std::map<Position, Fixed> _tangibles;
-            CollideLambda _collide;
-            UpdateLambda _update;
-    };
-}
\ No newline at end of file
diff --git a/source/kernel/front/component/physic/Movable.cpp b/source/kernel/front/component/physic/Movable.cpp
index df0eef5..a48eae0 100644
--- a/source/kernel/front/component/physic/Movable.cpp
+++ b/source/kernel/front/component/physic/Movable.cpp
@@ -1,8 +1,8 @@
 #include "Movable.hpp"
 
 namespace megu::kernel {
-    Movable::Movable(float x, float y, float w, float h)
-    : TangibleMovable(Position(x, y), Dimension(w, h, 0.f)) {}
+    Movable::Movable(float x, float y, float w, float h, CollideLambda cl, UpdateLambda ul)
+    : TangibleMovable(Position(x, y), Dimension(w, h, 0.f)), _collide(cl), _update(ul) {}
 
     void Movable::update_physic(double time) {
         if(this->_update != nullptr) {
diff --git a/source/kernel/front/component/physic/Movable.hpp b/source/kernel/front/component/physic/Movable.hpp
index bdb94e6..45cd760 100644
--- a/source/kernel/front/component/physic/Movable.hpp
+++ b/source/kernel/front/component/physic/Movable.hpp
@@ -10,7 +10,7 @@
 namespace megu::kernel {
     class Movable : public TangibleMovable, public Physical<PhysicEngine> {
         public:
-            Movable(float x, float y, float w, float h);
+            Movable(float x, float y, float w, float h, CollideLambda = nullptr, UpdateLambda = nullptr);
 
             void update_physic(double) override;
             void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override;
diff --git a/source/kernel/front/component/physic/Tile.cpp b/source/kernel/front/component/physic/Tile.cpp
new file mode 100644
index 0000000..eafd5df
--- /dev/null
+++ b/source/kernel/front/component/physic/Tile.cpp
@@ -0,0 +1,26 @@
+#include "Tile.hpp"
+
+namespace megu::kernel {
+    Tile::Tile(float x, float y, float d)
+    : Fixed(x, y, d, d) {}
+
+    bool Tile::operator==(const Tile & tile) const {
+        return this->id() == tile.id();
+    }
+
+    bool Tile::operator>=(const Tile & tile) const {
+        return this->id() >= tile.id();
+    }
+
+    bool Tile::operator<=(const Tile & tile) const {
+        return this->id() <= tile.id();
+    }
+
+    bool Tile::operator>(const Tile & tile) const {
+        return this->id() > tile.id();
+    }
+
+    bool Tile::operator<(const Tile & tile) const {
+        return this->id() < tile.id();
+    }
+}
\ No newline at end of file
diff --git a/source/kernel/front/component/physic/Tile.hpp b/source/kernel/front/component/physic/Tile.hpp
new file mode 100644
index 0000000..112ac25
--- /dev/null
+++ b/source/kernel/front/component/physic/Tile.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "Fixed.hpp"
+
+namespace megu::kernel {
+    class Tile : public Fixed {
+        public:
+            Tile(float x, float y, float d);
+
+            bool operator==(const Tile &) const;
+            bool operator>=(const Tile &) const;
+            bool operator<=(const Tile &) const;
+            bool operator>(const Tile &) const;
+            bool operator<(const Tile &) const;        
+    };
+}
\ No newline at end of file
diff --git a/source/kernel/front/component/physic/TileArray.cpp b/source/kernel/front/component/physic/TileArray.cpp
new file mode 100644
index 0000000..4dd9bc5
--- /dev/null
+++ b/source/kernel/front/component/physic/TileArray.cpp
@@ -0,0 +1,69 @@
+#include "TileArray.hpp"
+
+#include <kernel/front/Kernel.hpp>
+
+namespace megu::kernel {
+    TileArray::TileArray(float x, float y, float w, float h, CollideLambda cl, UpdateLambda ul) 
+    : TangibleStatic(Position(x, y), Dimension(w, h, 0.f)), _collide(cl), _update(ul) {}
+
+    std::optional<std::reference_wrapper<const Tile>> TileArray::at(const Position & position) const {
+        for(auto & [pos, tile] : this->_tiles) {
+            if(pos == position) {
+                return tile;
+            }
+        }
+        
+        return std::optional<std::reference_wrapper<const Tile>>();
+    }
+
+    void TileArray::push(const Position & position, Tile & tile) {
+        this->_tiles.insert({position, tile});
+    }
+
+    void TileArray::erase(const Tile & tile) {
+        for(auto it = this->_tiles.begin(); it != this->_tiles.end();) {
+            if(it->second.get().id() == tile.id()) {
+                it = this->_tiles.erase(it);
+            }
+            else {
+                ++it;
+            }
+        }
+    }
+
+    void TileArray::on_collide(Kernel & kernel, PhysicEngine & engine, Identifiable & id, Physical & physical, double time) {
+        if(this->_collide == nullptr) {
+            return;
+        }
+        
+        auto & tangible = engine.get(physical);
+        for(auto & [positon, tile] : this->_tiles) {
+            SquareBox box = SquareBox(positon, tile.get().getBox().dimension());
+            if(tangible.isColliding(box)) {
+                this->_collide(kernel, engine, id, tile, time);
+            }
+        }
+    }
+
+    void TileArray::update_physic(double time) const {
+        if(this->_update != nullptr) {
+            this->_update(time);
+        }
+    }
+
+    void TileArray::apply(Kernel & kernel, PhysicEngine & engine) {
+        engine.get().push(0, *this);
+    }
+
+    void TileArray::unapply(Kernel & kernel, PhysicEngine & engine) {
+        engine.get().remove(*this);
+    }
+
+    void TileArray::setCollideLambda(TileCollideLambda lambda) {
+        this->_collide = lambda;
+    }
+
+    void TileArray::setUpdateLambda(UpdateLambda lambda) {
+        this->_update = lambda;
+    }
+}
\ No newline at end of file
diff --git a/source/kernel/front/component/physic/TileArray.hpp b/source/kernel/front/component/physic/TileArray.hpp
new file mode 100644
index 0000000..a3ade2b
--- /dev/null
+++ b/source/kernel/front/component/physic/TileArray.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <kernel/back/component/Physical.hpp>
+#include <kernel/back/engine/PhysicEngine.hpp>
+#include <vector>
+#include <functional>
+
+#include "Tile.hpp"
+
+namespace megu::kernel {
+    class TileArray : public Physical<PhysicEngine>, public TangibleStatic {
+        public:
+            TileArray(float, float, float, float, CollideLambda = nullptr, UpdateLambda = nullptr);
+
+            std::optional<std::reference_wrapper<const Tile>> at(const Position &) const;
+
+            void push(const Position &, Tile &);
+            void erase(const Tile &);
+
+            using TileCollideLambda = std::function<void(Kernel &, PhysicEngine &, Identifiable &, Tile &, double)>;
+        
+            void setCollideLambda(TileCollideLambda);
+            void setUpdateLambda(UpdateLambda);
+
+            void update_physic(double) const override;
+            void apply(Kernel & k, PhysicEngine &) override;
+            void unapply(Kernel & k, PhysicEngine &) override;
+            void on_collide(Kernel &, PhysicEngine &, Identifiable &, Physical &, double) override;
+
+        private:
+            std::map<Position, std::reference_wrapper<Tile>> _tiles;
+            TileCollideLambda _collide;
+            UpdateLambda _update;
+    };
+}
\ No newline at end of file
diff --git a/source/kernel/front/props/PropsTileMap.cpp b/source/kernel/front/props/PropsTileMap.cpp
index 8ec7d35..b00c76e 100644
--- a/source/kernel/front/props/PropsTileMap.cpp
+++ b/source/kernel/front/props/PropsTileMap.cpp
@@ -1,7 +1,7 @@
 #include "PropsTileMap.hpp"
 
 namespace megu::kernel {
-    PropsTileMap::PropsTileMap(Tilemap & tilemap, FixedArray & fixedarray)
+    PropsTileMap::PropsTileMap(Tilemap & tilemap, TileArray & fixedarray)
     : _graphic(tilemap), _physic(fixedarray) {} 
 
 }
\ No newline at end of file
diff --git a/source/kernel/front/props/PropsTileMap.hpp b/source/kernel/front/props/PropsTileMap.hpp
index eee3f71..993e9b5 100644
--- a/source/kernel/front/props/PropsTileMap.hpp
+++ b/source/kernel/front/props/PropsTileMap.hpp
@@ -2,18 +2,18 @@
 
 #include <kernel/front/props/Props.hpp>
 #include <kernel/front/component/graphic/TileMap.hpp>
-#include <kernel/front/component/physic/FixedArray.hpp>
+#include <kernel/front/component/physic/TileArray.hpp>
 
 namespace megu::kernel {
     class PropsTileMap : public Prop {
         public:
-            PropsTileMap(Tilemap &, FixedArray &);
+            PropsTileMap(Tilemap &, TileArray &);
 
             inline Prop::Graphical_Component * getGraphicComponent() override {return &this->_graphic;}
             inline Prop::Physical_Component * getPhysicComponent() override {return &this->_physic;}
 
         private:
             Tilemap & _graphic;
-            FixedArray & _physic;  
+            kernel::TileArray & _physic;  
     };
 }
\ No newline at end of file
-- 
GitLab