Original Post
Hello everybody, I am currently developing my first own "larger" game. It should once become a simple 2D space side-scrolling game. I want it to be extensible and quite reusable for later projects. Till now I have only programmed simple games like Tetris and such things. Now I want to implement a more complex one. I have never before thought much about game design but now I have to because I want to have my code a little bit more organized. I am reading a bit on Component Oriented Programming and Entity Systems (like here or here). I like it very much so far and want to implement my game more or less like this. But there are some things that are not clear to me and it would be nice if you guys could help me a bit! I'm from Switzerland and my first language is not English. I hope you understand me well. ;) So here is how I'm planning to organize my game: All the game objects are single entities that consist of components. The entities can use components to form a certain object in the game. Examples of components are: Position, Render, Physics, Controller, Life. The implementations of the components are not in the component itself, they are in a separate subsystem (e.g. the Render() function of the Render component is in the Rendering Subsystem). In the components I store only specific data needed by the component (e.g. texture name for the Render component). All this sounds quite good, but which class has to know about the existence of which class? My idea was to register a component in its subsystem when it's created and remove it when it's deleted. So no component knows about each other, but each subsystem has a list of pointers to the components that belong to the system. This would look something like this: What I like in this component system is that I can have nice data-driven programming. What I'm not sure about is how the Entities or Components are interacting with each other (with events?). Here an example: I have 3 entities, a player, a monster and a custom visual effect. When the player kills the monster (ID "monster12") I want the visual effect to be deactivated. How would I do this? The Life component of the monster knows that he's dead, but how would it know it has to pass this information to the visual effect? Does the Life Subsystem send a message to all other components in the world? (like "monster12 has been killed by player") Or does the monster know that when it dies it has to pass the "deactivate" message directly to the visual effect? It would be nice if you could explain me how you would do this event handling. (solving the example) Maybe you could present your own manner to handle this. Comments on my "Entity System" are also very welcome. Thank you for reading this long post. I'm pretty sure I have left something unclear, please just ask when something is like that. :) Thanks in advance, I'm looking forward to your answers! Aeroz [Edited by - aeroz on April 8, 2008 3:53:49 AM]
/*--------ENTITY---------*/
class Entity
{
public:
Entity( const ObjIdType& rId) {
setID(rId);
}
const ObjIdType& getID() const { return m_OID; }
void setID( const ObjIdType& rId ) { m_OID = rId; }
Component* GetComponent(const CompIdType& rFamilyID ) {
return m_components[rFamilyID];
}
Component* SetComponent(Component *pNewComp);
void ClearComponents();
private:
ObjIdType m_OID; /*unique identifier for this object*/
std::map<const CompIdType, Component*> m_components; /* map of all components */
};
/*--------COMPONENT--------*/
class Component {
public:
Component() : m_pOwner(NULL) { /* register comp in subsystem */ }
virtual ~Component() = 0 {}
virtual const CompIdType& ComponentID() const = 0;
virtual const CompIdType& FamilyID() const = 0;
void SetOwnerObject( Entity* obj ) { m_pOwner = obj; }
Entity* GetOwnerObject() const { return m_pOwner; }
private:
Entity* m_pOwner;
};
/*--------SUBSYSTEM---------*/
class SubSystem {
public:
void RegisterComponent( Component* );
void UnregisterComponent( Component* );
virtual void Update() {}
private:
std::vector<Component*> m_components; /* map of all components in the system */
};
/*-------THIS IS AN EXAMPLE OF A COMPONENT------*/
class CompRenderPolygon : public Component
{
public:
CompRenderPolygon() { RenderSystem::RegisterComponent( this ); }
~CompRenderPolygon() { RenderSystem::UnregisterComponent( this ); }
SetTexture(...);
SetColor(...);
SetTransparency(...);
private:
/* data */
}
