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 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 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