From 896b368cbe1440c8d02e72104cf0af192cfe26cf Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 13 Aug 2014 22:45:37 +0200 Subject: [PATCH] Refactoring to split the PlatformSystem into a PlatformSet subpart. Also introduces the same concept for Drawables, with DrawableSet. Single drawables can't be registered anymore. --- CMakeLists.txt | 1 + src/character.hpp | 5 +- src/collider.cpp | 87 +++++++++++++++++++++++++--- src/collider.hpp | 5 ++ src/collisionbarset.hpp | 35 ++++++++++++ src/drawableset.hpp | 35 ++++++++++++ src/gameplayscene.cpp | 10 +++- src/gameplayscene.hpp | 6 +- src/gameplaysceneclassic.cpp | 11 ++-- src/platform.hpp | 1 + src/platformset.cpp | 100 ++++++++++++++++++++++++++++++++ src/platformset.hpp | 62 ++++++++++++++++++++ src/platformsystem.cpp | 108 +++++++++++++---------------------- src/platformsystem.hpp | 19 +++--- src/tiledwallpaper.hpp | 7 ++- 15 files changed, 393 insertions(+), 99 deletions(-) create mode 100644 src/collisionbarset.hpp create mode 100644 src/drawableset.hpp create mode 100644 src/platformset.cpp create mode 100644 src/platformset.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bea885..7e1e177 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ add_executable(${PROJECT_NAME} src/movers/moverworld.cpp src/line.cpp src/collider.cpp + src/platformset.cpp ) target_link_libraries(${PROJECT_NAME} diff --git a/src/character.hpp b/src/character.hpp index da31922..97f44a8 100644 --- a/src/character.hpp +++ b/src/character.hpp @@ -22,6 +22,7 @@ #include "placeable.hpp" #include "drawable.hpp" +#include "drawableset.hpp" #include "vector.hpp" #include "sizenotifiable.hpp" #include "horzcollisionbar.hpp" @@ -30,13 +31,14 @@ #include #include #include +#include namespace cloonel { class SDLMain; class Texture; template class Line; - class Character : public Placeable, public Drawable { + class Character : public Placeable, public Drawable, public DrawableSet { public: typedef std::function&, const float2&)> BounceCallbackType; @@ -54,6 +56,7 @@ namespace cloonel { private: //Overrides virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket ); + virtual void CopyDrawables ( std::vector& parOut ) const { parOut.push_back(this); } void OnBounce ( const Line& parCollision, const float2& parDirection ); diff --git a/src/collider.cpp b/src/collider.cpp index 5d5bdf0..78439af 100644 --- a/src/collider.cpp +++ b/src/collider.cpp @@ -21,6 +21,7 @@ #include "horzcollisionbar.hpp" #include "line.hpp" #include "vector.hpp" +#include "collisionbarset.hpp" #include "vectormath.hpp" #include #include @@ -36,7 +37,11 @@ namespace cloonel { namespace { typedef std::vector CollisionBarListType; typedef std::vector> CollisionBarGroupListType; - const CollisionBarListType g_empty; + typedef std::vector CollisionBarSetListType; + typedef std::vector> CollisionBarSetsListType; + + const CollisionBarListType g_emptyBars; + const CollisionBarSetListType g_emptySets; ///---------------------------------------------------------------------- ///---------------------------------------------------------------------- @@ -46,8 +51,18 @@ namespace cloonel { return itm.second; } } - assert(false); - return g_empty; + return g_emptyBars; + } + + ///---------------------------------------------------------------------- + ///---------------------------------------------------------------------- + const CollisionBarSetListType& findGroup (const CollisionBarSetsListType& parList, Collider::GroupIDType parID) { + for (const auto& itm : parList) { + if (itm.first == parID) { + return itm.second; + } + } + return g_emptySets; } #if !defined(NDEBUG) @@ -55,19 +70,27 @@ namespace cloonel { ///---------------------------------------------------------------------- bool isGroupRegistered (const CollisionBarGroupListType& parList, Collider::GroupIDType parID) { const CollisionBarListType& result = findGroup(parList, parID); - return &g_empty != &result; + return &g_emptyBars != &result; + } + + ///---------------------------------------------------------------------- + ///---------------------------------------------------------------------- + bool isGroupRegistered (const CollisionBarSetsListType& parList, Collider::GroupIDType parID) { + const CollisionBarSetListType& result = findGroup(parList, parID); + return &g_emptySets != &result; } #endif ///---------------------------------------------------------------------- ///---------------------------------------------------------------------- - CollisionBarListType& findOrAddGroup (CollisionBarGroupListType& parList, Collider::GroupIDType parID) { + template + typename L::value_type::second_type& findOrAddGroup (L& parList, Collider::GroupIDType parID) { for (auto& itm : parList) { if (itm.first == parID) { return itm.second; } } - parList.push_back(std::make_pair(parID, CollisionBarListType())); + parList.push_back(std::make_pair(parID, typename L::value_type::second_type())); assert(parList.back().first == parID); return parList.back().second; } @@ -127,11 +150,36 @@ namespace cloonel { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- void Collider::RunCollisionTests (float parDeltaT) const { + CollisionBarGroupListType collectedGroups; + //For each CollisionBarSet list+ID + for (const auto& set : m_collisionBarSets) { + //Get or make a list for the currend ID + CollisionBarListType& newList = findOrAddGroup(collectedGroups, set.first); + //For each CollisionBarSet with the current ID + for (auto setObject : set.second) { +#if !defined(NDEBUG) + const size_t oldListSize = newList.size(); + const CollisionBar* const lastCollisionBar = (oldListSize == 0 ? nullptr : newList.back()); +#endif + //Get the collision bars in the current list + setObject->CopyBars(newList); + + //Make sure the CollisionBarSet didn't tamper with elements already in the list + assert(oldListSize <= newList.size()); + assert(0 == oldListSize or newList[oldListSize - 1] == lastCollisionBar); + } + } + for (const auto& relationship : m_relationships) { const CollisionBarListType& group1 = findGroup(m_collisionBars, relationship.first); const CollisionBarListType& group2 = (relationship.first == relationship.second ? group1 : findGroup(m_collisionBars, relationship.second)); + const CollisionBarListType& group1a = findGroup(collectedGroups, relationship.first); + const CollisionBarListType& group2a = (relationship.first == relationship.second ? group1a : findGroup(collectedGroups, relationship.second)); collide(parDeltaT, group1, group2); + collide(parDeltaT, group1, group2a); + collide(parDeltaT, group1a, group2); + collide(parDeltaT, group1a, group2a); } } @@ -143,8 +191,8 @@ namespace cloonel { #endif assert(m_relationships.end() == std::find(m_relationships.begin(), m_relationships.end(), std::make_pair(parGroup1, parGroup2))); assert(m_relationships.end() == std::find(m_relationships.begin(), m_relationships.end(), std::make_pair(parGroup2, parGroup1))); - assert(isGroupRegistered(m_collisionBars, parGroup1)); - assert(isGroupRegistered(m_collisionBars, parGroup2)); + assert(isGroupRegistered(m_collisionBars, parGroup1) or isGroupRegistered(m_collisionBarSets, parGroup1)); + assert(isGroupRegistered(m_collisionBars, parGroup2) or isGroupRegistered(m_collisionBarSets, parGroup2)); m_relationships.push_back(std::make_pair(parGroup1, parGroup2)); } @@ -175,6 +223,29 @@ namespace cloonel { void Collider::Reset() noexcept { m_relationships.clear(); m_collisionBars.clear(); + m_collisionBarSets.clear(); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void Collider::RegisterBarSet (GroupIDType parGroup, const CollisionBarSet* parSet) { +#if defined(VERBOSE_COLLIDER) + std::cout << "Collider: Registering bar set " << parSet << " in group " << parGroup << "\n"; +#endif + CollisionBarSetListType& group = findOrAddGroup(m_collisionBarSets, parGroup); + assert(isGroupRegistered(m_collisionBarSets, parGroup)); + assert(parSet); + group.push_back(parSet); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void Collider::UnregisterBarSet (GroupIDType parGroup, const CollisionBarSet* parSet) { + assert(isGroupRegistered(m_collisionBarSets, parGroup)); + CollisionBarSetListType& group = findOrAddGroup(m_collisionBarSets, parGroup); + auto itdele = std::find(group.begin(), group.end(), parSet); + assert(itdele != group.end()); + group.erase(itdele); } } //namespace cloonel diff --git a/src/collider.hpp b/src/collider.hpp index 2414efa..577d877 100644 --- a/src/collider.hpp +++ b/src/collider.hpp @@ -27,6 +27,7 @@ namespace cloonel { class HorzCollisionBar; + class CollisionBarSet; typedef HorzCollisionBar CollisionBar; @@ -41,14 +42,18 @@ namespace cloonel { void TieGroups ( GroupIDType parGroup1, GroupIDType parGroup2 ); void RegisterBar ( GroupIDType parGroup, const CollisionBar* parBar ); void UnregisterBar ( GroupIDType parGroup, const CollisionBar* parBar ); + void RegisterBarSet ( GroupIDType parGroup, const CollisionBarSet* parSet ); + void UnregisterBarSet ( GroupIDType parGroup, const CollisionBarSet* parSet ); void Reset ( void ) noexcept; private: typedef std::vector>> CollisionBarGroupListType; + typedef std::vector>> CollisionBarSetsListType; typedef std::vector> RelationshipListType; RelationshipListType m_relationships; CollisionBarGroupListType m_collisionBars; + CollisionBarSetsListType m_collisionBarSets; }; } //namespace cloonel diff --git a/src/collisionbarset.hpp b/src/collisionbarset.hpp new file mode 100644 index 0000000..563d6ed --- /dev/null +++ b/src/collisionbarset.hpp @@ -0,0 +1,35 @@ +/* + Copyright 2014 Michele "King_DuckZ" Santullo + + This file is part of CloonelJump. + + CloonelJump is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CloonelJump is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CloonelJump. If not, see . + +*/ + +#ifndef id0632E9698575456ABDB19F9BB0AFE492 +#define id0632E9698575456ABDB19F9BB0AFE492 + +#include + +namespace cloonel { + class HorzCollisionBar; + + class CollisionBarSet { + public: + virtual void CopyBars ( std::vector& parOut ) const = 0; + }; +} //namespace cloonel + +#endif diff --git a/src/drawableset.hpp b/src/drawableset.hpp new file mode 100644 index 0000000..975169e --- /dev/null +++ b/src/drawableset.hpp @@ -0,0 +1,35 @@ +/* + Copyright 2014 Michele "King_DuckZ" Santullo + + This file is part of CloonelJump. + + CloonelJump is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CloonelJump is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CloonelJump. If not, see . + +*/ + +#ifndef idBFBF4D5B34DD49E68B89249AA1D8FCE4 +#define idBFBF4D5B34DD49E68B89249AA1D8FCE4 + +#include + +namespace cloonel { + class Drawable; + + class DrawableSet { + public: + virtual void CopyDrawables ( std::vector& parOut ) const = 0; + }; +} //namespace cloonel + +#endif diff --git a/src/gameplayscene.cpp b/src/gameplayscene.cpp index 0e03736..2b48d56 100644 --- a/src/gameplayscene.cpp +++ b/src/gameplayscene.cpp @@ -20,6 +20,7 @@ #include "gameplayscene.hpp" #include "mover.hpp" #include "drawable.hpp" +#include "drawableset.hpp" #include "placeable.hpp" #include @@ -53,8 +54,13 @@ namespace cloonel { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- void GameplayScene::OnRender() { - for (auto itDrawable : m_drawables) { - itDrawable->Draw(); + std::vector drawables; + for (auto drawableSet : m_drawableSets) { + drawables.clear(); + drawableSet->CopyDrawables(drawables); + for (auto drawable : drawables) { + drawable->Draw(); + } } } diff --git a/src/gameplayscene.hpp b/src/gameplayscene.hpp index 0c7a26b..b4a7d38 100644 --- a/src/gameplayscene.hpp +++ b/src/gameplayscene.hpp @@ -27,7 +27,7 @@ namespace cloonel { class Mover; - class Drawable; + class DrawableSet; class GameplayScene : public GameBase { public: @@ -35,7 +35,7 @@ namespace cloonel { virtual ~GameplayScene ( void ) noexcept = default; void AddMover ( Mover* parMover ) { assert(parMover); m_movers.push_back(parMover); } - void AddDrawable ( const Drawable* parDrawable ) { assert(parDrawable); m_drawables.push_back(parDrawable); } + void AddDrawableSet ( const DrawableSet* parSet ) { assert(parSet); m_drawableSets.push_back(parSet); } virtual void Destroy ( void ) noexcept; @@ -49,7 +49,7 @@ namespace cloonel { Collider m_collider; std::vector m_movers; - std::vector m_drawables; + std::vector m_drawableSets; }; } //namespace cloonel diff --git a/src/gameplaysceneclassic.cpp b/src/gameplaysceneclassic.cpp index 93f48b3..54fd89a 100644 --- a/src/gameplaysceneclassic.cpp +++ b/src/gameplaysceneclassic.cpp @@ -96,11 +96,8 @@ namespace cloonel { { auto regPlayerCollision(std::bind(&Collider::RegisterBar, &collider, CollisionID_Player, std::placeholders::_1)); player->RegisterForCollision(regPlayerCollision); - - auto regPlatfCollision(std::bind(&Collider::RegisterBar, &collider, CollisionID_Platforms, std::placeholders::_1)); - auto unregPlatfCollision(std::bind(&Collider::UnregisterBar, &collider, CollisionID_Platforms, std::placeholders::_1)); - platforms->RegisterForCollision(regPlatfCollision, unregPlatfCollision); } + platforms->RegisterForCollision(collider, CollisionID_Platforms); player->SetOnBounceCallback(std::bind(&OnCharacterBounce, moverSine.get(), std::placeholders::_1, std::placeholders::_2)); @@ -113,10 +110,10 @@ namespace cloonel { AddMover(m_moverSine.get()); AddMover(m_moverLeftRight.get()); - AddDrawable(m_wallpaper.get()); + AddDrawableSet(m_wallpaper.get()); AddMover(m_moverWorld.get()); - m_platforms->AddDrawables(); - AddDrawable(m_player.get()); + AddDrawableSet(m_platforms->GetDrawableSet()); + AddDrawableSet(m_player.get()); const float jumpPower = halfRefHeight * 0.71f; m_moverSine->SetPower(jumpPower); diff --git a/src/platform.hpp b/src/platform.hpp index a9b8619..fc52d5d 100644 --- a/src/platform.hpp +++ b/src/platform.hpp @@ -41,6 +41,7 @@ namespace cloonel { float2 TopLeft ( void ) const { return GetPos(); } float2 BottomRight ( void ) const { return TopLeft() + m_size; } + const HorzCollisionBar* TopCollisionBar ( void ) const { return m_collisionTop.get(); } void RegisterForCollision ( ColliderRegisterFunc parReg ); diff --git a/src/platformset.cpp b/src/platformset.cpp new file mode 100644 index 0000000..76887d1 --- /dev/null +++ b/src/platformset.cpp @@ -0,0 +1,100 @@ +/* + Copyright 2014 Michele "King_DuckZ" Santullo + + This file is part of CloonelJump. + + CloonelJump is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CloonelJump is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CloonelJump. If not, see . + +*/ + +#include "platformset.hpp" +#include "platform.hpp" +#include "CloonelJumpConfig.h" +#include +#include +#include +#include +#include +#include + +namespace cloonel { + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + PlatformSet::PlatformSet (SDLMain* parSdl) : + m_platforms(MAX_PLATFORMS_ON_SCREEN), + m_sdlmain(parSdl) + { + assert(m_sdlmain); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + PlatformSet::~PlatformSet() noexcept { + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSet::Add (const float2& parPos, const float2& parSize, Texture* parTexture) { + m_platforms.push_back(Platform(m_sdlmain, parPos, parTexture, parSize)); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSet::CopyBars (std::vector& parOut) const { + parOut.reserve(parOut.size() + m_platforms.size()); + for (auto& platf : m_platforms) { + parOut.push_back(platf.TopCollisionBar()); + } + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSet::CopyDrawables (std::vector& parOut) const { + parOut.reserve(parOut.size() + m_platforms.size()); + for (auto& platf : m_platforms) { + parOut.push_back(&platf); + } + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + size_t PlatformSet::CountFreePlatforms() const { + size_t freePlatforms = 0; + for (const auto& platf : m_platforms) { + if (platf.GetPos().y() < 0.0f) + ++freePlatforms; + else + break; + } + return MAX_PLATFORMS_ON_SCREEN - m_platforms.size() + freePlatforms; + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSet::clear() noexcept { + m_platforms.clear(); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSet::SendBeginMovement() noexcept { + std::for_each(m_platforms.begin(), m_platforms.end(), std::bind(&Platform::BeginMovement, std::placeholders::_1)); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSet::SendAddOffset (const float2& parOffset) noexcept { + std::for_each(m_platforms.begin(), m_platforms.end(), std::bind(&Platform::AddOffset, std::placeholders::_1, parOffset)); + } +} //namespace cloonel diff --git a/src/platformset.hpp b/src/platformset.hpp new file mode 100644 index 0000000..ca13553 --- /dev/null +++ b/src/platformset.hpp @@ -0,0 +1,62 @@ +/* + Copyright 2014 Michele "King_DuckZ" Santullo + + This file is part of CloonelJump. + + CloonelJump is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CloonelJump is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CloonelJump. If not, see . + +*/ + +#ifndef idB56C30EE09454EA2864FA6D1607131D5 +#define idB56C30EE09454EA2864FA6D1607131D5 + +#include "collisionbarset.hpp" +#include "drawableset.hpp" +#include "movers/mover.hpp" +#include +#include + +namespace cloonel { + class SDLMain; + class Platform; + class Texture; + + class PlatformSet : public CollisionBarSet, public DrawableSet { + public: + PlatformSet ( SDLMain* parSdl ); + PlatformSet ( const PlatformSet& ) = delete; + ~PlatformSet ( void ) noexcept; + PlatformSet& operator= ( const PlatformSet& ) = delete; + + void Add ( const float2& parPos, const float2& parSize, Texture* parTexture ); + size_t CountFreePlatforms ( void ) const; + void SendBeginMovement ( void ) noexcept; + void SendAddOffset ( const float2& parOffset ) noexcept; + + size_t size ( void ) const { return m_platforms.size(); } + bool empty ( void ) const { return m_platforms.empty(); } + void clear ( void ) noexcept; + const Platform& back ( void ) { return m_platforms.back(); } + + private: + //Overrides + virtual void CopyBars ( std::vector& parOut ) const; + virtual void CopyDrawables ( std::vector& parOut ) const; + + boost::circular_buffer m_platforms; + SDLMain* const m_sdlmain; + }; +} //namespace cloonel + +#endif diff --git a/src/platformsystem.cpp b/src/platformsystem.cpp index c76b15d..576ce42 100644 --- a/src/platformsystem.cpp +++ b/src/platformsystem.cpp @@ -24,13 +24,14 @@ #include "gameplayscene.hpp" #include "mover.hpp" #include "collider.hpp" +#include "platformset.hpp" #include #include #include #include #include -#include #include +#include namespace cloonel { namespace { @@ -60,42 +61,13 @@ namespace cloonel { } } //unnamed namespace - struct PlatformInfo { - PlatformInfo ( void ) : - platform(nullptr), - ticket(0) - { - } - PlatformInfo ( const PlatformInfo& ) = delete; - PlatformInfo ( Platform&& parPlatf ) noexcept : - platform(new Platform(std::move(parPlatf))), - ticket(0) - { - } - PlatformInfo ( PlatformInfo&& parOther ) noexcept : - platform(std::move(parOther.platform)), - ticket(parOther.ticket) - { - } - ~PlatformInfo ( void ) noexcept = default; - PlatformInfo& operator= ( const PlatformInfo& ) = delete; - PlatformInfo& operator= ( PlatformInfo&& parOther ) { - platform.swap(parOther.platform); - std::swap(ticket, parOther.ticket); - return *this; - } - - std::unique_ptr platform; - Mover::PlaceableTicketType ticket; - }; - struct PlatformSystem::LocalData : public boost::noncopyable { LocalData ( const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance ); ~LocalData ( void ) noexcept = default; - boost::circular_buffer platforms; + PlatformSet platforms; Texture texture; - SDLMain* const sdlmain; + std::list> registeredTo; GameplayScene* const scene; const float maxDistance; }; @@ -103,9 +75,8 @@ namespace cloonel { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- PlatformSystem::LocalData::LocalData (const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance) : - platforms(MAX_PLATFORMS_ON_SCREEN), + platforms(parSDLMain), texture(parTexturePath, parSDLMain, false), - sdlmain(parSDLMain), scene(parScene), maxDistance(parMaxDistance) { @@ -129,26 +100,23 @@ namespace cloonel { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- void PlatformSystem::SpawnPlatforms() { - const size_t totalPlatf = MAX_PLATFORMS_ON_SCREEN; const float2 platfWH(static_cast(g_platfWidth), static_cast(g_platfHeight)); - size_t freePlatforms = 0; - for (size_t z = 0; z < m_localdata->platforms.size(); ++z) { - if (m_localdata->platforms[z].platform->GetPos().y() < 0.0f) - ++freePlatforms; - else - break; - } - freePlatforms = totalPlatf - m_localdata->platforms.size() + freePlatforms; - - float prevPlatf = (m_localdata->platforms.empty() ? 0.0f : m_localdata->platforms.back().platform->GetPos().y() + GetPos().y()); + size_t freePlatforms = m_localdata->platforms.CountFreePlatforms(); + float prevPlatf = (m_localdata->platforms.empty() ? 0.0f : m_localdata->platforms.back().GetPos().y() + GetPos().y()); + //FIXME: platform's height shouldn't grow unbounded, they should have the + //screen-relative position only. Change the movers as appropriate. + //std::cout << "Top platform is at index " << m_localdata->platforms.size() - 1 << ", prevPlatf = " << prevPlatf << " "; + //if (not m_localdata->platforms.empty()) { + //std::cout << "top pos is " << m_localdata->platforms.back().platform->GetPos() << ", system's pos is " << GetPos() << "\n"; + //} while (static_cast(REFERENCE_HEIGHT) - prevPlatf >= m_targetAverage) { assert(freePlatforms > 0); const auto newPos(PositionForNewPlatf(prevPlatf, m_targetAverage, m_localdata->maxDistance, freePlatforms)); --freePlatforms; prevPlatf = newPos.y(); - m_localdata->platforms.push_back(Platform(m_localdata->sdlmain, newPos, &m_localdata->texture, platfWH)); + m_localdata->platforms.Add(newPos, platfWH, &m_localdata->texture); } } @@ -162,41 +130,45 @@ namespace cloonel { this->SpawnPlatforms(); } - ///-------------------------------------------------------------------------- - ///-------------------------------------------------------------------------- - void PlatformSystem::RegisterForCollision (ColliderRegisterFunc parReg, ColliderUnregisterFunc parUnreg) { - m_registerToCollider = parReg; - m_unregisterFromCollider = parUnreg; - - for (auto& platf : m_localdata->platforms) { - platf.platform->RegisterForCollision(m_registerToCollider); - } - } - ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- void PlatformSystem::Destroy() noexcept { m_localdata->texture.Destroy(); + for (const auto& unregPair : m_localdata->registeredTo) { + unregPair.second->UnregisterBarSet(unregPair.first, &m_localdata->platforms); + } + m_localdata->registeredTo.clear(); m_localdata->platforms.clear(); } ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- - void PlatformSystem::AddDrawables() { - for (size_t z = 0; z < m_localdata->platforms.size(); ++z) { - PlatformInfo& newPlatf = m_localdata->platforms[z]; - m_localdata->scene->AddDrawable(newPlatf.platform.get()); - newPlatf.ticket = Mover::NullTicket; - } + void PlatformSystem::BeginMovement() { + m_localdata->platforms.SendBeginMovement(); } ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- - void PlatformSystem::OnRegister (Mover& parMover, Mover::PlaceableTicketType parTicket) { - for (size_t z = 0; z < m_localdata->platforms.size(); ++z) { - assert(m_localdata->platforms[z].platform != nullptr); - m_localdata->platforms[z].ticket = parMover.RegisterPlaceable(m_localdata->platforms[z].platform.get(), parTicket); - } + void PlatformSystem::AddOffset (const float2& parOffset) noexcept { + m_localdata->platforms.SendAddOffset(parOffset); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSystem::SetAbsolutePosition (const float2&) noexcept { + assert(false); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void PlatformSystem::RegisterForCollision (Collider& parCollider, Collider::GroupIDType parGroupID) { + parCollider.RegisterBarSet(parGroupID, &m_localdata->platforms); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + const DrawableSet* PlatformSystem::GetDrawableSet() const { + return &m_localdata->platforms; } } //namespace cloonel diff --git a/src/platformsystem.hpp b/src/platformsystem.hpp index 5002812..6e5e620 100644 --- a/src/platformsystem.hpp +++ b/src/platformsystem.hpp @@ -21,12 +21,13 @@ #include "placeable.hpp" #include "collidertypedef.hpp" +#include "collider.hpp" #include namespace cloonel { class SDLMain; class GameplayScene; - class Collider; + class DrawableSet; class PlatformSystem : public Placeable { public: @@ -34,24 +35,24 @@ namespace cloonel { PlatformSystem ( const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance ); PlatformSystem ( const PlatformSystem& ) = delete; PlatformSystem ( PlatformSystem&& parOther ) = delete; - ~PlatformSystem ( void ) noexcept; + virtual ~PlatformSystem ( void ) noexcept; PlatformSystem& operator= ( const PlatformSystem& ) = delete; void Prepare ( void ); - void RegisterForCollision ( ColliderRegisterFunc parReg, ColliderUnregisterFunc parUnreg ); - void AddDrawables ( void ); void Destroy ( void ) noexcept; void SpawnPlatforms ( void ); - - //Overrides - virtual void OnRegister ( Mover& parOut, Mover::PlaceableTicketType parTicket ); + void RegisterForCollision ( Collider& parCollider, Collider::GroupIDType parGroupID ); + const DrawableSet* GetDrawableSet ( void ) const; private: struct LocalData; + //Overrides + virtual void BeginMovement ( void ); + virtual void AddOffset ( const float2& parOffset ) noexcept; + virtual void SetAbsolutePosition ( const float2& ) noexcept; + const std::unique_ptr m_localdata; - ColliderRegisterFunc m_registerToCollider; - ColliderUnregisterFunc m_unregisterFromCollider; float m_targetAverage; }; } //namespace cloonel diff --git a/src/tiledwallpaper.hpp b/src/tiledwallpaper.hpp index 4ba4b6d..be2b9e5 100644 --- a/src/tiledwallpaper.hpp +++ b/src/tiledwallpaper.hpp @@ -22,20 +22,25 @@ #include "drawable.hpp" #include "sizenotifiable.hpp" +#include "drawableset.hpp" #include +#include namespace cloonel { class Texture; class SDLMain; - class TiledWallpaper : public Drawable { + class TiledWallpaper : public Drawable, public DrawableSet { public: TiledWallpaper ( const std::string&& parPath, SDLMain* parMain ); virtual ~TiledWallpaper ( void ) noexcept; void Reload ( void ); void Destroy ( void ) noexcept; + + //Overrides virtual void Draw ( void ) const; + virtual void CopyDrawables ( std::vector& parOut ) const { parOut.push_back(this); } private: class TileCountNotifiable : public SizeNotifiable {