Add code to register objects to the collider.

The character and the platforms can register now, but
collision is not triggered for some reason.
This commit is contained in:
King_DuckZ 2014-08-01 00:50:49 +02:00
parent 42fb50e93e
commit cdd37fead7
13 changed files with 133 additions and 10 deletions

View file

@ -14,6 +14,7 @@ find_package(Boost 1.55.0 REQUIRED)
add_definitions( add_definitions(
${PNG_DEFINITIONS} ${PNG_DEFINITIONS}
-DWITH_VERBOSE_OBS_MANAGER -DWITH_VERBOSE_OBS_MANAGER
-DWITH_VERBOSE_COLLIDER
) )
include_directories(SYSTEM include_directories(SYSTEM

View file

@ -20,6 +20,7 @@
#include "character.hpp" #include "character.hpp"
#include "sdlmain.hpp" #include "sdlmain.hpp"
#include "texture.hpp" #include "texture.hpp"
#include "collider.hpp"
#include <cassert> #include <cassert>
namespace cloonel { namespace cloonel {
@ -52,6 +53,12 @@ namespace cloonel {
Character::~Character() noexcept { Character::~Character() noexcept {
} }
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
void Character::RegisterForCollision (ColliderRegisterFunc parRegisterCollision) {
parRegisterCollision(&m_bottomBar);
}
///------------------------------------------------------------------------- ///-------------------------------------------------------------------------
///------------------------------------------------------------------------- ///-------------------------------------------------------------------------
void Character::Prepare() { void Character::Prepare() {

View file

@ -25,6 +25,7 @@
#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>
@ -35,12 +36,13 @@ namespace cloonel {
class Character : public Placeable, public Drawable { class Character : public Placeable, public Drawable {
public: public:
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 );
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 );
private: private:
HorzCollisionBar m_bottomBar; HorzCollisionBar m_bottomBar;

View file

@ -85,7 +85,7 @@ namespace cloonel {
if (Collide(parDeltaT, *bar1, *bar2, overlap)) { if (Collide(parDeltaT, *bar1, *bar2, overlap)) {
#if defined(VERBOSE_COLLIDER) #if defined(VERBOSE_COLLIDER)
std::cout << "Collider: Collision while testing group " << parGroup1 << " and " << parGroup2 << " "; std::cout << "Collider: Collision ";
std::cout << "between " << bar1 << " and " << bar2 << "\n"; std::cout << "between " << bar1 << " and " << bar2 << "\n";
#endif #endif
const auto dir1 = normalized(bar1->GetPos() - bar1->From()); const auto dir1 = normalized(bar1->GetPos() - bar1->From());
@ -122,6 +122,9 @@ namespace cloonel {
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
void Collider::TieGroups (GroupIDType parGroup1, GroupIDType parGroup2) { 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(parGroup1, parGroup2)));
assert(m_relationships.end() == std::find(m_relationships.begin(), m_relationships.end(), std::make_pair(parGroup2, parGroup1))); assert(m_relationships.end() == std::find(m_relationships.begin(), m_relationships.end(), std::make_pair(parGroup2, parGroup1)));
assert(isGroupRegistered(m_collisionBars, parGroup1)); assert(isGroupRegistered(m_collisionBars, parGroup1));
@ -132,11 +135,31 @@ namespace cloonel {
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
void Collider::RegisterBar (GroupIDType parGroup, const CollisionBar* parBar) { 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); CollisionBarListType& group = findOrAddGroup(m_collisionBars, parGroup);
assert(isGroupRegistered(m_collisionBars, parGroup)); assert(isGroupRegistered(m_collisionBars, parGroup));
assert(parBar); assert(parBar);
group.push_back(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();
}
} //namespace cloonel } //namespace cloonel
#if defined(VERBOSE_COLLIDER) #if defined(VERBOSE_COLLIDER)

View file

@ -40,6 +40,8 @@ namespace cloonel {
void RunCollisionTests ( float parDeltaT ) const; void RunCollisionTests ( float parDeltaT ) const;
void TieGroups ( GroupIDType parGroup1, GroupIDType parGroup2 ); void TieGroups ( GroupIDType parGroup1, GroupIDType parGroup2 );
void RegisterBar ( GroupIDType parGroup, const CollisionBar* parBar ); void RegisterBar ( GroupIDType parGroup, const CollisionBar* parBar );
void UnregisterBar ( GroupIDType parGroup, const CollisionBar* parBar );
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 CollisionBar*>>> CollisionBarGroupListType;

32
src/collidertypedef.hpp Normal file
View 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

View file

@ -49,6 +49,7 @@ namespace cloonel {
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
void GameplayScene::Destroy() noexcept { void GameplayScene::Destroy() noexcept {
m_collider.Reset();
} }
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------

View file

@ -40,7 +40,7 @@ namespace cloonel {
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 );

View file

@ -32,6 +32,7 @@
#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,12 @@ namespace cloonel {
GameAction_Left, GameAction_Left,
GameAction_Right GameAction_Right
}; };
enum {
CollisionID_Platforms,
CollisionID_Player,
CollisionID_Enemies
};
} //unnamed namespace } //unnamed namespace
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
@ -62,6 +69,7 @@ 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();
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(), float2(80.0f, 120.0f)));
@ -80,6 +88,15 @@ 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);
auto regPlatfCollision(std::bind(&Collider::RegisterBar, &collider, CollisionID_Platforms, std::placeholders::_1));
auto unregPlatfCollision(std::bind(&Collider::UnregisterBar, &collider, CollisionID_Platforms, std::placeholders::_1));
platforms->RegisterForCollision(regPlatfCollision, unregPlatfCollision);
}
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);
@ -96,6 +113,9 @@ namespace cloonel {
const float jumpPower = halfRefHeight * 1.29f; const float jumpPower = halfRefHeight * 1.29f;
m_moverSine->SetPower(jumpPower); m_moverSine->SetPower(jumpPower);
collider.TieGroups(CollisionID_Platforms, CollisionID_Player);
//collider.TieGroups(CollisionID_Enemies, CollisionID_Player);
} }
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
@ -110,7 +130,6 @@ namespace cloonel {
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));
} }
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------

View file

@ -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,12 @@ 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);
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void Platform::RegisterForCollision (ColliderRegisterFunc parReg) {
parReg(m_collisionTop.get());
} }
} //namespace cloonel } //namespace cloonel

View file

@ -23,31 +23,37 @@
#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; }
void RegisterForCollision ( ColliderRegisterFunc parReg );
//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

View file

@ -23,6 +23,7 @@
#include "texture.hpp" #include "texture.hpp"
#include "gameplayscene.hpp" #include "gameplayscene.hpp"
#include "mover.hpp" #include "mover.hpp"
#include "collider.hpp"
#include <ciso646> #include <ciso646>
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <cassert>
@ -167,6 +168,17 @@ namespace cloonel {
} }
} }
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void PlatformSystem::RegisterForCollision (ColliderRegisterFunc parReg, ColliderUnregisterFunc parUnreg) {
m_registerToCollider = parReg;
m_unregisterFromCollider = parUnreg;
for (auto& platf : m_localdata->platforms) {
platf.platform->RegisterForCollision(m_registerToCollider);
}
}
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
void PlatformSystem::Destroy() noexcept { void PlatformSystem::Destroy() noexcept {

View file

@ -20,11 +20,13 @@
#ifndef id17908979556C47F8A978688BBE4A9D22 #ifndef id17908979556C47F8A978688BBE4A9D22
#include "placeable.hpp" #include "placeable.hpp"
#include "collidertypedef.hpp"
#include <memory> #include <memory>
namespace cloonel { namespace cloonel {
class SDLMain; class SDLMain;
class GameplayScene; class GameplayScene;
class Collider;
class PlatformSystem : public Placeable { class PlatformSystem : public Placeable {
public: public:
@ -36,6 +38,7 @@ namespace cloonel {
PlatformSystem& operator= ( const PlatformSystem& ) = delete; PlatformSystem& operator= ( const PlatformSystem& ) = delete;
void Prepare ( void ); void Prepare ( void );
void RegisterForCollision ( ColliderRegisterFunc parReg, ColliderUnregisterFunc parUnreg );
void AddDrawables ( void ); void AddDrawables ( void );
void Destroy ( void ) noexcept; void Destroy ( void ) noexcept;
void SpawnPlatforms ( void ); void SpawnPlatforms ( void );
@ -47,6 +50,8 @@ namespace cloonel {
struct LocalData; struct LocalData;
const std::unique_ptr<LocalData> m_localdata; const std::unique_ptr<LocalData> m_localdata;
ColliderRegisterFunc m_registerToCollider;
ColliderUnregisterFunc m_unregisterFromCollider;
}; };
} //namespace cloonel } //namespace cloonel