Merge branch 'dev'
Conflicts: CMakeLists.txt
This commit is contained in:
commit
dff58a98ef
35 changed files with 969 additions and 154 deletions
|
@ -6,6 +6,15 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -Wall -Wextra -pe
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -Wall -Wextra -pedantic -Wconversion")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -Wall -Wextra -pedantic -Wconversion")
|
||||||
|
|
||||||
option(WITH_BUILTIN_PHYSFS "Force using the version of PhysFS accompanying the code even if a system library is available" OFF)
|
option(WITH_BUILTIN_PHYSFS "Force using the version of PhysFS accompanying the code even if a system library is available" OFF)
|
||||||
|
option(FORCE_OPENGLES "Try to chose the openGL ES renderer if available. Enable this on Raspberry Pi" OFF)
|
||||||
|
option(RASPBERRY_PI "Compile for Raspberry Pi" OFF)
|
||||||
|
|
||||||
|
if (FORCE_OPENGLES OR RASPBERRY_PI)
|
||||||
|
add_definitions(-DFORCE_OPENGLES)
|
||||||
|
if (RASPBERRY_PI)
|
||||||
|
add_definitions(-DRASPBERRY_PI)
|
||||||
|
endif(RASPBERRY_PI)
|
||||||
|
endif (FORCE_OPENGLES OR RASPBERRY_PI)
|
||||||
|
|
||||||
include(FindPkgConfig)
|
include(FindPkgConfig)
|
||||||
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
|
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
|
||||||
|
@ -26,9 +35,22 @@ endif(PHYSFS_FOUND)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
${PNG_DEFINITIONS}
|
${PNG_DEFINITIONS}
|
||||||
-DWITH_VERBOSE_OBS_MANAGER
|
# -DWITH_VERBOSE_OBS_MANAGER
|
||||||
|
-DWITH_VERBOSE_COLLIDER
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (RASPBERRY_PI)
|
||||||
|
message(STATUS "Will build for Raspberry Pi")
|
||||||
|
include_directories(SYSTEM
|
||||||
|
/opt/vc/include
|
||||||
|
/opt/vc/include/interface/vcos/pthreads
|
||||||
|
/opt/vc/include/interface/vmcs_host/linux
|
||||||
|
)
|
||||||
|
link_directories(
|
||||||
|
/opt/vc/lib
|
||||||
|
)
|
||||||
|
endif (RASPBERRY_PI)
|
||||||
|
|
||||||
include_directories(SYSTEM
|
include_directories(SYSTEM
|
||||||
${SDL2_INCLUDE_DIR}
|
${SDL2_INCLUDE_DIR}
|
||||||
${PNG_INCLUDE_DIRS}
|
${PNG_INCLUDE_DIRS}
|
||||||
|
@ -76,10 +98,11 @@ add_executable(${PROJECT_NAME}
|
||||||
src/horzcollisionbar.cpp
|
src/horzcollisionbar.cpp
|
||||||
src/platform.cpp
|
src/platform.cpp
|
||||||
src/vectormath.cpp
|
src/vectormath.cpp
|
||||||
src/platformsystem.cpp
|
src/platformspawner.cpp
|
||||||
src/movers/moverworld.cpp
|
src/movers/moverworld.cpp
|
||||||
src/line.cpp
|
src/line.cpp
|
||||||
src/collider.cpp
|
src/collider.cpp
|
||||||
|
src/platformset.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
@ -87,3 +110,9 @@ target_link_libraries(${PROJECT_NAME}
|
||||||
${PHYSFS_LIBRARY}
|
${PHYSFS_LIBRARY}
|
||||||
${PNG_LIBRARIES}
|
${PNG_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (RASPBERRY_PI)
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
bcm_host
|
||||||
|
)
|
||||||
|
endif(RASPBERRY_PI)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#define id5FC1D6EEF9DF41E790068FBC6753035F
|
#define id5FC1D6EEF9DF41E790068FBC6753035F
|
||||||
|
|
||||||
#define GameName "@PROJECT_NAME@"
|
#define GameName "@PROJECT_NAME@"
|
||||||
#define GameVersionMinor 11
|
#define GameVersionMinor 12
|
||||||
#define GameVersionMajor 0
|
#define GameVersionMajor 0
|
||||||
|
|
||||||
#define REFERENCE_WIDTH 480
|
#define REFERENCE_WIDTH 480
|
||||||
|
@ -32,6 +32,8 @@
|
||||||
#define MAX_PLATFORMS_ON_SCREEN 24
|
#define MAX_PLATFORMS_ON_SCREEN 24
|
||||||
#define REFERENCE_PLATFORM_WIDTH 104
|
#define REFERENCE_PLATFORM_WIDTH 104
|
||||||
#define REFERENCE_PLATFORM_HEIGHT 25
|
#define REFERENCE_PLATFORM_HEIGHT 25
|
||||||
|
#define REFERENCE_CHARA_WIDTH 55
|
||||||
|
#define REFERENCE_CHARA_HEIGHT 70
|
||||||
|
|
||||||
/* TODO: make this path relative */
|
/* TODO: make this path relative */
|
||||||
#define GAME_BASE_PATH "@CMAKE_SOURCE_DIR@"
|
#define GAME_BASE_PATH "@CMAKE_SOURCE_DIR@"
|
||||||
|
|
|
@ -20,9 +20,16 @@
|
||||||
#include "character.hpp"
|
#include "character.hpp"
|
||||||
#include "sdlmain.hpp"
|
#include "sdlmain.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
|
#include "collider.hpp"
|
||||||
|
#include "line.hpp"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
|
namespace {
|
||||||
|
void DoNothing (const Line<float, 2>&, const float2&) {
|
||||||
|
}
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
Character::Character (const std::string& parPath, SDLMain* parMain, float2 parSize) :
|
Character::Character (const std::string& parPath, SDLMain* parMain, float2 parSize) :
|
||||||
|
@ -30,9 +37,11 @@ namespace cloonel {
|
||||||
Drawable(parSize),
|
Drawable(parSize),
|
||||||
m_bottomBar(float2(0.0f), parSize.x()),
|
m_bottomBar(float2(0.0f), parSize.x()),
|
||||||
m_screenRatio(parMain),
|
m_screenRatio(parMain),
|
||||||
|
m_bounceCallback(&DoNothing),
|
||||||
m_texture(new Texture(parPath, parMain, false))
|
m_texture(new Texture(parPath, parMain, false))
|
||||||
{
|
{
|
||||||
assert(parMain);
|
assert(parMain);
|
||||||
|
m_bottomBar.SetCallback(std::bind(&Character::OnBounce, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
|
@ -42,9 +51,11 @@ namespace cloonel {
|
||||||
Drawable(parSize),
|
Drawable(parSize),
|
||||||
m_bottomBar(float2(0.0f), parSize.x()),
|
m_bottomBar(float2(0.0f), parSize.x()),
|
||||||
m_screenRatio(parMain),
|
m_screenRatio(parMain),
|
||||||
|
m_bounceCallback(&DoNothing),
|
||||||
m_texture(new Texture(parPath, parMain, false))
|
m_texture(new Texture(parPath, parMain, false))
|
||||||
{
|
{
|
||||||
assert(parMain);
|
assert(parMain);
|
||||||
|
m_bottomBar.SetCallback(std::bind(&Character::OnBounce, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
|
@ -52,6 +63,12 @@ namespace cloonel {
|
||||||
Character::~Character() noexcept {
|
Character::~Character() noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
void Character::RegisterForCollision (ColliderRegisterFunc parRegisterCollision) {
|
||||||
|
parRegisterCollision(&m_bottomBar);
|
||||||
|
}
|
||||||
|
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
void Character::Prepare() {
|
void Character::Prepare() {
|
||||||
|
@ -72,4 +89,27 @@ namespace cloonel {
|
||||||
void Character::Draw() const {
|
void Character::Draw() const {
|
||||||
m_texture->Render(GetPos(), WidthHeight(), m_screenRatio.Ratio(), true);
|
m_texture->Render(GetPos(), WidthHeight(), m_screenRatio.Ratio(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
void Character::OnRegister (Mover& parMover, Mover::PlaceableTicketType parParentTicket) {
|
||||||
|
parMover.RegisterPlaceable(&m_bottomBar, parParentTicket);
|
||||||
|
}
|
||||||
|
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
void Character::SetOnBounceCallback (BounceCallbackType parCallb) {
|
||||||
|
m_bounceCallback = parCallb;
|
||||||
|
}
|
||||||
|
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
///-------------------------------------------------------------------------
|
||||||
|
void Character::OnBounce (const Line<float, 2>& parCollision, const float2& parDirection) {
|
||||||
|
if (parDirection.y() < 0.0f) {
|
||||||
|
const float2 newPos(GetPos().x(), parCollision.Start().y());
|
||||||
|
this->SetAbsolutePosition(newPos);
|
||||||
|
m_bottomBar.SetAbsolutePosition(newPos);
|
||||||
|
m_bounceCallback(parCollision, parDirection);
|
||||||
|
}
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -22,29 +22,47 @@
|
||||||
|
|
||||||
#include "placeable.hpp"
|
#include "placeable.hpp"
|
||||||
#include "drawable.hpp"
|
#include "drawable.hpp"
|
||||||
|
#include "drawableset.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "sizenotifiable.hpp"
|
#include "sizenotifiable.hpp"
|
||||||
#include "horzcollisionbar.hpp"
|
#include "horzcollisionbar.hpp"
|
||||||
|
#include "collidertypedef.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class SDLMain;
|
class SDLMain;
|
||||||
class Texture;
|
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:
|
public:
|
||||||
|
typedef std::function<void(const Line<float, 2>&, const float2&)> BounceCallbackType;
|
||||||
|
|
||||||
Character ( const std::string& parPath, SDLMain* parMain, float2 parSize );
|
Character ( const std::string& parPath, SDLMain* parMain, float2 parSize );
|
||||||
Character ( const std::string&& parPath, SDLMain* parMai, float2 parSize );
|
Character ( const std::string&& parPath, SDLMain* parMain, float2 parSize );
|
||||||
|
Character ( const Character& ) = delete;
|
||||||
virtual ~Character ( void ) noexcept;
|
virtual ~Character ( void ) noexcept;
|
||||||
|
|
||||||
void Prepare ( void );
|
void Prepare ( void );
|
||||||
void Destroy ( void ) noexcept;
|
void Destroy ( void ) noexcept;
|
||||||
virtual void Draw ( void ) const;
|
virtual void Draw ( void ) const;
|
||||||
|
void RegisterForCollision ( ColliderRegisterFunc parRegisterCollision );
|
||||||
|
void SetOnBounceCallback ( BounceCallbackType parCallb );
|
||||||
|
|
||||||
private:
|
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 );
|
||||||
|
|
||||||
HorzCollisionBar m_bottomBar;
|
HorzCollisionBar m_bottomBar;
|
||||||
SizeNotifiable<regbehaviours::AutoRegister> m_screenRatio;
|
SizeNotifiable<regbehaviours::AutoRegister> m_screenRatio;
|
||||||
|
BounceCallbackType m_bounceCallback;
|
||||||
const std::unique_ptr<Texture> m_texture;
|
const std::unique_ptr<Texture> m_texture;
|
||||||
};
|
};
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
203
src/collider.cpp
203
src/collider.cpp
|
@ -18,6 +18,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "collider.hpp"
|
#include "collider.hpp"
|
||||||
|
#include "horzcollisionbar.hpp"
|
||||||
|
#include "line.hpp"
|
||||||
|
#include "vector.hpp"
|
||||||
|
#include "collisionbarset.hpp"
|
||||||
|
#include "vectormath.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -30,6 +35,106 @@
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
namespace {
|
namespace {
|
||||||
|
typedef std::vector<const CollisionBar*> CollisionBarListType;
|
||||||
|
typedef std::vector<std::pair<Collider::GroupIDType, CollisionBarListType>> CollisionBarGroupListType;
|
||||||
|
typedef std::vector<const CollisionBarSet*> CollisionBarSetListType;
|
||||||
|
typedef std::vector<std::pair<Collider::GroupIDType, CollisionBarSetListType>> CollisionBarSetsListType;
|
||||||
|
|
||||||
|
const CollisionBarListType g_emptyBars;
|
||||||
|
const CollisionBarSetListType g_emptySets;
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
const CollisionBarListType& findGroup (const CollisionBarGroupListType& parList, Collider::GroupIDType parID) {
|
||||||
|
for (const auto& itm : parList) {
|
||||||
|
if (itm.first == parID) {
|
||||||
|
return itm.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
bool isGroupRegistered (const CollisionBarGroupListType& parList, Collider::GroupIDType parID) {
|
||||||
|
const CollisionBarListType& result = findGroup(parList, parID);
|
||||||
|
return &g_emptyBars != &result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
bool isGroupRegistered (const CollisionBarSetsListType& parList, Collider::GroupIDType parID) {
|
||||||
|
const CollisionBarSetListType& result = findGroup(parList, parID);
|
||||||
|
return &g_emptySets != &result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
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, typename L::value_type::second_type()));
|
||||||
|
assert(parList.back().first == parID);
|
||||||
|
return parList.back().second;
|
||||||
|
}
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
void collide (float parDeltaT, const CollisionBarListType& parGroup1, const CollisionBarListType& parGroup2) {
|
||||||
|
Line<float, 2> overlap;
|
||||||
|
for (const auto& bar1 : parGroup1) {
|
||||||
|
assert(bar1);
|
||||||
|
for (const auto& bar2 : parGroup2) {
|
||||||
|
assert(bar2);
|
||||||
|
if (bar2 == bar1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Collide(parDeltaT, *bar1, *bar2, overlap)) {
|
||||||
|
#if defined(VERBOSE_COLLIDER)
|
||||||
|
std::cout << "Collider: Collision ";
|
||||||
|
std::cout << "between " << bar1 << " and " << bar2 << "\n";
|
||||||
|
#endif
|
||||||
|
const auto& offs1 = bar1->GetOffset();
|
||||||
|
const auto& offs2 = bar2->GetOffset();
|
||||||
|
float2 dir1, dir2;
|
||||||
|
if (offs1 == float2(0.0f) and offs2 == float2(0.0f)) {
|
||||||
|
dir1 = dir2 = float2(0.0f);
|
||||||
|
}
|
||||||
|
else if (offs1 == float2(0.0f)) {
|
||||||
|
dir2 = normalized(offs2);
|
||||||
|
dir1 = -1.0f * dir2;
|
||||||
|
}
|
||||||
|
else if (offs2 == float2(0.0f)) {
|
||||||
|
dir1 = normalized(offs1);
|
||||||
|
dir2 = -1.0f * dir1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dir1 = normalized(offs1);
|
||||||
|
dir2 = normalized(offs2);
|
||||||
|
}
|
||||||
|
bar1->InvokeCallback(overlap, dir1);
|
||||||
|
bar2->InvokeCallback(overlap, dir2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
@ -44,7 +149,103 @@ namespace cloonel {
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void Collider::RunCollisionTests() {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void Collider::TieGroups (GroupIDType parGroup1, GroupIDType parGroup2) {
|
||||||
|
#if defined(VERBOSE_COLLIDER)
|
||||||
|
std::cout << "Collider: Tying group " << parGroup1 << " to " << parGroup2 << " for collision tests\n";
|
||||||
|
#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) or isGroupRegistered(m_collisionBarSets, parGroup1));
|
||||||
|
assert(isGroupRegistered(m_collisionBars, parGroup2) or isGroupRegistered(m_collisionBarSets, parGroup2));
|
||||||
|
m_relationships.push_back(std::make_pair(parGroup1, parGroup2));
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void Collider::RegisterBar (GroupIDType parGroup, const CollisionBar* parBar) {
|
||||||
|
#if defined(VERBOSE_COLLIDER)
|
||||||
|
std::cout << "Collider: Registering bar " << parBar << " in group " << parGroup << "\n";
|
||||||
|
#endif
|
||||||
|
CollisionBarListType& group = findOrAddGroup(m_collisionBars, parGroup);
|
||||||
|
assert(isGroupRegistered(m_collisionBars, parGroup));
|
||||||
|
assert(parBar);
|
||||||
|
group.push_back(parBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void Collider::UnregisterBar (GroupIDType parGroup, const CollisionBar* parBar) {
|
||||||
|
assert(isGroupRegistered(m_collisionBars, parGroup));
|
||||||
|
CollisionBarListType& group = findOrAddGroup(m_collisionBars, parGroup);
|
||||||
|
auto itdele = std::find(group.begin(), group.end(), parBar);
|
||||||
|
assert(itdele != group.end());
|
||||||
|
group.erase(itdele);
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
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
|
} //namespace cloonel
|
||||||
|
|
||||||
|
|
|
@ -22,18 +22,38 @@
|
||||||
|
|
||||||
#include "observersmanager.hpp"
|
#include "observersmanager.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class HorzCollisionBar;
|
class HorzCollisionBar;
|
||||||
|
class CollisionBarSet;
|
||||||
|
|
||||||
|
typedef HorzCollisionBar CollisionBar;
|
||||||
|
|
||||||
class Collider {
|
class Collider {
|
||||||
public:
|
public:
|
||||||
|
typedef int GroupIDType;
|
||||||
|
|
||||||
Collider ( void );
|
Collider ( void );
|
||||||
~Collider ( void ) noexcept;
|
~Collider ( void ) noexcept;
|
||||||
|
|
||||||
void RunCollisionTests ( void );
|
void RunCollisionTests ( float parDeltaT ) const;
|
||||||
|
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:
|
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
|
} //namespace cloonel
|
||||||
|
|
||||||
|
|
32
src/collidertypedef.hpp
Normal file
32
src/collidertypedef.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
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 id3DF7C722C6AE4978874605F38F26E350
|
||||||
|
#define id3DF7C722C6AE4978874605F38F26E350
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace cloonel {
|
||||||
|
class HorzCollisionBar;
|
||||||
|
typedef std::function<void(HorzCollisionBar*)> ColliderRegisterFunc;
|
||||||
|
typedef std::function<void(HorzCollisionBar*)> ColliderUnregisterFunc;
|
||||||
|
} //namespace cloonel
|
||||||
|
|
||||||
|
#endif
|
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,9 @@
|
||||||
#include "gameplayscene.hpp"
|
#include "gameplayscene.hpp"
|
||||||
#include "mover.hpp"
|
#include "mover.hpp"
|
||||||
#include "drawable.hpp"
|
#include "drawable.hpp"
|
||||||
|
#include "drawableset.hpp"
|
||||||
|
#include "placeable.hpp"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
@ -32,23 +35,39 @@ namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void GameplayScene::OnUpdate (float parDelta) {
|
void GameplayScene::OnUpdate (float parDelta) {
|
||||||
for (auto itMover : m_movers) {
|
{
|
||||||
itMover->Update(parDelta);
|
std::unordered_set<Placeable*> notify;
|
||||||
|
for (auto mover : m_movers) {
|
||||||
|
mover->CopyPlaceables(notify);
|
||||||
}
|
}
|
||||||
m_collider.RunCollisionTests();
|
for (auto placeable : notify) {
|
||||||
|
assert(placeable);
|
||||||
|
placeable->BeginMovement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto mover : m_movers) {
|
||||||
|
mover->Update(parDelta);
|
||||||
|
}
|
||||||
|
m_collider.RunCollisionTests(parDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void GameplayScene::OnRender() {
|
void GameplayScene::OnRender() {
|
||||||
for (auto itDrawable : m_drawables) {
|
std::vector<const Drawable*> drawables;
|
||||||
itDrawable->Draw();
|
for (auto drawableSet : m_drawableSets) {
|
||||||
|
drawables.clear();
|
||||||
|
drawableSet->CopyDrawables(drawables);
|
||||||
|
for (auto drawable : drawables) {
|
||||||
|
drawable->Draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void GameplayScene::Destroy() noexcept {
|
void GameplayScene::Destroy() noexcept {
|
||||||
|
m_collider.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class Mover;
|
class Mover;
|
||||||
class Drawable;
|
class DrawableSet;
|
||||||
|
|
||||||
class GameplayScene : public GameBase {
|
class GameplayScene : public GameBase {
|
||||||
public:
|
public:
|
||||||
|
@ -35,12 +35,12 @@ namespace cloonel {
|
||||||
virtual ~GameplayScene ( void ) noexcept = default;
|
virtual ~GameplayScene ( void ) noexcept = default;
|
||||||
|
|
||||||
void AddMover ( Mover* parMover ) { assert(parMover); m_movers.push_back(parMover); }
|
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;
|
virtual void Destroy ( void ) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Collider* GetCollider ( void );
|
Collider* GetCollider ( void ) { return &m_collider; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void OnRender ( void );
|
virtual void OnRender ( void );
|
||||||
|
@ -49,7 +49,7 @@ namespace cloonel {
|
||||||
|
|
||||||
Collider m_collider;
|
Collider m_collider;
|
||||||
std::vector<Mover*> m_movers;
|
std::vector<Mover*> m_movers;
|
||||||
std::vector<const Drawable*> m_drawables;
|
std::vector<const DrawableSet*> m_drawableSets;
|
||||||
};
|
};
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,12 @@
|
||||||
#include "moverworld.hpp"
|
#include "moverworld.hpp"
|
||||||
#include "tiledwallpaper.hpp"
|
#include "tiledwallpaper.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
#include "platformsystem.hpp"
|
#include "platformspawner.hpp"
|
||||||
#include "CloonelJumpConfig.h"
|
#include "CloonelJumpConfig.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <SDL2/SDL_scancode.h>
|
#include <SDL2/SDL_scancode.h>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -39,6 +40,16 @@ namespace cloonel {
|
||||||
GameAction_Left,
|
GameAction_Left,
|
||||||
GameAction_Right
|
GameAction_Right
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CollisionID_Platforms,
|
||||||
|
CollisionID_Player,
|
||||||
|
CollisionID_Enemies
|
||||||
|
};
|
||||||
|
|
||||||
|
void OnCharacterBounce (MoverSine* parMover, const Line<float, 2>&, const float2&) {
|
||||||
|
parMover->ResetToBounce();
|
||||||
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
@ -62,13 +73,15 @@ namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void GameplaySceneClassic::OnPrepare() {
|
void GameplaySceneClassic::OnPrepare() {
|
||||||
const float halfRefHeight = static_cast<float>(REFERENCE_HEIGHT) / 2.0f;
|
const float halfRefHeight = static_cast<float>(REFERENCE_HEIGHT) / 2.0f;
|
||||||
|
Collider& collider = *this->GetCollider();
|
||||||
|
const float2 charaRefSize(static_cast<float>(REFERENCE_CHARA_WIDTH), static_cast<float>(REFERENCE_CHARA_HEIGHT));
|
||||||
|
|
||||||
std::unique_ptr<MoverSine> moverSine(new MoverSine());
|
std::unique_ptr<MoverSine> moverSine(new MoverSine());
|
||||||
std::unique_ptr<Character> player(new Character("resources/graphics/player.png", SDLObject(), float2(80.0f, 120.0f)));
|
std::unique_ptr<Character> player(new Character("resources/graphics/player.png", SDLObject(), charaRefSize));
|
||||||
std::unique_ptr<MoverLeftRight> moverLeftRight(new MoverLeftRight(1.5f, 5.0f, 40.0f));
|
std::unique_ptr<MoverLeftRight> moverLeftRight(new MoverLeftRight(1.5f, 5.0f, 40.0f));
|
||||||
std::unique_ptr<MoverWorld> moverWorld(new MoverWorld(halfRefHeight));
|
std::unique_ptr<MoverWorld> moverWorld(new MoverWorld(halfRefHeight));
|
||||||
std::unique_ptr<TiledWallpaper> wallpaper(new TiledWallpaper("resources/graphics/background_tile.png", SDLObject()));
|
std::unique_ptr<TiledWallpaper> wallpaper(new TiledWallpaper("resources/graphics/background_tile.png", SDLObject()));
|
||||||
std::unique_ptr<PlatformSystem> platforms(new PlatformSystem("resources/graphics/platform.png", SDLObject(), this, halfRefHeight * 0.9f));
|
std::unique_ptr<PlatformSpawner> platforms(new PlatformSpawner("resources/graphics/platform.png", SDLObject(), this, halfRefHeight * 0.9f));
|
||||||
|
|
||||||
player->Prepare();
|
player->Prepare();
|
||||||
platforms->Prepare();
|
platforms->Prepare();
|
||||||
|
@ -80,6 +93,14 @@ namespace cloonel {
|
||||||
moverWorld->RegisterPlaceable(platforms.get());
|
moverWorld->RegisterPlaceable(platforms.get());
|
||||||
wallpaper->Reload();
|
wallpaper->Reload();
|
||||||
|
|
||||||
|
{
|
||||||
|
auto regPlayerCollision(std::bind(&Collider::RegisterBar, &collider, CollisionID_Player, std::placeholders::_1));
|
||||||
|
player->RegisterForCollision(regPlayerCollision);
|
||||||
|
}
|
||||||
|
platforms->RegisterForCollision(collider, CollisionID_Platforms);
|
||||||
|
|
||||||
|
player->SetOnBounceCallback(std::bind(&OnCharacterBounce, moverSine.get(), std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
||||||
std::swap(moverSine, m_moverSine);
|
std::swap(moverSine, m_moverSine);
|
||||||
std::swap(player, m_player);
|
std::swap(player, m_player);
|
||||||
std::swap(moverLeftRight, m_moverLeftRight);
|
std::swap(moverLeftRight, m_moverLeftRight);
|
||||||
|
@ -89,13 +110,16 @@ namespace cloonel {
|
||||||
|
|
||||||
AddMover(m_moverSine.get());
|
AddMover(m_moverSine.get());
|
||||||
AddMover(m_moverLeftRight.get());
|
AddMover(m_moverLeftRight.get());
|
||||||
AddDrawable(m_wallpaper.get());
|
AddDrawableSet(m_wallpaper.get());
|
||||||
AddMover(m_moverWorld.get());
|
AddMover(m_moverWorld.get());
|
||||||
m_platforms->AddDrawables();
|
AddDrawableSet(m_platforms->GetDrawableSet());
|
||||||
AddDrawable(m_player.get());
|
AddDrawableSet(m_player.get());
|
||||||
|
|
||||||
const float jumpPower = halfRefHeight * 1.29f;
|
const float jumpPower = halfRefHeight * 0.71f;
|
||||||
m_moverSine->SetPower(jumpPower);
|
m_moverSine->SetPower(jumpPower);
|
||||||
|
|
||||||
|
collider.TieGroups(CollisionID_Platforms, CollisionID_Player);
|
||||||
|
//collider.TieGroups(CollisionID_Enemies, CollisionID_Player);
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
@ -104,13 +128,12 @@ namespace cloonel {
|
||||||
GameplayScene::Destroy();
|
GameplayScene::Destroy();
|
||||||
|
|
||||||
//Destroy in reverse creation order
|
//Destroy in reverse creation order
|
||||||
m_platforms = std::move(std::unique_ptr<PlatformSystem>(nullptr));
|
m_platforms = std::move(std::unique_ptr<PlatformSpawner>(nullptr));
|
||||||
m_wallpaper = std::move(std::unique_ptr<TiledWallpaper>(nullptr));
|
m_wallpaper = std::move(std::unique_ptr<TiledWallpaper>(nullptr));
|
||||||
m_moverWorld = std::move(std::unique_ptr<MoverWorld>(nullptr));
|
m_moverWorld = std::move(std::unique_ptr<MoverWorld>(nullptr));
|
||||||
m_moverLeftRight = std::move(std::unique_ptr<MoverLeftRight>(nullptr));
|
m_moverLeftRight = std::move(std::unique_ptr<MoverLeftRight>(nullptr));
|
||||||
m_player = std::move(std::unique_ptr<Character>(nullptr));
|
m_player = std::move(std::unique_ptr<Character>(nullptr));
|
||||||
m_moverSine = std::move(std::unique_ptr<MoverSine>(nullptr));
|
m_moverSine = std::move(std::unique_ptr<MoverSine>(nullptr));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace cloonel {
|
||||||
class MoverWorld;
|
class MoverWorld;
|
||||||
class TiledWallpaper;
|
class TiledWallpaper;
|
||||||
class Texture;
|
class Texture;
|
||||||
class PlatformSystem;
|
class PlatformSpawner;
|
||||||
|
|
||||||
class GameplaySceneClassic : public GameplayScene {
|
class GameplaySceneClassic : public GameplayScene {
|
||||||
public:
|
public:
|
||||||
|
@ -49,7 +49,7 @@ namespace cloonel {
|
||||||
std::unique_ptr<MoverLeftRight> m_moverLeftRight;
|
std::unique_ptr<MoverLeftRight> m_moverLeftRight;
|
||||||
std::unique_ptr<MoverWorld> m_moverWorld;
|
std::unique_ptr<MoverWorld> m_moverWorld;
|
||||||
std::unique_ptr<TiledWallpaper> m_wallpaper;
|
std::unique_ptr<TiledWallpaper> m_wallpaper;
|
||||||
std::unique_ptr<PlatformSystem> m_platforms;
|
std::unique_ptr<PlatformSpawner> m_platforms;
|
||||||
};
|
};
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
namespace {
|
namespace {
|
||||||
typedef Line<float, 2> Line2D;
|
typedef HorzCollisionBar::Line2D Line2D;
|
||||||
|
|
||||||
float calculateOverlappingTime ( float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB ) __attribute__((pure));
|
float calculateOverlappingTime ( float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB ) __attribute__((pure));
|
||||||
void DoNothing ( void ) __attribute__((pure));
|
void DoNothing ( const Line2D&, const float2& ) __attribute__((pure));
|
||||||
std::pair<bool, Line2D> getOverlap ( float parDeltaT, const Line2D& parA, const Line2D& parB, const float2& parDeltaA, const float2& parDeltaB ) __attribute__((pure));
|
std::pair<bool, Line2D> getOverlap ( float parDeltaT, const Line2D& parA, const Line2D& parB, const float2& parDeltaA, const float2& parDeltaB ) __attribute__((pure));
|
||||||
|
|
||||||
///----------------------------------------------------------------------
|
///----------------------------------------------------------------------
|
||||||
|
@ -41,8 +41,8 @@ namespace cloonel {
|
||||||
///reference time frame.
|
///reference time frame.
|
||||||
///----------------------------------------------------------------------
|
///----------------------------------------------------------------------
|
||||||
float calculateOverlappingTime (float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB) {
|
float calculateOverlappingTime (float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB) {
|
||||||
const float deltaDiff = std::max(parDeltaA, parDeltaB) - std::min(parDeltaA, parDeltaB);
|
//const float deltaDiff = std::max(parDeltaA, parDeltaB) - std::min(parDeltaA, parDeltaB);
|
||||||
assert(deltaDiff >= 0.0f);
|
const float deltaDiff = std::abs(parDeltaA - parDeltaB);
|
||||||
|
|
||||||
if (deltaDiff <= 0.00001f)
|
if (deltaDiff <= 0.00001f)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
@ -67,13 +67,13 @@ namespace cloonel {
|
||||||
|
|
||||||
const auto& retStart = (midpointA.Start().x() > midpointB.Start().x() ? midpointA.Start() : midpointB.Start());
|
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());
|
const auto& retEnd = (midpointA.End().x() < midpointB.End().x() ? midpointA.End() : midpointB.End());
|
||||||
return std::make_pair(true, Line2D(retStart, retEnd));
|
return std::make_pair(true, Line2D(retStart, float2(retEnd.x(), retStart.y())));
|
||||||
}
|
}
|
||||||
|
|
||||||
///----------------------------------------------------------------------
|
///----------------------------------------------------------------------
|
||||||
///no-op
|
///no-op
|
||||||
///----------------------------------------------------------------------
|
///----------------------------------------------------------------------
|
||||||
void DoNothing() {
|
void DoNothing (const HorzCollisionBar::Line2D&, const float2&) {
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ namespace cloonel {
|
||||||
HorzCollisionBar::HorzCollisionBar (const float2& parFrom, float parLength) :
|
HorzCollisionBar::HorzCollisionBar (const float2& parFrom, float parLength) :
|
||||||
Placeable(parFrom),
|
Placeable(parFrom),
|
||||||
m_segment(parFrom, float2(1.0f, 0.0f), parLength),
|
m_segment(parFrom, float2(1.0f, 0.0f), parLength),
|
||||||
|
m_offset(0.0f),
|
||||||
m_callback(&DoNothing)
|
m_callback(&DoNothing)
|
||||||
{
|
{
|
||||||
assert(parLength != 0.0f);
|
assert(parLength != 0.0f);
|
||||||
|
@ -89,7 +90,7 @@ namespace cloonel {
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void HorzCollisionBar::SetCallback (std::function<void()> parCallback) {
|
void HorzCollisionBar::SetCallback (CallbackType parCallback) {
|
||||||
m_callback = parCallback;
|
m_callback = parCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +102,28 @@ namespace cloonel {
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
bool Collide (float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line<float, 2>& parOut) {
|
void HorzCollisionBar::InvokeCallback (const Line2D& parOverlap, const float2& parDirection) const {
|
||||||
const auto offsetA = parA.GetPos() - parA.m_segment.Start();
|
m_callback(parOverlap, parDirection);
|
||||||
const auto offsetB = parB.GetPos() - parB.m_segment.Start();
|
}
|
||||||
const auto overlap(getOverlap(parDeltaT, parA.m_segment, parB.m_segment, offsetA, offsetB));
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
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 overlap(getOverlap(parDeltaT, parA.m_segment, parB.m_segment, parA.GetOffset(), parB.GetOffset()));
|
||||||
|
|
||||||
if (overlap.first) {
|
if (overlap.first) {
|
||||||
parOut = overlap.second;
|
parOut = overlap.second;
|
||||||
|
|
|
@ -29,22 +29,34 @@ namespace cloonel {
|
||||||
class HorzCollisionBar;
|
class HorzCollisionBar;
|
||||||
|
|
||||||
class HorzCollisionBar : public Placeable {
|
class HorzCollisionBar : public Placeable {
|
||||||
friend bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line<float, 2>& parOut );
|
public:
|
||||||
|
typedef Line<float, 2> Line2D;
|
||||||
|
typedef std::function<void(const Line2D&, const float2&)> CallbackType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HorzCollisionBar ( const float2& parFrom, float parLength );
|
HorzCollisionBar ( const float2& parFrom, float parLength );
|
||||||
~HorzCollisionBar ( void ) noexcept = default;
|
virtual ~HorzCollisionBar ( void ) noexcept = default;
|
||||||
|
|
||||||
float2 From ( void ) const { return this->GetPos(); }
|
float2 From ( void ) const { return this->GetPos(); }
|
||||||
float2 To ( void ) const;
|
float2 To ( void ) const;
|
||||||
|
|
||||||
void SetCallback ( std::function<void()> parCallback );
|
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:
|
private:
|
||||||
Line<float, 2> m_segment;
|
friend bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line2D& parOut );
|
||||||
std::function<void()> m_callback;
|
|
||||||
|
Line2D m_segment;
|
||||||
|
float2 m_offset;
|
||||||
|
CallbackType m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line<float, 2>& parOut ) __attribute__((pure));
|
bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, HorzCollisionBar::Line2D& parOut ) __attribute__((pure));
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,9 +31,10 @@ namespace cloonel {
|
||||||
typedef T Scalar;
|
typedef T Scalar;
|
||||||
|
|
||||||
Line ( void ) {}
|
Line ( void ) {}
|
||||||
|
explicit Line ( Scalar parValue );
|
||||||
Line ( const Line& parOther );
|
Line ( const Line& parOther );
|
||||||
Line ( const Point& parStart, const Point& parEnd );
|
Line ( const Point& parStart, const Point& parEnd );
|
||||||
Line ( const Point& parStart, const Point& parDirection, Scalar parLength ) : Line(parStart, parDirection * parLength) { }
|
Line ( const Point& parStart, const Point& parDirection, Scalar parLength ) : Line(parStart, parStart + parDirection * parLength) { }
|
||||||
~Line ( void ) noexcept = default;
|
~Line ( void ) noexcept = default;
|
||||||
|
|
||||||
Point& Start ( void ) { return m_points.x(); }
|
Point& Start ( void ) { return m_points.x(); }
|
||||||
|
|
32
src/line.inl
32
src/line.inl
|
@ -7,6 +7,14 @@ namespace cloonel {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <typename T, uint32_t S>
|
||||||
|
Line<T, S>::Line (Scalar parValue) :
|
||||||
|
m_points(Point(parValue))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
template <typename T, uint32_t S>
|
template <typename T, uint32_t S>
|
||||||
|
@ -14,13 +22,13 @@ namespace cloonel {
|
||||||
m_points(parStart, parEnd)
|
m_points(parStart, parEnd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
template <typename T, uint32_t S>
|
template <typename T, uint32_t S>
|
||||||
Line<T, S>& Line<T, S>::operator+= (const Point& parRhs) {
|
Line<T, S>& Line<T, S>::operator+= (const Point& parRhs) {
|
||||||
for (uint32_t z = 0; z < S; ++z) {
|
m_points.x() += parRhs;
|
||||||
m_points[z] += parRhs;
|
m_points.y() += parRhs;
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +36,8 @@ namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
template <typename T, uint32_t S>
|
template <typename T, uint32_t S>
|
||||||
Line<T, S>& Line<T, S>::operator-= (const Point& parRhs) {
|
Line<T, S>& Line<T, S>::operator-= (const Point& parRhs) {
|
||||||
for (uint32_t z = 0; z < S; ++z) {
|
m_points.x() -= parRhs;
|
||||||
m_points[z] -= parRhs;
|
m_points.y() -= parRhs;
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,4 +116,17 @@ namespace cloonel {
|
||||||
const T dotproduct = dot(linePerp, pt);
|
const T dotproduct = dot(linePerp, pt);
|
||||||
return (dotproduct <= T(0));
|
return (dotproduct <= T(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <typename T, uint32_t S>
|
||||||
|
std::ostream& operator<< ( std::ostream& parStream, const Line<T, S>& parLine ) {
|
||||||
|
for (uint32_t z = 0; z < S - 1; ++z) {
|
||||||
|
parStream << parLine[z] << "-";
|
||||||
|
}
|
||||||
|
parStream << parLine[S - 1];
|
||||||
|
return parStream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -58,6 +58,8 @@ int main (int, char* parArgv[]) {
|
||||||
physfs.Append(GAME_BASE_PATH "/resources/", "resources");
|
physfs.Append(GAME_BASE_PATH "/resources/", "resources");
|
||||||
|
|
||||||
sdlmain.Init();
|
sdlmain.Init();
|
||||||
|
std::cout << "Using renderer \"" << sdlmain.GetRendererName() << "\" ";
|
||||||
|
std::cout << "and video driver \"" << sdlmain.GetVideoDriverName() << "\"\n";
|
||||||
|
|
||||||
cloonel::GameplaySceneClassic game(&sdlmain);
|
cloonel::GameplaySceneClassic game(&sdlmain);
|
||||||
RunMainLoop(game);
|
RunMainLoop(game);
|
||||||
|
|
|
@ -45,4 +45,10 @@ namespace cloonel {
|
||||||
parPlaceable->OnRegister(*this, currTicket);
|
parPlaceable->OnRegister(*this, currTicket);
|
||||||
return currTicket;
|
return currTicket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void Mover::CopyPlaceables (std::unordered_set<Placeable*>& parOut) {
|
||||||
|
m_placeables.CopyObservers(parOut);
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "observersmanager.hpp"
|
#include "observersmanager.hpp"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class Placeable;
|
class Placeable;
|
||||||
|
@ -40,6 +41,7 @@ namespace cloonel {
|
||||||
virtual void Update ( float parDelta );
|
virtual void Update ( float parDelta );
|
||||||
PlaceableTicketType RegisterPlaceable ( Placeable* parPlaceable, PlaceableTicketType parParent=ObserversManager<Placeable*>::Ticket_Null );
|
PlaceableTicketType RegisterPlaceable ( Placeable* parPlaceable, PlaceableTicketType parParent=ObserversManager<Placeable*>::Ticket_Null );
|
||||||
void UnregisterPlaceable ( PlaceableTicketType parID ) noexcept { m_placeables.Remove(parID); }
|
void UnregisterPlaceable ( PlaceableTicketType parID ) noexcept { m_placeables.Remove(parID); }
|
||||||
|
void CopyPlaceables ( std::unordered_set<Placeable*>& parOut );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::size_t PlaceableCount ( void ) const { return m_placeables.size(); }
|
std::size_t PlaceableCount ( void ) const { return m_placeables.size(); }
|
||||||
|
|
|
@ -47,4 +47,10 @@ namespace cloonel {
|
||||||
while (m_alpha >= pitwo)
|
while (m_alpha >= pitwo)
|
||||||
m_alpha -= pitwo;
|
m_alpha -= pitwo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void MoverSine::ResetToBounce() {
|
||||||
|
m_alpha = 0.0f;
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace cloonel {
|
||||||
~MoverSine ( void ) noexcept = default;
|
~MoverSine ( void ) noexcept = default;
|
||||||
|
|
||||||
void SetPower ( float parPower ) noexcept { m_power = parPower; }
|
void SetPower ( float parPower ) noexcept { m_power = parPower; }
|
||||||
|
void ResetToBounce ( void );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void ApplyMotion ( float parDelta );
|
virtual void ApplyMotion ( float parDelta );
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <tree.hh>
|
#include <tree.hh>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#if defined (WITH_VERBOSE_OBS_MANAGER) && defined(__GNUC__) && __GNUC__ >= 2 && !defined(NDEBUG)
|
#if defined (WITH_VERBOSE_OBS_MANAGER) && defined(__GNUC__) && __GNUC__ >= 2 && !defined(NDEBUG)
|
||||||
# define OBS_MANAGER_LOG
|
# define OBS_MANAGER_LOG
|
||||||
|
@ -78,6 +79,7 @@ namespace cloonel {
|
||||||
std::size_t size ( void ) const { return m_tree.size(); }
|
std::size_t size ( void ) const { return m_tree.size(); }
|
||||||
iterator begin ( void ) { return iterator(m_tree.begin(), &TicketedWrapperToItm); }
|
iterator begin ( void ) { return iterator(m_tree.begin(), &TicketedWrapperToItm); }
|
||||||
iterator end ( void ) { return iterator(m_tree.end(), &TicketedWrapperToItm); }
|
iterator end ( void ) { return iterator(m_tree.end(), &TicketedWrapperToItm); }
|
||||||
|
void CopyObservers ( std::unordered_set<T>& parOut );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeIteratorType GetByTicket_AssertPresent ( TicketType parTicket );
|
TreeIteratorType GetByTicket_AssertPresent ( TicketType parTicket );
|
||||||
|
@ -161,6 +163,15 @@ namespace cloonel {
|
||||||
assert(m_tree.end() != ret);
|
assert(m_tree.end() != ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
void ObserversManager<T>::CopyObservers (std::unordered_set<T>& parOut) {
|
||||||
|
for (const auto& itm : m_tree) {
|
||||||
|
parOut.insert(itm.itm);
|
||||||
|
}
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
#if defined(OBS_MANAGER_LOG)
|
#if defined(OBS_MANAGER_LOG)
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace cloonel {
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
PhysicsFSWrapper::~PhysicsFSWrapper() noexcept {
|
PhysicsFSWrapper::~PhysicsFSWrapper() noexcept {
|
||||||
const bool succeeded = static_cast<bool>(PHYSFS_deinit());
|
const bool succeeded = static_cast<bool>(PHYSFS_deinit());
|
||||||
|
(void)succeeded;
|
||||||
assert(succeeded);
|
assert(succeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,4 +34,9 @@ namespace cloonel {
|
||||||
void Placeable::OnRegister (Mover&, Mover::PlaceableTicketType) {
|
void Placeable::OnRegister (Mover&, Mover::PlaceableTicketType) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void Placeable::BeginMovement() {
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -27,12 +27,14 @@ namespace cloonel {
|
||||||
class Placeable {
|
class Placeable {
|
||||||
public:
|
public:
|
||||||
float2 GetPos ( void ) const noexcept;
|
float2 GetPos ( void ) const noexcept;
|
||||||
void AddOffset ( const float2& parOffset ) noexcept;
|
virtual void AddOffset ( const float2& parOffset ) noexcept;
|
||||||
|
virtual void SetAbsolutePosition ( const float2& parPos ) noexcept;
|
||||||
virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket );
|
virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket );
|
||||||
|
virtual void BeginMovement ( void );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Placeable ( float2 parPos );
|
explicit Placeable ( float2 parPos );
|
||||||
~Placeable ( void ) noexcept = default;
|
virtual ~Placeable ( void ) noexcept = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float2 m_pos;
|
float2 m_pos;
|
||||||
|
@ -49,6 +51,12 @@ namespace cloonel {
|
||||||
inline float2 Placeable::GetPos() const noexcept {
|
inline float2 Placeable::GetPos() const noexcept {
|
||||||
return m_pos;
|
return m_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
inline void Placeable::SetAbsolutePosition (const float2& parPos) noexcept {
|
||||||
|
m_pos = parPos;
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,16 +19,18 @@
|
||||||
|
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
|
#include "horzcollisionbar.hpp"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
Platform::Platform (SDLMain* parSdlMain, const float2& parPos, Texture* parTexture, const float2& parSize) :
|
Platform::Platform (SDLMain* parSdlMain, const float2& parPos, Texture* parTexture, const float2& parSize) :
|
||||||
Placeable(parPos),
|
Placeable(parPos),
|
||||||
m_collisionTop(parPos, parSize.x()),
|
|
||||||
m_screenRatio(parSdlMain),
|
m_screenRatio(parSdlMain),
|
||||||
m_size(parSize),
|
m_size(parSize),
|
||||||
|
m_collisionTop(new HorzCollisionBar(parPos, parSize.x())),
|
||||||
m_surface(parTexture)
|
m_surface(parTexture)
|
||||||
{
|
{
|
||||||
assert(m_surface);
|
assert(m_surface);
|
||||||
|
@ -38,13 +40,18 @@ namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
Platform::Platform (Platform&& parOther) noexcept :
|
Platform::Platform (Platform&& parOther) noexcept :
|
||||||
Placeable(parOther.GetPos()),
|
Placeable(parOther.GetPos()),
|
||||||
m_collisionTop(parOther.m_collisionTop),
|
|
||||||
m_screenRatio(std::move(parOther.m_screenRatio)),
|
m_screenRatio(std::move(parOther.m_screenRatio)),
|
||||||
m_size(parOther.m_size),
|
m_size(parOther.m_size),
|
||||||
|
m_collisionTop(std::move(parOther.m_collisionTop)),
|
||||||
m_surface(parOther.m_surface)
|
m_surface(parOther.m_surface)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
Platform::~Platform() noexcept {
|
||||||
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void Platform::Draw() const {
|
void Platform::Draw() const {
|
||||||
|
@ -65,6 +72,6 @@ namespace cloonel {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void Platform::OnRegister (Mover& parMover, Mover::PlaceableTicketType parParentTicket) {
|
void Platform::OnRegister (Mover& parMover, Mover::PlaceableTicketType parParentTicket) {
|
||||||
parMover.RegisterPlaceable(&m_collisionTop, parParentTicket);
|
parMover.RegisterPlaceable(m_collisionTop.get(), parParentTicket);
|
||||||
}
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -23,31 +23,36 @@
|
||||||
#include "sizenotifiable.hpp"
|
#include "sizenotifiable.hpp"
|
||||||
#include "drawable.hpp"
|
#include "drawable.hpp"
|
||||||
#include "placeable.hpp"
|
#include "placeable.hpp"
|
||||||
#include "horzcollisionbar.hpp"
|
#include "collidertypedef.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class Texture;
|
class Texture;
|
||||||
class SDLMain;
|
class SDLMain;
|
||||||
|
class HorzCollisionBar;
|
||||||
|
|
||||||
class Platform : public Drawable, public Placeable {
|
class Platform : public Drawable, public Placeable {
|
||||||
public:
|
public:
|
||||||
Platform ( SDLMain* parSdlMain, const float2& parPos, Texture* parTexture, const float2& parSize );
|
Platform ( SDLMain* parSdlMain, const float2& parPos, Texture* parTexture, const float2& parSize );
|
||||||
Platform ( Platform&& parOther ) noexcept;
|
Platform ( Platform&& parOther ) noexcept;
|
||||||
Platform ( const Platform& ) = delete;
|
Platform ( const Platform& ) = delete;
|
||||||
virtual ~Platform ( void ) noexcept = default;
|
virtual ~Platform ( void ) noexcept;
|
||||||
Platform& operator= ( const Platform& parOther );
|
Platform& operator= ( const Platform& parOther );
|
||||||
|
|
||||||
float2 TopLeft ( void ) const { return GetPos(); }
|
float2 TopLeft ( void ) const { return GetPos(); }
|
||||||
float2 BottomRight ( void ) const { return TopLeft() + m_size; }
|
float2 BottomRight ( void ) const { return TopLeft() + m_size; }
|
||||||
|
const HorzCollisionBar* TopCollisionBar ( void ) const { return m_collisionTop.get(); }
|
||||||
|
|
||||||
//Overrides
|
//Overrides
|
||||||
virtual void Draw ( void ) const;
|
virtual void Draw ( void ) const;
|
||||||
virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket );
|
virtual void OnRegister ( Mover& parMover, Mover::PlaceableTicketType parParentTicket );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HorzCollisionBar m_collisionTop;
|
|
||||||
SizeNotifiable<regbehaviours::AutoRegister> m_screenRatio;
|
SizeNotifiable<regbehaviours::AutoRegister> m_screenRatio;
|
||||||
float2 m_size;
|
float2 m_size;
|
||||||
|
ColliderRegisterFunc m_registerToCollider;
|
||||||
|
ColliderUnregisterFunc m_unregisterFromCollider;
|
||||||
|
std::unique_ptr<HorzCollisionBar> m_collisionTop;
|
||||||
Texture* m_surface;
|
Texture* m_surface;
|
||||||
};
|
};
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
118
src/platformset.cpp
Normal file
118
src/platformset.cpp
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
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 {
|
||||||
|
namespace {
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
boost::circular_buffer<Platform>::const_iterator FindFirstVisible (const boost::circular_buffer<Platform>& parPlatforms) {
|
||||||
|
auto curr = parPlatforms.begin();
|
||||||
|
while (curr != parPlatforms.end() and curr->TopLeft().y() < 0.0f) {
|
||||||
|
++curr;
|
||||||
|
}
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
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 {
|
||||||
|
auto eleCopy = FindFirstVisible(m_platforms);
|
||||||
|
const size_t count = m_platforms.end() - eleCopy;
|
||||||
|
parOut.reserve(parOut.size() + count);
|
||||||
|
while (m_platforms.end() != eleCopy) {
|
||||||
|
parOut.push_back(eleCopy->TopCollisionBar());
|
||||||
|
++eleCopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void PlatformSet::CopyDrawables (std::vector<const Drawable*>& parOut) const {
|
||||||
|
auto eleCopy = FindFirstVisible(m_platforms);
|
||||||
|
const size_t count = m_platforms.end() - eleCopy;
|
||||||
|
parOut.reserve(parOut.size() + count);
|
||||||
|
while (m_platforms.end() != eleCopy) {
|
||||||
|
parOut.push_back(&*eleCopy);
|
||||||
|
++eleCopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
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
|
|
@ -17,19 +17,21 @@
|
||||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "platformsystem.hpp"
|
#include "platformspawner.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
#include "CloonelJumpConfig.h"
|
#include "CloonelJumpConfig.h"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
#include "gameplayscene.hpp"
|
#include "gameplayscene.hpp"
|
||||||
#include "mover.hpp"
|
#include "mover.hpp"
|
||||||
|
#include "collider.hpp"
|
||||||
|
#include "platformset.hpp"
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/circular_buffer.hpp>
|
|
||||||
#include <boost/algorithm/clamp.hpp>
|
#include <boost/algorithm/clamp.hpp>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -59,52 +61,22 @@ namespace cloonel {
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
struct PlatformInfo {
|
struct PlatformSpawner::LocalData : public boost::noncopyable {
|
||||||
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 ( const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance );
|
||||||
~LocalData ( void ) noexcept = default;
|
~LocalData ( void ) noexcept = default;
|
||||||
|
|
||||||
boost::circular_buffer<PlatformInfo> platforms;
|
PlatformSet platforms;
|
||||||
Texture texture;
|
Texture texture;
|
||||||
SDLMain* const sdlmain;
|
std::list<std::pair<Collider::GroupIDType, Collider*>> registeredTo;
|
||||||
GameplayScene* const scene;
|
GameplayScene* const scene;
|
||||||
const float maxDistance;
|
const float maxDistance;
|
||||||
};
|
};
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
PlatformSystem::LocalData::LocalData (const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance) :
|
PlatformSpawner::LocalData::LocalData (const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance) :
|
||||||
platforms(MAX_PLATFORMS_ON_SCREEN),
|
platforms(parSDLMain),
|
||||||
texture(parTexturePath, parSDLMain, false),
|
texture(parTexturePath, parSDLMain, false),
|
||||||
sdlmain(parSDLMain),
|
|
||||||
scene(parScene),
|
scene(parScene),
|
||||||
maxDistance(parMaxDistance)
|
maxDistance(parMaxDistance)
|
||||||
{
|
{
|
||||||
|
@ -112,85 +84,91 @@ namespace cloonel {
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
PlatformSystem::PlatformSystem (const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance) :
|
PlatformSpawner::PlatformSpawner (const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance) :
|
||||||
Placeable(float2(0.0f)),
|
Placeable(float2(0.0f)),
|
||||||
m_localdata(new LocalData(parTexturePath, parSDLMain, parScene, parMaxDistance))
|
m_localdata(new LocalData(parTexturePath, parSDLMain, parScene, parMaxDistance)),
|
||||||
|
m_targetAverage(parMaxDistance / 5.25f) //TODO: change this value to make up for the difficulty
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
PlatformSystem::~PlatformSystem() noexcept {
|
PlatformSpawner::~PlatformSpawner() noexcept {
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void PlatformSystem::SpawnPlatforms() {
|
void PlatformSpawner::SpawnPlatforms() {
|
||||||
//const int2 refWH(REFERENCE_WIDTH, REFERENCE_HEIGHT);
|
const float2 platfWH(static_cast<float>(g_platfWidth), static_cast<float>(g_platfHeight));
|
||||||
//const int2 platfWH(g_platfWidth, g_platfHeight);
|
|
||||||
|
|
||||||
// if (m_localdata.platforms.back().platform->TopLeft().y() <= 0.0f) {
|
size_t freePlatforms = m_localdata->platforms.CountFreePlatforms();
|
||||||
// const float2 newPos(static_cast<float>(std::rand() % (refWH.x() - platfWH.x())), static_cast<float>(std::rand() % (refWH.y() - platfWH.y())));
|
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
|
||||||
//if (m_localdata->platforms.empty()) {
|
//screen-relative position only. Change the movers as appropriate.
|
||||||
// const float2 newPos(static_cast<float>(std::rand() % (refWH.x() - platfWH.x())), static_cast<float>(std::rand() % (refWH.y() - platfWH.y())));
|
//std::cout << "Top platform is at index " << m_localdata->platforms.size() - 1 << ", prevPlatf = " << prevPlatf << " ";
|
||||||
// m_localdata->platforms.push_back(Platform(m_localdata->sdlmain, newPos, &m_localdata->texture, static_cast<float2>(platfWH)));
|
//if (not m_localdata->platforms.empty()) {
|
||||||
|
//std::cout << "top pos is " << m_localdata->platforms.back().platform->GetPos() << ", system's pos is " << GetPos() << "\n";
|
||||||
// PlatformInfo& newPlatf = m_localdata->platforms.back();
|
|
||||||
// m_localdata->scene->AddDrawable(&newPlatf.platform);
|
|
||||||
// const Mover::PlaceableTicketType ticket = m_localdata->mover.RegisterPlaceable(&newPlatf.platform);
|
|
||||||
// newPlatf.ticket = ticket;
|
|
||||||
//}
|
//}
|
||||||
|
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.Add(newPos, platfWH, &m_localdata->texture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void PlatformSystem::Prepare() {
|
void PlatformSpawner::Prepare() {
|
||||||
m_localdata->texture.Reload();
|
m_localdata->texture.Reload();
|
||||||
|
|
||||||
//Spawn the initial platforms
|
//Spawn the initial platforms
|
||||||
m_localdata->platforms.clear();
|
m_localdata->platforms.clear();
|
||||||
const size_t totalPlatf = MAX_PLATFORMS_ON_SCREEN;
|
this->SpawnPlatforms();
|
||||||
//const auto totalPlatfFloatInv = 1.0f / static_cast<float>(totalPlatf);
|
|
||||||
const float2 platfWH(static_cast<float>(g_platfWidth), static_cast<float>(g_platfHeight));
|
|
||||||
float prevPlatf = 0.0f;
|
|
||||||
const float averageTarget = m_localdata->maxDistance / 5.25f; //TODO: change this value to make up for the difficulty
|
|
||||||
for (size_t z = 0; z < totalPlatf; ++z) {
|
|
||||||
const auto newPos(PositionForNewPlatf(prevPlatf, averageTarget, m_localdata->maxDistance, totalPlatf - z));
|
|
||||||
prevPlatf = newPos.y();
|
|
||||||
|
|
||||||
m_localdata->platforms.push_back(Platform(m_localdata->sdlmain, newPos, &m_localdata->texture, platfWH));
|
|
||||||
|
|
||||||
if (static_cast<float>(REFERENCE_HEIGHT) - newPos.y() < averageTarget)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void PlatformSystem::Destroy() noexcept {
|
void PlatformSpawner::Destroy() noexcept {
|
||||||
m_localdata->texture.Destroy();
|
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();
|
m_localdata->platforms.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void PlatformSystem::AddDrawables() {
|
void PlatformSpawner::BeginMovement() {
|
||||||
for (size_t z = 0; z < m_localdata->platforms.size(); ++z) {
|
m_localdata->platforms.SendBeginMovement();
|
||||||
PlatformInfo& newPlatf = m_localdata->platforms[z];
|
|
||||||
m_localdata->scene->AddDrawable(newPlatf.platform.get());
|
|
||||||
newPlatf.ticket = Mover::NullTicket;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
void PlatformSystem::OnRegister (Mover& parMover, Mover::PlaceableTicketType parTicket) {
|
void PlatformSpawner::AddOffset (const float2& parOffset) noexcept {
|
||||||
for (size_t z = 0; z < m_localdata->platforms.size(); ++z) {
|
m_localdata->platforms.SendAddOffset(parOffset);
|
||||||
assert(m_localdata->platforms[z].platform != nullptr);
|
|
||||||
m_localdata->platforms[z].ticket = parMover.RegisterPlaceable(m_localdata->platforms[z].platform.get(), parTicket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void PlatformSpawner::SetAbsolutePosition (const float2&) noexcept {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
void PlatformSpawner::RegisterForCollision (Collider& parCollider, Collider::GroupIDType parGroupID) {
|
||||||
|
parCollider.RegisterBarSet(parGroupID, &m_localdata->platforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
const DrawableSet* PlatformSpawner::GetDrawableSet() const {
|
||||||
|
return &m_localdata->platforms;
|
||||||
}
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
|
@ -20,33 +20,40 @@
|
||||||
#ifndef id17908979556C47F8A978688BBE4A9D22
|
#ifndef id17908979556C47F8A978688BBE4A9D22
|
||||||
|
|
||||||
#include "placeable.hpp"
|
#include "placeable.hpp"
|
||||||
|
#include "collidertypedef.hpp"
|
||||||
|
#include "collider.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class SDLMain;
|
class SDLMain;
|
||||||
class GameplayScene;
|
class GameplayScene;
|
||||||
|
class DrawableSet;
|
||||||
|
|
||||||
class PlatformSystem : public Placeable {
|
class PlatformSpawner : public Placeable {
|
||||||
public:
|
public:
|
||||||
PlatformSystem ( void ) = delete;
|
PlatformSpawner ( void ) = delete;
|
||||||
PlatformSystem ( const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance );
|
PlatformSpawner ( const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance );
|
||||||
PlatformSystem ( const PlatformSystem& ) = delete;
|
PlatformSpawner ( const PlatformSpawner& ) = delete;
|
||||||
PlatformSystem ( PlatformSystem&& parOther ) = delete;
|
PlatformSpawner ( PlatformSpawner&& parOther ) = delete;
|
||||||
~PlatformSystem ( void ) noexcept;
|
virtual ~PlatformSpawner ( void ) noexcept;
|
||||||
PlatformSystem& operator= ( const PlatformSystem& ) = delete;
|
PlatformSpawner& operator= ( const PlatformSpawner& ) = delete;
|
||||||
|
|
||||||
void Prepare ( void );
|
void Prepare ( void );
|
||||||
void AddDrawables ( void );
|
|
||||||
void Destroy ( void ) noexcept;
|
void Destroy ( void ) noexcept;
|
||||||
void SpawnPlatforms ( void );
|
void SpawnPlatforms ( void );
|
||||||
|
void RegisterForCollision ( Collider& parCollider, Collider::GroupIDType parGroupID );
|
||||||
//Overrides
|
const DrawableSet* GetDrawableSet ( void ) const;
|
||||||
virtual void OnRegister ( Mover& parOut, Mover::PlaceableTicketType parTicket );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LocalData;
|
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;
|
const std::unique_ptr<LocalData> m_localdata;
|
||||||
|
float m_targetAverage;
|
||||||
};
|
};
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -24,14 +24,63 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <ciso646>
|
||||||
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#if defined(RASPBERRY_PI)
|
||||||
|
#include <bcm_host.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
|
namespace {
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------
|
||||||
|
std::pair<int, std::string> GetRenderingDriver() {
|
||||||
|
typedef std::pair<int, std::string> RetPairType;
|
||||||
|
|
||||||
|
const int count = SDL_GetNumRenderDrivers();
|
||||||
|
int opengles = -1;
|
||||||
|
int opengles2 = -1;
|
||||||
|
int opengl = -1;
|
||||||
|
SDL_RendererInfo info;
|
||||||
|
for (int z = 0; z < count; ++z) {
|
||||||
|
const int ret = SDL_GetRenderDriverInfo(z, &info);
|
||||||
|
if (0 == ret) {
|
||||||
|
if (std::strcmp("opengles", info.name) == 0)
|
||||||
|
opengles = z;
|
||||||
|
else if (std::strcmp("opengles2", info.name) == 0)
|
||||||
|
opengles2 = z;
|
||||||
|
else if (std::strcmp("opengl", info.name) == 0)
|
||||||
|
opengl = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if !defined(FORCE_OPENGLES)
|
||||||
|
if (opengl > -1)
|
||||||
|
return RetPairType(opengl, "opengl");
|
||||||
|
#endif
|
||||||
|
if (opengles2 > -1)
|
||||||
|
return RetPairType(opengles2, "opengles2");
|
||||||
|
if (opengles > -1)
|
||||||
|
return RetPairType(opengles, "opengles");
|
||||||
|
#if defined(FORCE_OPENGLES)
|
||||||
|
if (opengl > -1)
|
||||||
|
return RetPairType(opengl, "opengl");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RetPairType(-1, "default");
|
||||||
|
}
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
struct SDLMain::LocalData {
|
struct SDLMain::LocalData {
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
SizeRatio sizeratio;
|
SizeRatio sizeratio;
|
||||||
ObserversManager<SizeNotifiableBase*> resChangeNotifList;
|
ObserversManager<SizeNotifiableBase*> resChangeNotifList;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
#if defined(RASPBERRY_PI)
|
||||||
|
bool bcmInitialized;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
|
@ -41,12 +90,19 @@ namespace cloonel {
|
||||||
m_localData(new LocalData)
|
m_localData(new LocalData)
|
||||||
{
|
{
|
||||||
m_localData->sizeratio.SetOriginal(static_cast<float2>(parReferenceRes), static_cast<float2>(parRes));
|
m_localData->sizeratio.SetOriginal(static_cast<float2>(parReferenceRes), static_cast<float2>(parRes));
|
||||||
|
m_localData->initialized = false;
|
||||||
|
#if defined(RASPBERRY_PI)
|
||||||
|
m_localData->bcmInitialized = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
SDLMain::~SDLMain() noexcept {
|
SDLMain::~SDLMain() noexcept {
|
||||||
ClearIFN(*m_localData);
|
ClearIFN(*m_localData);
|
||||||
|
#if defined(RASPBERRY_PI)
|
||||||
|
assert(not m_localData->bcmInitialized);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
|
@ -59,6 +115,12 @@ namespace cloonel {
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
void SDLMain::InitSDL (LocalData& parInitSDL) {
|
void SDLMain::InitSDL (LocalData& parInitSDL) {
|
||||||
|
#if defined(RASPBERRY_PI)
|
||||||
|
assert(not parInitSDL.bcmInitialized);
|
||||||
|
bcm_host_init();
|
||||||
|
parInitSDL.bcmInitialized = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
parInitSDL.window = nullptr;
|
parInitSDL.window = nullptr;
|
||||||
parInitSDL.renderer = nullptr;
|
parInitSDL.renderer = nullptr;
|
||||||
parInitSDL.initialized = false;
|
parInitSDL.initialized = false;
|
||||||
|
@ -67,13 +129,19 @@ namespace cloonel {
|
||||||
throw std::runtime_error(SDL_GetError());
|
throw std::runtime_error(SDL_GetError());
|
||||||
parInitSDL.initialized = true;
|
parInitSDL.initialized = true;
|
||||||
|
|
||||||
|
#if defined(FORCE_OPENGLES)
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
|
#endif
|
||||||
|
|
||||||
const float2 wh(m_localData->sizeratio.Resolution());
|
const float2 wh(m_localData->sizeratio.Resolution());
|
||||||
SDL_Window* const win = SDL_CreateWindow(m_gameName.c_str(), 100, 100, static_cast<int>(wh.x()), static_cast<int>(wh.y()), SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
SDL_Window* const win = SDL_CreateWindow(m_gameName.c_str(), 100, 100, static_cast<int>(wh.x()), static_cast<int>(wh.y()), SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||||
if (!win)
|
if (!win)
|
||||||
throw std::runtime_error(SDL_GetError());
|
throw std::runtime_error(SDL_GetError());
|
||||||
parInitSDL.window = win;
|
parInitSDL.window = win;
|
||||||
|
|
||||||
SDL_Renderer* const renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
const auto rendererDriver = GetRenderingDriver();
|
||||||
|
m_rendererName = rendererDriver.second;
|
||||||
|
SDL_Renderer* const renderer = SDL_CreateRenderer(win, rendererDriver.first, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
if (!renderer)
|
if (!renderer)
|
||||||
throw std::runtime_error(SDL_GetError());
|
throw std::runtime_error(SDL_GetError());
|
||||||
parInitSDL.renderer = renderer;
|
parInitSDL.renderer = renderer;
|
||||||
|
@ -86,9 +154,17 @@ namespace cloonel {
|
||||||
SDL_DestroyRenderer(parInitSDL.renderer);
|
SDL_DestroyRenderer(parInitSDL.renderer);
|
||||||
if (parInitSDL.window)
|
if (parInitSDL.window)
|
||||||
SDL_DestroyWindow(parInitSDL.window);
|
SDL_DestroyWindow(parInitSDL.window);
|
||||||
if (parInitSDL.initialized)
|
if (parInitSDL.initialized) {
|
||||||
|
parInitSDL.initialized = false;
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
#if defined(RASPBERRY_PI)
|
||||||
|
if (parInitSDL.bcmInitialized) {
|
||||||
|
parInitSDL.bcmInitialized = false;
|
||||||
|
bcm_host_deinit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
///------------------------------------------------------------------------
|
///------------------------------------------------------------------------
|
||||||
|
@ -151,4 +227,10 @@ namespace cloonel {
|
||||||
ushort2 SDLMain::WidthHeight() const noexcept {
|
ushort2 SDLMain::WidthHeight() const noexcept {
|
||||||
return static_cast<ushort2>(m_localData->sizeratio.Resolution());
|
return static_cast<ushort2>(m_localData->sizeratio.Resolution());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///------------------------------------------------------------------------
|
||||||
|
///------------------------------------------------------------------------
|
||||||
|
std::string SDLMain::GetVideoDriverName() const {
|
||||||
|
return std::string(SDL_GetCurrentVideoDriver());
|
||||||
|
}
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -42,6 +42,8 @@ namespace cloonel {
|
||||||
size_t RegisterForResChange ( SizeNotifiableBase* parNotif );
|
size_t RegisterForResChange ( SizeNotifiableBase* parNotif );
|
||||||
void UnregisterForResChange ( size_t parID ) noexcept;
|
void UnregisterForResChange ( size_t parID ) noexcept;
|
||||||
void SwapRegisteredForResChange ( size_t parID, SizeNotifiableBase* parNotif );
|
void SwapRegisteredForResChange ( size_t parID, SizeNotifiableBase* parNotif );
|
||||||
|
const std::string& GetRendererName ( void ) const { return m_rendererName; }
|
||||||
|
std::string GetVideoDriverName ( void ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LocalData;
|
struct LocalData;
|
||||||
|
@ -50,6 +52,7 @@ namespace cloonel {
|
||||||
void ClearIFN ( LocalData& parData ) noexcept;
|
void ClearIFN ( LocalData& parData ) noexcept;
|
||||||
|
|
||||||
const std::string m_gameName;
|
const std::string m_gameName;
|
||||||
|
std::string m_rendererName;
|
||||||
std::unique_ptr<LocalData> m_localData;
|
std::unique_ptr<LocalData> m_localData;
|
||||||
};
|
};
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
|
@ -22,20 +22,25 @@
|
||||||
|
|
||||||
#include "drawable.hpp"
|
#include "drawable.hpp"
|
||||||
#include "sizenotifiable.hpp"
|
#include "sizenotifiable.hpp"
|
||||||
|
#include "drawableset.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class Texture;
|
class Texture;
|
||||||
class SDLMain;
|
class SDLMain;
|
||||||
|
|
||||||
class TiledWallpaper : public Drawable {
|
class TiledWallpaper : public Drawable, public DrawableSet {
|
||||||
public:
|
public:
|
||||||
TiledWallpaper ( const std::string&& parPath, SDLMain* parMain );
|
TiledWallpaper ( const std::string&& parPath, SDLMain* parMain );
|
||||||
virtual ~TiledWallpaper ( void ) noexcept;
|
virtual ~TiledWallpaper ( void ) noexcept;
|
||||||
|
|
||||||
void Reload ( void );
|
void Reload ( void );
|
||||||
void Destroy ( void ) noexcept;
|
void Destroy ( void ) noexcept;
|
||||||
|
|
||||||
|
//Overrides
|
||||||
virtual void Draw ( void ) const;
|
virtual void Draw ( void ) const;
|
||||||
|
virtual void CopyDrawables ( std::vector<const Drawable*>& parOut ) const { parOut.push_back(this); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class TileCountNotifiable : public SizeNotifiable<regbehaviours::AutoRegister> {
|
class TileCountNotifiable : public SizeNotifiable<regbehaviours::AutoRegister> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue