diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2993504..d7aa40b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ include(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
find_package(PNG REQUIRED)
-find_package(Boost 1.35.0 REQUIRED)
+find_package(Boost 1.55.0 REQUIRED)
add_definitions(
${PNG_DEFINITIONS}
diff --git a/src/CloonelJumpConfig.h.in b/src/CloonelJumpConfig.h.in
index f753f1e..e563dec 100644
--- a/src/CloonelJumpConfig.h.in
+++ b/src/CloonelJumpConfig.h.in
@@ -29,7 +29,7 @@
#define DEF_WIN_WIDTH REFERENCE_WIDTH
#define DEF_WIN_HEIGHT REFERENCE_HEIGHT
#define DEF_RANDOM_SEED 1984
-#define MAX_PLATFORMS_ON_SCREEN 8
+#define MAX_PLATFORMS_ON_SCREEN 24
/* TODO: make this path relative */
#define GAME_BASE_PATH "@CMAKE_SOURCE_DIR@"
diff --git a/src/circularbuffer.hpp b/src/circularbuffer.hpp
deleted file mode 100644
index b808b37..0000000
--- a/src/circularbuffer.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- Copyright 2014 Michele "King_DuckZ" Santullo
-
- This file is part of CloonelJump.
-
- CloonelJump is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- CloonelJump is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with CloonelJump. If not, see .
-
-*/
-
-#ifndef idF67A018826604CAFBE25BCA939A1FBC9
-#define idF67A018826604CAFBE25BCA939A1FBC9
-
-#include
-#include
-#include
-#include
-
-namespace cloonel {
- template
- class CircularBuffer : public boost::noncopyable {
- public:
- typedef size_t size_type;
- typedef typename std::iterator_traits::value_type value_type;
- typedef typename std::iterator_traits::reference reference;
-
- CircularBuffer ( Iterator parFirst, Iterator parLast );
- CircularBuffer ( CircularBuffer&& parOther );
- ~CircularBuffer ( void ) noexcept = default;
- CircularBuffer& operator= ( CircularBuffer&& parOther );
-
- reference operator[] ( size_type parIndex );
-
- size_type size ( void ) const { return (m_used >= capacity() ? capacity() : m_used); }
- bool empty ( void ) const { return 0 == m_used; }
- size_type capacity ( void ) const { return m_end - m_start; }
- void push ( value_type&& parObj );
- void reset ( void );
- void reset ( Iterator parFirst, Iterator parLast );
- reference front ( void );
- reference back ( void );
-
- private:
- Iterator m_start;
- Iterator m_end;
- Iterator m_curr;
- size_type m_used;
- };
-} //namespace cloonel
-
-#include "circularbuffer.inl"
-
-#endif
diff --git a/src/circularbuffer.inl b/src/circularbuffer.inl
deleted file mode 100644
index c03c262..0000000
--- a/src/circularbuffer.inl
+++ /dev/null
@@ -1,68 +0,0 @@
-namespace cloonel {
- template
- CircularBuffer::CircularBuffer (Iterator parFirst, Iterator parLast) :
- m_start(parFirst),
- m_end(parLast),
- m_curr(parFirst),
- m_used(0)
- {
- }
-
- template
- void CircularBuffer::push (value_type&& parObj) {
- *m_curr = std::move(parObj);
- ++m_curr;
- ++m_used;
- if (m_curr == m_end) {
- m_curr = m_start;
- m_used = capacity();
- }
- }
-
- template
- void CircularBuffer::reset() {
- m_used = 0;
- m_curr = m_start;
- }
-
- template
- void CircularBuffer::reset (Iterator parFirst, Iterator parLast) {
- m_start = parFirst;
- m_end = parLast;
- reset();
- }
-
- template
- typename CircularBuffer::reference CircularBuffer::front() {
- if (empty())
- throw std::out_of_range("The circular buffer is empty, but front() was called.");
- if (m_curr == m_start)
- return *(m_start + (capacity() - 1));
- else
- return *(m_curr - 1);
- }
-
- template
- typename CircularBuffer::reference CircularBuffer::back() {
- if (empty())
- throw std::out_of_range("The circular buffer is empty, but back() was called.");
- const auto cap = capacity();
- if (m_used != cap) {
- return *m_start;
- }
- else {
- const auto currPos = m_curr - m_start;
- const auto index = (currPos + cap - 1) % cap;
- return *(m_start + index);
- }
- }
-
- template
- typename CircularBuffer::reference CircularBuffer::operator[] (size_type parIndex) {
- if (parIndex < 0 or parIndex >= size())
- throw std::out_of_range("Index out of range in CircularBuffer");
-
- const auto index = (m_curr - m_start + parIndex) % capacity();
- return *(m_start + index);
- }
-} //namespace cloonel
diff --git a/src/platformsystem.cpp b/src/platformsystem.cpp
index c130d3a..f8c07a8 100644
--- a/src/platformsystem.cpp
+++ b/src/platformsystem.cpp
@@ -23,17 +23,38 @@
#include "texture.hpp"
#include "gameplayscene.hpp"
#include "mover.hpp"
-#include "circularbuffer.hpp"
#include
#include
#include
#include
#include
+#include
namespace cloonel {
namespace {
const uint32_t g_platfWidth = 104;
const uint32_t g_platfHeight = 25;
+
+ float2 PositionForNewPlatf (float parStart, float parAverage, float parMaxDist, size_t parLeft) {
+ assert(parAverage >= 0.0f);
+ const float& maxDist = parMaxDist;
+ const float minDist = std::max(static_cast(g_platfHeight), (static_cast(REFERENCE_HEIGHT) - parStart) / static_cast(parLeft));
+ assert(minDist <= maxDist); //make sure the player can jump all the way to the top
+ assert(minDist <= parAverage); //that would screw up the player
+
+ const float upperRange = std::max(parAverage, maxDist) - parAverage;
+ const float lowerRange = std::max(parAverage, minDist) - minDist;
+ assert(upperRange >= 0.0f);
+ assert(lowerRange >= 0.0f);
+
+ const float invRandMax = 1.0f / static_cast(RAND_MAX);
+ const float yDist = static_cast(std::rand()) * invRandMax * (lowerRange + upperRange - minDist) + minDist;
+ assert(yDist >= minDist and yDist <= maxDist);
+
+ const auto rndNum = std::rand() % (REFERENCE_WIDTH - g_platfWidth);
+
+ return float2(static_cast(rndNum), yDist + parStart);
+ }
} //unnamed namespace
struct PlatformInfo {
@@ -69,8 +90,7 @@ namespace cloonel {
LocalData ( const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance );
~LocalData ( void ) noexcept = default;
- std::vector platformsBuff;
- CircularBuffer::iterator> platforms;
+ boost::circular_buffer platforms;
Texture texture;
SDLMain* const sdlmain;
GameplayScene* const scene;
@@ -80,8 +100,7 @@ namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
PlatformSystem::LocalData::LocalData (const char* parTexturePath, SDLMain* parSDLMain, GameplayScene* parScene, float parMaxDistance) :
- platformsBuff(MAX_PLATFORMS_ON_SCREEN),
- platforms(platformsBuff.begin(), platformsBuff.end()),
+ platforms(MAX_PLATFORMS_ON_SCREEN),
texture(parTexturePath, parSDLMain, false),
sdlmain(parSDLMain),
scene(parScene),
@@ -129,18 +148,20 @@ namespace cloonel {
m_localdata->texture.Reload();
//Spawn the initial platforms
- m_localdata->platforms.reset();
- const size_t totalPlatf = m_localdata->platforms.capacity();
- const auto totalPlatfFloatInv = 1.0f / static_cast(totalPlatf);
+ m_localdata->platforms.clear();
+ const size_t totalPlatf = MAX_PLATFORMS_ON_SCREEN;
+ //const auto totalPlatfFloatInv = 1.0f / static_cast(totalPlatf);
const int2 platfWH(g_platfWidth, g_platfHeight);
+ float prevPlatf = 0.0f;
+ const float averageTarget = m_localdata->maxDistance / 8.0f; //TODO: change this value to make up for the difficulty
for (size_t z = 0; z < totalPlatf; ++z) {
- const float y = std::min(
- static_cast(REFERENCE_HEIGHT) - 25.0f,
- static_cast(z) * (static_cast(REFERENCE_HEIGHT) * totalPlatfFloatInv)
- );
- const auto rndNum = std::rand() % (REFERENCE_WIDTH - platfWH.x());
- const float2 newPos(static_cast(rndNum), 100.0f + std::min(m_localdata->maxDistance, y));
- m_localdata->platforms.push(Platform(m_localdata->sdlmain, newPos, &m_localdata->texture, static_cast(platfWH)));
+ 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, static_cast(platfWH)));
+
+ if (static_cast(REFERENCE_HEIGHT) - newPos.y() < averageTarget)
+ break;
}
}
@@ -149,11 +170,7 @@ namespace cloonel {
void PlatformSystem::Destroy() noexcept {
m_localdata->texture.Destroy();
- for (size_t z = 0; z < m_localdata->platforms.size(); ++z) {
- m_localdata->mover.UnregisterPlaceable(m_localdata->platforms[z].ticket);
- }
- m_localdata->platforms.reset();
- m_localdata->platformsBuff.clear();
+ m_localdata->platforms.clear();
}
///--------------------------------------------------------------------------
@@ -170,6 +187,7 @@ namespace cloonel {
///--------------------------------------------------------------------------
void PlatformSystem::OnRegister (Mover& parMover, Mover::PlaceableTicketType parTicket) {
for (size_t z = 0; z < m_localdata->platforms.size(); ++z) {
+ assert(m_localdata->platforms[z].platform != nullptr);
m_localdata->platforms[z].ticket = parMover.RegisterPlaceable(m_localdata->platforms[z].platform.get(), parTicket);
}
}