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.
This commit is contained in:
parent
3c0e460a23
commit
896b368cbe
15 changed files with 393 additions and 99 deletions
|
@ -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}
|
||||
|
|
|
@ -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 <memory>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
||||
class Texture;
|
||||
template <typename T, uint32_t S> class Line;
|
||||
|
||||
class Character : public Placeable, public Drawable {
|
||||
class Character : public Placeable, public Drawable, public DrawableSet {
|
||||
public:
|
||||
typedef std::function<void(const Line<float, 2>&, const float2&)> BounceCallbackType;
|
||||
|
||||
|
@ -54,6 +56,7 @@ namespace cloonel {
|
|||
private:
|
||||
//Overrides
|
||||
virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket );
|
||||
virtual void CopyDrawables ( std::vector<const Drawable*>& parOut ) const { parOut.push_back(this); }
|
||||
|
||||
void OnBounce ( const Line<float, 2>& parCollision, const float2& parDirection );
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "horzcollisionbar.hpp"
|
||||
#include "line.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "collisionbarset.hpp"
|
||||
#include "vectormath.hpp"
|
||||
#include <vector>
|
||||
#include <ciso646>
|
||||
|
@ -36,7 +37,11 @@ namespace cloonel {
|
|||
namespace {
|
||||
typedef std::vector<const CollisionBar*> CollisionBarListType;
|
||||
typedef std::vector<std::pair<Collider::GroupIDType, CollisionBarListType>> CollisionBarGroupListType;
|
||||
const CollisionBarListType g_empty;
|
||||
typedef std::vector<const CollisionBarSet*> CollisionBarSetListType;
|
||||
typedef std::vector<std::pair<Collider::GroupIDType, CollisionBarSetListType>> 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>
|
||||
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
|
||||
|
||||
|
|
|
@ -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<std::pair<GroupIDType, std::vector<const CollisionBar*>>> CollisionBarGroupListType;
|
||||
typedef std::vector<std::pair<GroupIDType, std::vector<const CollisionBarSet*>>> CollisionBarSetsListType;
|
||||
typedef std::vector<std::pair<GroupIDType, GroupIDType>> RelationshipListType;
|
||||
|
||||
RelationshipListType m_relationships;
|
||||
CollisionBarGroupListType m_collisionBars;
|
||||
CollisionBarSetsListType m_collisionBarSets;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
|
|
35
src/collisionbarset.hpp
Normal file
35
src/collisionbarset.hpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef id0632E9698575456ABDB19F9BB0AFE492
|
||||
#define id0632E9698575456ABDB19F9BB0AFE492
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cloonel {
|
||||
class HorzCollisionBar;
|
||||
|
||||
class CollisionBarSet {
|
||||
public:
|
||||
virtual void CopyBars ( std::vector<const HorzCollisionBar*>& parOut ) const = 0;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
35
src/drawableset.hpp
Normal file
35
src/drawableset.hpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef idBFBF4D5B34DD49E68B89249AA1D8FCE4
|
||||
#define idBFBF4D5B34DD49E68B89249AA1D8FCE4
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cloonel {
|
||||
class Drawable;
|
||||
|
||||
class DrawableSet {
|
||||
public:
|
||||
virtual void CopyDrawables ( std::vector<const Drawable*>& parOut ) const = 0;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
|
@ -20,6 +20,7 @@
|
|||
#include "gameplayscene.hpp"
|
||||
#include "mover.hpp"
|
||||
#include "drawable.hpp"
|
||||
#include "drawableset.hpp"
|
||||
#include "placeable.hpp"
|
||||
#include <unordered_set>
|
||||
|
||||
|
@ -53,8 +54,13 @@ namespace cloonel {
|
|||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void GameplayScene::OnRender() {
|
||||
for (auto itDrawable : m_drawables) {
|
||||
itDrawable->Draw();
|
||||
std::vector<const Drawable*> drawables;
|
||||
for (auto drawableSet : m_drawableSets) {
|
||||
drawables.clear();
|
||||
drawableSet->CopyDrawables(drawables);
|
||||
for (auto drawable : drawables) {
|
||||
drawable->Draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Mover*> m_movers;
|
||||
std::vector<const Drawable*> m_drawables;
|
||||
std::vector<const DrawableSet*> m_drawableSets;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
100
src/platformset.cpp
Normal file
100
src/platformset.cpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "platformset.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "CloonelJumpConfig.h"
|
||||
#include <ciso646>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
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<const HorzCollisionBar*>& parOut) const {
|
||||
parOut.reserve(parOut.size() + m_platforms.size());
|
||||
for (auto& platf : m_platforms) {
|
||||
parOut.push_back(platf.TopCollisionBar());
|
||||
}
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void PlatformSet::CopyDrawables (std::vector<const Drawable*>& 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
|
62
src/platformset.hpp
Normal file
62
src/platformset.hpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef idB56C30EE09454EA2864FA6D1607131D5
|
||||
#define idB56C30EE09454EA2864FA6D1607131D5
|
||||
|
||||
#include "collisionbarset.hpp"
|
||||
#include "drawableset.hpp"
|
||||
#include "movers/mover.hpp"
|
||||
#include <list>
|
||||
#include <boost/circular_buffer.hpp>
|
||||
|
||||
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<const HorzCollisionBar*>& parOut ) const;
|
||||
virtual void CopyDrawables ( std::vector<const Drawable*>& parOut ) const;
|
||||
|
||||
boost::circular_buffer<Platform> m_platforms;
|
||||
SDLMain* const m_sdlmain;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
|
@ -24,13 +24,14 @@
|
|||
#include "gameplayscene.hpp"
|
||||
#include "mover.hpp"
|
||||
#include "collider.hpp"
|
||||
#include "platformset.hpp"
|
||||
#include <ciso646>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/algorithm/clamp.hpp>
|
||||
#include <list>
|
||||
|
||||
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> 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<PlatformInfo> platforms;
|
||||
PlatformSet platforms;
|
||||
Texture texture;
|
||||
SDLMain* const sdlmain;
|
||||
std::list<std::pair<Collider::GroupIDType, Collider*>> 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<float>(g_platfWidth), static_cast<float>(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<float>(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
|
||||
|
|
|
@ -21,12 +21,13 @@
|
|||
|
||||
#include "placeable.hpp"
|
||||
#include "collidertypedef.hpp"
|
||||
#include "collider.hpp"
|
||||
#include <memory>
|
||||
|
||||
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<LocalData> m_localdata;
|
||||
ColliderRegisterFunc m_registerToCollider;
|
||||
ColliderUnregisterFunc m_unregisterFromCollider;
|
||||
float m_targetAverage;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
|
|
@ -22,20 +22,25 @@
|
|||
|
||||
#include "drawable.hpp"
|
||||
#include "sizenotifiable.hpp"
|
||||
#include "drawableset.hpp"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
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<const Drawable*>& parOut ) const { parOut.push_back(this); }
|
||||
|
||||
private:
|
||||
class TileCountNotifiable : public SizeNotifiable<regbehaviours::AutoRegister> {
|
||||
|
|
Loading…
Reference in a new issue