Search code examples
c++pythoncomponentsentity-system

Component-based game entities and type checking


I'm writing a game and it's going to use a component-based entity system. The first two components that I'm implementing are EntityRepresentation and EntityState. The representation holds the animations, and the state decides how the entity should react to game events (examples of EntityStates: standing, jumping, attacking, dead, falling).

The EntityRepresnetation decides what animation to draw on the screen depending on the Entity's EntityState. If the Entity is in "jumping" state, the corresponding animation will be played. (See the EntityRepresentation::changeAnimation() function.)

Here's roughly how I wrote the class...

class EntityRepresentation
{
  public:
    void draw(float x, float y, long currentTime, DrawingContext& dc) {
        // ...
    }

    void changeAnimation(const EntityState::Id& stateId) {
        currentAnimation = animationMap_[stateId];
    }

  private:
    map<EntityState::Id, const Animation*> animationMap_;
    const Animation* currentAnimation_;
};

There's something that I really don't like with my current approach... >:( The EntityState::Id part. Currently, the EntityRepresentation maps each animation it holds to a specific EntityState::Id. The ID is unique to every class that derives from EntityState (unique to the class, not the instance). These IDs are basically strings that have to be written by hand in the class' constructor, which means they are highly prone to name-collisions — more so since I plan to make the game scriptable (Python).

Can someone give me some advice as to how I can alleviate this problem I have with the IDs. I've seen a lot of implementations of the component-based system in games that also use IDs, but I still don't like them. It just rubs me the wrong way.

Maybe you can suggest a design change, such that the EntityRepresentation doesn't have to know the type of the EntityState, all while still preserving encapsulation.


Solution

  • Use typeid(), that's what it's for. You could use a const type_info* as the key type.

    Alternatively, you know, you could just use actual inheritance, like, calling a virtual function to get the current animation, which would be much smarter.