diff --git a/src/gameplayscene.cpp b/src/gameplayscene.cpp index 0a1756d..0e03736 100644 --- a/src/gameplayscene.cpp +++ b/src/gameplayscene.cpp @@ -20,6 +20,8 @@ #include "gameplayscene.hpp" #include "mover.hpp" #include "drawable.hpp" +#include "placeable.hpp" +#include namespace cloonel { ///-------------------------------------------------------------------------- @@ -32,8 +34,18 @@ namespace cloonel { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- void GameplayScene::OnUpdate (float parDelta) { - for (auto itMover : m_movers) { - itMover->Update(parDelta); + { + std::unordered_set notify; + for (auto mover : m_movers) { + mover->CopyPlaceables(notify); + } + for (auto placeable : notify) { + assert(placeable); + placeable->BeginMovement(); + } + } + for (auto mover : m_movers) { + mover->Update(parDelta); } m_collider.RunCollisionTests(parDelta); } diff --git a/src/horzcollisionbar.cpp b/src/horzcollisionbar.cpp index de706cf..d3b5454 100644 --- a/src/horzcollisionbar.cpp +++ b/src/horzcollisionbar.cpp @@ -41,8 +41,8 @@ namespace cloonel { ///reference time frame. ///---------------------------------------------------------------------- float calculateOverlappingTime (float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB) { - const float deltaDiff = std::max(parDeltaA, parDeltaB) - std::min(parDeltaA, parDeltaB); - assert(deltaDiff >= 0.0f); + //const float deltaDiff = std::max(parDeltaA, parDeltaB) - std::min(parDeltaA, parDeltaB); + const float deltaDiff = std::abs(parDeltaA - parDeltaB); if (deltaDiff <= 0.00001f) return 0.0f; @@ -67,6 +67,7 @@ namespace cloonel { const auto& retStart = (midpointA.Start().x() > midpointB.Start().x() ? midpointA.Start() : midpointB.Start()); const auto& retEnd = (midpointA.End().x() < midpointB.End().x() ? midpointA.End() : midpointB.End()); + assert(retStart.y() == retEnd.y()); return std::make_pair(true, Line2D(retStart, retEnd)); } @@ -82,6 +83,7 @@ namespace cloonel { HorzCollisionBar::HorzCollisionBar (const float2& parFrom, float parLength) : Placeable(parFrom), m_segment(parFrom, float2(1.0f, 0.0f), parLength), + m_offset(0.0f), m_callback(&DoNothing) { assert(parLength != 0.0f); @@ -105,12 +107,24 @@ namespace cloonel { m_callback(parOverlap, parDirection); } + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void HorzCollisionBar::AddOffset (const float2& parOffset) noexcept { + Placeable::AddOffset(parOffset); + m_segment += parOffset; + m_offset += parOffset; + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void HorzCollisionBar::BeginMovement() { + m_offset = float2(0.0f); + } + ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- bool Collide (float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, HorzCollisionBar::Line2D& parOut) { - const auto offsetA = parA.GetPos() - parA.m_segment.Start(); - const auto offsetB = parB.GetPos() - parB.m_segment.Start(); - const auto overlap(getOverlap(parDeltaT, parA.m_segment, parB.m_segment, offsetA, offsetB)); + const auto overlap(getOverlap(parDeltaT, parA.m_segment, parB.m_segment, parA.GetOffset(), parB.GetOffset())); if (overlap.first) { parOut = overlap.second; diff --git a/src/horzcollisionbar.hpp b/src/horzcollisionbar.hpp index f3eb933..71e046b 100644 --- a/src/horzcollisionbar.hpp +++ b/src/horzcollisionbar.hpp @@ -35,18 +35,24 @@ namespace cloonel { public: HorzCollisionBar ( const float2& parFrom, float parLength ); - ~HorzCollisionBar ( void ) noexcept = default; + virtual ~HorzCollisionBar ( void ) noexcept = default; float2 From ( void ) const { return this->GetPos(); } float2 To ( void ) const; void SetCallback ( CallbackType parCallback ); void InvokeCallback ( const Line2D& parOverlap, const float2& parDirection ) const; + const float2& GetOffset ( void ) const noexcept { return m_offset; } + + //Overrides + virtual void AddOffset ( const float2& parOffset ) noexcept; + virtual void BeginMovement ( void ); private: friend bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line2D& parOut ); Line2D m_segment; + float2 m_offset; CallbackType m_callback; }; diff --git a/src/movers/mover.cpp b/src/movers/mover.cpp index 234ddfc..7da8bf0 100644 --- a/src/movers/mover.cpp +++ b/src/movers/mover.cpp @@ -45,4 +45,10 @@ namespace cloonel { parPlaceable->OnRegister(*this, currTicket); return currTicket; } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void Mover::CopyPlaceables (std::unordered_set& parOut) { + m_placeables.CopyObservers(parOut); + } } //namespace cloonel diff --git a/src/movers/mover.hpp b/src/movers/mover.hpp index e0e6a63..5e3e7d8 100644 --- a/src/movers/mover.hpp +++ b/src/movers/mover.hpp @@ -22,6 +22,7 @@ #include "vector.hpp" #include "observersmanager.hpp" +#include namespace cloonel { class Placeable; @@ -40,6 +41,7 @@ namespace cloonel { virtual void Update ( float parDelta ); PlaceableTicketType RegisterPlaceable ( Placeable* parPlaceable, PlaceableTicketType parParent=ObserversManager::Ticket_Null ); void UnregisterPlaceable ( PlaceableTicketType parID ) noexcept { m_placeables.Remove(parID); } + void CopyPlaceables ( std::unordered_set& parOut ); protected: std::size_t PlaceableCount ( void ) const { return m_placeables.size(); } diff --git a/src/observersmanager.hpp b/src/observersmanager.hpp index 3d1c865..926c532 100644 --- a/src/observersmanager.hpp +++ b/src/observersmanager.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #if defined (WITH_VERBOSE_OBS_MANAGER) && defined(__GNUC__) && __GNUC__ >= 2 && !defined(NDEBUG) # define OBS_MANAGER_LOG @@ -78,6 +79,7 @@ namespace cloonel { std::size_t size ( void ) const { return m_tree.size(); } iterator begin ( void ) { return iterator(m_tree.begin(), &TicketedWrapperToItm); } iterator end ( void ) { return iterator(m_tree.end(), &TicketedWrapperToItm); } + void CopyObservers ( std::unordered_set& parOut ); private: TreeIteratorType GetByTicket_AssertPresent ( TicketType parTicket ); @@ -161,6 +163,15 @@ namespace cloonel { assert(m_tree.end() != ret); return ret; } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + void ObserversManager::CopyObservers (std::unordered_set& parOut) { + for (const auto& itm : m_tree) { + parOut.insert(itm.itm); + } + } } //namespace cloonel #if defined(OBS_MANAGER_LOG) diff --git a/src/placeable.cpp b/src/placeable.cpp index a196317..6daa7f5 100644 --- a/src/placeable.cpp +++ b/src/placeable.cpp @@ -34,4 +34,9 @@ namespace cloonel { void Placeable::OnRegister (Mover&, Mover::PlaceableTicketType) { return; } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void Placeable::BeginMovement() { + } } //namespace cloonel diff --git a/src/placeable.hpp b/src/placeable.hpp index 1969160..f9208da 100644 --- a/src/placeable.hpp +++ b/src/placeable.hpp @@ -27,12 +27,13 @@ namespace cloonel { class Placeable { public: float2 GetPos ( void ) const noexcept; - void AddOffset ( const float2& parOffset ) noexcept; + virtual void AddOffset ( const float2& parOffset ) noexcept; virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket ); + virtual void BeginMovement ( void ); protected: explicit Placeable ( float2 parPos ); - ~Placeable ( void ) noexcept = default; + virtual ~Placeable ( void ) noexcept = default; private: float2 m_pos;