I am working on a game environment which will feature a number of different entities. Each of this will have a few common functions (Draw, Update, etc) but sometimes the game must treat them differently based on their enemy type. So far, I have encoded the "type" of enemy in their instances' class. So, we have a situation like:
class MotionObject { ... };
class Entity : public MotionObject { ... };
class Coin : public Entity { ... };
class TextSign : public Entity { ... };
class ShapeEnemy : public Entity { ... };
class Attractor : public ShapeEnemy { ... };
class Bumper : public ShapeEnemy { ... };
So the classes Coin, TextSign, Attractor and Bumper are the types of entities instantiated in the game. Having different classes for different types of entities feels right, but I can't shake the feeling that some cumbersomeness might be avoided if I just had one entity class, which contained a switch statement that controlled its behaviour based on its "entity type", something stored in a variable. The player interacts with these entities in different ways depending on their type, and I use dynamic_cast and a null test each time to figure out which behaviour is applied. To be clear, these are for behaviours where I can't call a simple Update() on each entity; the player will respond in a specific way, or their will be inter-entity interaction, all based on the entities type. My code looks like this:
void Game::Update(float deltaT) {
for (int i =0; i < DrawChildren.size(); i++) {
//each entity has its Update called
DrawChildren[i].Update(deltaT);
//What follows is code that the Game class needs to run based on the entity type.
Coin * coin = dynamic_cast<Coin*>(DrawChildren[i]);
if (coin != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
TextSign * textSign = dynamic_cast<TextSign*>(DrawChildren[i]);
if (textSign != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
Attractor * attractor = dynamic_cast<Attractor*>(DrawChildren[i]);
if (attractor != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
Bumper * bumper = dynamic_cast<Bumper*>(DrawChildren[i]);
if (bumper != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
}
...
}
Is there a less cumbersome way to do this?