There is an abstract class Entity
, and other classes like Player
and Enemy
are inherit from it. When game detects a collision between the entities, the following method is called:
void handleCollision(Entity* ent1, Entity* ent2) {
if (dynamic_cast<Player*>(ent1) || dynamic_cast<Player*>(ent2) &&
dynamic_cast<Enemy*>(ent1) || dynamic_cast<Enemy*>(ent2)) {
//player <-> enemy collision
}
else if (dynamic_cast<Player*>(ent1) || dynamic_cast<Player*>(ent2) &&
dynamic_cast<Projectile*>(ent1) || dynamic_cast<Projectile*>(ent2)) {
//player <-> projectile collision
}
else if () {
//...
}
else if() {
//...
}
}
Each entity has unique behavior when colliding with another, which depends on the type of entity (Player, Enemy, etc), that's why I need to check every possible combination between entities as shown above. But I don't like the fact it creates a huge else if chain, where each entity is checked multiple times. Is there another way of doing it?
Trying to expand Ben Voigt's comment about multiple virtual dispatch, something along the lines of:
void handleCollision(Entity* ent1, Entity* ent2)
{
ent1->collide_with(ent2);
}
Where:
class Entity
{
public:
virtual void collide_with(Entity*) = 0; // Dispatcher
virtual void handle_collision_with(Entity*) {}
virtual void handle_collision_with(class Player*) {}
virtual void handle_collision_with(class Enemy*) {}
virtual void handle_collision_with(class Projectile*) {}
};
class Player : public Entity
{
public:
virtual void collide_with(Entity* other) override
{
other->handle_collision_with(this);
}
virtual void handle_collision_with(Entity* other) override
{
// Unhandled entity
}
virtual void handle_collision_with(Player* other) override
{
// Handle collision player-player
}
virtual void handle_collision_with(Projectile* projectile) override
{
// Handle collision player-projectile
}
};
class Enemy : public Entity
{
public:
virtual void collide_with(Entity* other) override
{
other->handle_collision_with(this);
}
virtual void handle_collision_with(Enemy* other) override
{
// Handle collision enemy-enemy
}
virtual void handle_collision_with(Player* player) override
{
// Handle collision enemy-player
}
virtual void handle_collision_with(Projectile* projectile) override
{
// Handle collision enemy-projectile
}
};
class Projectile : public Entity
{...}