[b]Code First[/b]
[i]CCollide.h[/i]
[cpp]
#pragma once
#include <SFML/Graphics.hpp>
#include <hash_map>
namespace cf
{
class CCollide
{
private:
typedef stdext::hash_map< int, cf::CCollide > Entities;
public:
static cf::CCollide::Entities &GetList();
static void AddCollide( cf::CCollide &entity );
static bool GetCollide( cf::CCollide &self );
static bool GetCollideWith( cf::CCollide &self, cf::CCollide &entity );
protected:
int m_PosId;
sf::Rect<float> m_BBox;
};
};
[/cpp]
[i]CCollide.cpp[/i]
[cpp]
#include "CCollide.h"
cf::CCollide::Entities &cf::CCollide::GetList()
{
static cf::CCollide::Entities m_EntList;
return m_EntList;
}
void cf::CCollide::AddCollide( cf::CCollide &entity )
{
GetList()[GetList().size() + 1] = entity;
GetList()[GetList().size()].m_PosId = GetList().size();
}
bool cf::CCollide::GetCollide( cf::CCollide &self )
{
for( int i = 0; i < (signed)GetList().size(); i++ )
{
if(GetList()[i].m_BBox.Intersects( GetList()[self.m_PosId].m_BBox ))
{
if( i != self.m_PosId )
return true;
}
}
return false;
}
bool cf::CCollide::GetCollideWith( cf::CCollide &self, cf::CCollide &entity )
{
if( self.m_BBox.Intersects( entity.m_BBox ) )
return true;
else return false;
}
[/cpp]
[i]Entry.cpp (Main)[/i]
[cpp]
#include <windows.h>
#include "CWindow.h"
#include "CPlayer.h"
#include "CJukebox.h"
#include "CCollide.h"
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR CommandLine, int ShowWindow )
{
cf::CWindow Window( "Facepunch DEMO", 800, 600 );
cf::CWorld TestWorld( "Test World", 1 );
cf::CPlayer Hero, Hero2, Hero3;
while( Window.Go() )
{
Window.Catch();
Window.Begin( sf::Color( 128, 128, 255 ) );
if( !cf::CCollide::GetCollide( Hero ) )
{
Hero.Run( Window, TestWorld );
Hero2.Run( Window, TestWorld );
Hero3.Run( Window, TestWorld );
}
Window.End();
}
}
[/cpp]
Was trying to test out my collision class, when a CCPlayer is made it is automatically added to my CCollide map.
Anyways, I got this memory leak after I added this and shit, and I've no idea why. It doesn't even render a frame, or crash. Just kind of shoots up. Any Ideas.
Unless you're calling AddCollide a whole lot, the code you posted isn't accountable for any excessive memory consumption.
But you shouldn't be using a hash table for the collision entities, and you shouldn't store them by value. If every one of your CPlayer entities called AddCollide once, you'd end up with a total of 3 fully qualified CPlayer entities and 3 separate CCollide entities stored in the hash map. That means the 3 CCollide entities as CPlayer will always be compared to 3 never-changing copies.
Your collision loop will segfault once the hash map has holes, because the hash_map call to [] will return null once it encounters an inexistant key.(And instead of casting the size to a signed integer, you should've just use size_t for the iterator.)
I recommend putting your CCollide entities in a linked list. Store the first and last nodes statically in the CCollide class, and store a non-static pointer to the next and previous CCollide nodes in the CCollide class.
Also:
[cpp]
bool cf::CCollide::GetCollideWith( cf::CCollide &self, cf::CCollide &entity )
{
if( self.m_BBox.Intersects( entity.m_BBox ) ) //'if' takes a bool, which means Intersects returns a value implicitly convertible to bool
return true;
else return false;
}
//Can be written as:
bool cf::CCollide::GetCollideWith( cf::CCollide &self, cf::CCollide &entity )
{
return self.m_BBox.Intersects( entity.m_BBox ); //return this boolean directly
}[/cpp]
Mmkay, thanks.
I changed it to a list, now how would I go about comparing two cf::CCollide objects to make sure they're not the same (So that an object isn't checked if it's colliding with itself)?
[QUOTE=NorthernGate;20203767]Mmkay, thanks.
I changed it to a list, now how would I go about comparing two cf::CCollide objects to make sure they're not the same (So that an object isn't checked if it's colliding with itself)?[/QUOTE]
All you need to do is compare pointer addresses.
[QUOTE=jA_cOp;20203941]All you need to do is compare pointer addresses.[/QUOTE]
Cool.
Okay, hopefully after this final problem is solved I'll have working collision checking! woo
My (hopefully) final problem is that two objects that are colliding (say Hero, and Hero2) isn't returning that they're colliding with GetCollide( Hero ).
[i]CCollide.h::GetCollide[/i]
[cpp]
bool cf::CCollide::GetCollide( cf::CCollide &self )
{
for( int i = 0; i < (signed)GetList().size(); i++ )
{
if( &self != &GetList().front() )
{
if( self.m_BBox.Intersects( GetList().front().m_BBox ) )
{
return true;
}
else
{
GetList().push_back( GetList().front() );
GetList().pop_front();
}
}
}
return false;
}
[/cpp]
[code]&GetList().front()[/code]
What does GetList() return? If this is an STL container, then that means you're still storing the CCollide entities by value.