Você certamente deve implementar algum tipo de tipo de superfície. Pense nisso, como você vai conseguir se consegue subir uma escada se não sabe se seu personagem acabou de colidir com uma parede ou uma escada? Você pode simplesmente usar o OOP para gerenciar uma hierarquia de tipos usando herança, mas eu sugiro que você use "categorias" implementadas usando um tipo enumerado:
Aqui está a idéia: Uma enumeração "Colisões" possui um sinalizador para cada categoria. Por exemplo:
namespace Collisions
{
enum Type
{
None = 0,
Floor = 1 << 0,
Ladder = 1 << 1,
Enemy = 1 << 2,
... // And whatever else you need.
// Then, you can construct named groups of flags.
Player = Floor | Ladder | Enemy
};
}
Com esse método, você poderá testar se o jogador justificou alguma coisa que deveria gerenciar, para que seu mecanismo possa chamar um método "colidido" da entidade:
void Player::Collided( Collisions::Type group )
{
if ( group & Collisions::Ladder )
{
// Manage Ladder Collision
}
if ( group & Collisions::Floor )
{
// Manage Floor Collision
}
if ( group & Collisions::Enemy )
{
// Manage Enemy Collision
}
}
O método usa sinalizadores bit a bit e o operador "Or" bit a bit para garantir que cada grupo tenha um valor diferente, com base no valor binário da categoria. Esse método funciona bem e é facilmente escalável para que você possa criar grupos de colisão alfandegária. Cada entidade (jogador, inimigo, etc.) do seu jogo possui alguns bits chamados de "filtro", que são usados para determinar com o que ela pode colidir. Seu código de colisão deve verificar se os bits correspondem e reagem de acordo, com algum código que pode se parecer com:
void PhysicEngine::OnCollision(...)
{
mPhysics.AddContact( body1, body1.GetFilter(), body2, body2.GetFilter() );
}