diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c63dd0..2993504 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,11 +58,13 @@ add_executable(${PROJECT_NAME} src/drawable.cpp src/sizeratio.cpp src/sizenotifiable.cpp + src/horzcollisionbar.cpp src/platform.cpp src/vectormath.cpp src/platformsystem.cpp src/movers/moverworld.cpp src/line.cpp + src/collider.cpp ) target_link_libraries(${PROJECT_NAME} diff --git a/src/collider.cpp b/src/collider.cpp new file mode 100644 index 0000000..1a446b7 --- /dev/null +++ b/src/collider.cpp @@ -0,0 +1,59 @@ +/* + Copyright 2014 Michele "King_DuckZ" Santullo + + This file is part of CloonelJump. + + CloonelJump is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CloonelJump is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CloonelJump. If not, see . +*/ + +#include "collider.hpp" +#include +#include +#include +#include + +#if defined(WITH_VERBOSE_COLLIDER) && !defined(NDEBUG) +#define VERBOSE_COLLIDER +#include +#endif + +namespace cloonel { + namespace { + } //unnamed namespace + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + Collider::Collider() { + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + Collider::~Collider() noexcept { + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void Collider::RunCollisionTests() { +#if defined(VERBOSE_COLLIDER) + std::cout << "Collider::RunCollisionTests() starting\n"; +#endif +#if defined(VERBOSE_COLLIDER) + std::cout << "Collider::RunCollisionTests() done\n"; +#endif + } +} //namespace cloonel + +#if defined(VERBOSE_COLLIDER) +#undef VERBOSE_COLLIDER +#endif diff --git a/src/collider.hpp b/src/collider.hpp new file mode 100644 index 0000000..a43bcff --- /dev/null +++ b/src/collider.hpp @@ -0,0 +1,40 @@ +/* + 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 id7E6024372BF34999A913A36B6EAB736B +#define id7E6024372BF34999A913A36B6EAB736B + +#include "observersmanager.hpp" +#include + +namespace cloonel { + class HorzCollisionBar; + + class Collider { + public: + Collider ( void ); + ~Collider ( void ) noexcept; + + void RunCollisionTests ( void ); + + private: + }; +} //namespace cloonel + +#endif diff --git a/src/gameplayscene.cpp b/src/gameplayscene.cpp index 0b97ea8..9826819 100644 --- a/src/gameplayscene.cpp +++ b/src/gameplayscene.cpp @@ -35,6 +35,7 @@ namespace cloonel { for (auto itMover : m_movers) { itMover->Update(parDelta); } + m_collider.RunCollisionTests(); } ///-------------------------------------------------------------------------- @@ -44,4 +45,14 @@ namespace cloonel { itDrawable->Draw(); } } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void GameplayScene::Destroy() noexcept { + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void GameplayScene::OnPrepareDone() { + } } //namespace cloonel diff --git a/src/gameplayscene.hpp b/src/gameplayscene.hpp index df4d550..bbc2b3e 100644 --- a/src/gameplayscene.hpp +++ b/src/gameplayscene.hpp @@ -23,6 +23,7 @@ #include #include #include "gamebase.hpp" +#include "collider.hpp" namespace cloonel { class Mover; @@ -39,10 +40,14 @@ namespace cloonel { virtual void Destroy ( void ) noexcept; protected: + Collider* GetCollider ( void ); + private: virtual void OnRender ( void ); virtual void OnUpdate ( float parDelta ); + virtual void OnPrepareDone ( void ); + Collider m_collider; std::vector m_movers; std::vector m_drawables; }; diff --git a/src/horzcollisionbar.cpp b/src/horzcollisionbar.cpp new file mode 100644 index 0000000..04f9bf8 --- /dev/null +++ b/src/horzcollisionbar.cpp @@ -0,0 +1,117 @@ +/* + Copyright 2014 Michele "King_DuckZ" Santullo + + This file is part of CloonelJump. + + CloonelJump is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CloonelJump is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CloonelJump. If not, see . +*/ + +#include "horzcollisionbar.hpp" +#include "line_helpers.hpp" +#include "maths.hpp" +#include +#include +#include + +namespace cloonel { + namespace { + typedef Line Line2D; + + float calculateOverlappingTime ( float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB ) __attribute__((pure)); + void DoNothing ( void ) __attribute__((pure)); + std::pair getOverlap ( float parDeltaT, const Line2D& parA, const Line2D& parB, const float2& parDeltaA, const float2& parDeltaB ) __attribute__((pure)); + + ///---------------------------------------------------------------------- + ///Calculate the time t at which the two segments (which are assumed to + ///be horizontal) will lie on the same line. parDeltaT is the duration + ///of the time frame being considered, parAY and parBY are the starting + ///y position of the two segments, parDeltaA and parDeltaB are the + ///distance traveled by segment A and segment B respectively in the + ///reference time frame. + ///---------------------------------------------------------------------- + float calculateOverlappingTime (float parDeltaT, float parAY, float parBY, float parDeltaA, float parDeltaB) { + const float deltaDiff = std::max(parDeltaA, parDeltaB) - std::min(parDeltaA, parDeltaB); + assert(deltaDiff >= 0.0f); + + if (deltaDiff <= 0.00001f) + return 0.0f; + else + return (parDeltaT * (parBY - parAY)) / (parDeltaA - parDeltaB); + } + + ///---------------------------------------------------------------------- + ///---------------------------------------------------------------------- + std::pair getOverlap (float parDeltaT, const Line2D& parA, const Line2D& parB, const float2& parDeltaA, const float2& parDeltaB) { + assert(parDeltaT > 0.0f); + const float overlapTime = calculateOverlappingTime(parDeltaT, parA.Start().y(), parB.Start().y(), parDeltaA.y(), parDeltaB.y()); + if (overlapTime < 0.0f or overlapTime > parDeltaT) + return std::make_pair(false, Line2D()); + + assert(overlapTime <= parDeltaT); + const auto midpointA(LerpRange(parA, parDeltaA, overlapTime / parDeltaT)); + const auto midpointB(LerpRange(parB, parDeltaB, overlapTime / parDeltaT)); + + if (midpointA.Start().x() >= midpointB.End().x() or midpointB.Start().x() >= midpointA.End().x()) + return std::make_pair(false, Line2D()); + + 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()); + return std::make_pair(true, Line2D(retStart, retEnd)); + } + + ///---------------------------------------------------------------------- + ///no-op + ///---------------------------------------------------------------------- + void DoNothing() { + } + } //unnamed namespace + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + HorzCollisionBar::HorzCollisionBar (const float2& parFrom, float parLength) : + Placeable(parFrom), + m_segment(parFrom, float2(1.0f, 0.0f), parLength), + m_callback(&DoNothing) + { + assert(parLength != 0.0f); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + void HorzCollisionBar::SetCallback (std::function parCallback) { + m_callback = parCallback; + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + float2 HorzCollisionBar::To() const { + return this->GetPos() + len(m_segment); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + bool Collide (float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line& parOut) { + const auto offsetA = parA.GetPos() - parA.m_segment.Start(); + const auto offsetB = parB.GetPos() - parB.m_segment.Start(); + const auto overlap(getOverlap(parDeltaT, parA.m_segment, parB.m_segment, offsetA, offsetB)); + + if (overlap.first) { + parOut = overlap.second; + return true; + } + else { + return false; + } + } +} //namespace cloonel diff --git a/src/horzcollisionbar.hpp b/src/horzcollisionbar.hpp new file mode 100644 index 0000000..88c13c5 --- /dev/null +++ b/src/horzcollisionbar.hpp @@ -0,0 +1,50 @@ +/* + 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 id202E39A912AA43E5A224AC77D676F6CA +#define id202E39A912AA43E5A224AC77D676F6CA + +#include "vector.hpp" +#include "placeable.hpp" +#include "line.hpp" +#include + +namespace cloonel { + class HorzCollisionBar; + + class HorzCollisionBar : public Placeable { + friend bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line& parOut ); + public: + HorzCollisionBar ( const float2& parFrom, float parLength ); + ~HorzCollisionBar ( void ) noexcept = default; + + float2 From ( void ) const { return this->GetPos(); } + float2 To ( void ) const; + + void SetCallback ( std::function parCallback ); + + private: + Line m_segment; + std::function m_callback; + }; + + bool Collide ( float parDeltaT, const HorzCollisionBar& parA, const HorzCollisionBar& parB, Line& parOut ) __attribute__((pure)); +} //namespace cloonel + +#endif diff --git a/src/line.hpp b/src/line.hpp index e8e1559..d0b37fd 100644 --- a/src/line.hpp +++ b/src/line.hpp @@ -30,7 +30,7 @@ namespace cloonel { typedef Vector Point; typedef T Scalar; - Line ( void ) = default; + Line ( void ) {} Line ( const Line& parOther ); Line ( const Point& parStart, const Point& parEnd ); Line ( const Point& parStart, const Point& parDirection, Scalar parLength ) : Line(parStart, parDirection * parLength) { } diff --git a/src/maths.hpp b/src/maths.hpp new file mode 100644 index 0000000..703a4d5 --- /dev/null +++ b/src/maths.hpp @@ -0,0 +1,45 @@ +/* + 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 id44C452F5B87A4993B127EFE654837C7D +#define id44C452F5B87A4993B127EFE654837C7D + +namespace cloonel { + template + T Lerp ( const T& parStart, const T& parEnd, const U& parPercent ) __attribute__((pure)); + template + T LerpRange ( const T& parStart, const R& parRange, const U& parPercent ) __attribute__((pure)); + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + T Lerp (const T& parStart, const T& parEnd, const U& parPercent) { + return parStart + parPercent * (parEnd - parStart); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + T LerpRange (const T& parStart, const R& parRange, const U& parPercent) { + return parStart + parPercent * parRange; + } +} //namespace cloonel + +#endif