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); } }