Sign in to follow this  
AntiGuy

Entity Components and the Main Loop

Recommended Posts

AntiGuy    267
Mentioning the word component seems to be like opening a can of worms so I'll try to make this a very very plain question. I've been over game object models for a while from a variety of sources now but I've yet to see something piece it all together. I know the implementations are varied but I really just would like someone to break it down plain and simple. Here's how I think things will be set up so far. This code is just an example.
class GameObject //I guess the general object class
{
 Matrix Transform //The Position and direction etc..
}
class Entity: GameObject //A Game Object with special features
{
 RenderingComponent Renderer //Component used to draw the object
 PhysicsComponent Physics //Component used for collision and such
}

void Initialization()
{
  RenderManager = new RenderManager();
  PhysicsManager = new PhysicsManager();
  Entity ent = new Entity();

  PhyicsManager.AddObject(ent.Physics);
  RenderManager.AddObject(ent.Renderer, /*some properties here*/);
}


void MainUpdate()
{
 
PhysicsManager.Update(); //Update all the objects in the physics Manager
RenderManager.Update(); //Updates all the objects in the render Manager

}


The managers hold a list of component refereces and updates them. I'm thinking this logic could be extended with other things like animation, AI, etc... Although there's some things missing (like scene management and such) but I'd like to know if the overall concept is correct. And one more thing! Is using a matrix instead of a position vector really more effecient? It feels weird not to see a vector for the position in a class library but somehow right.

Share this post


Link to post
Share on other sites
Hodgman    51328
Quote:
Original post by AntiGuy
Although there's some things missing (like scene management and such) but I'd like to know if the overall concept is correct.
Mostly, although usually the point of an entity/component system is that your entities are data-driven, instead of hand-coded, e.g.
class Entity
{
void CreateComponents( const XMLDocument& );//< etc...
std::vector<Component*> m_Components;
};
Also, putting any data directly into the entity (i.e. your transform matrix) goes against the idea of an entity as simply being a "thing that groups components".
What about logic entities that don't need positions? What about marker entities that need a position, but not rotation? I'd move the matrix into your physics component instead (in mine, both the physics component and the rendering component have their own matrix -- when physics changes, it updates rendering).

Quote:
And one more thing! Is using a matrix instead of a position vector really more effecient?
That depends... I've used engines where we had a position vector and a rotation (angles) vector. This was inefficient because you were constantly converting the angles into forward/right/up vectors... A matrix *is* a forward/right/up vector and a position vector.
Quote:
It feels weird not to see a vector for the position in a class library but somehow right.
It is there, you're just calling it something else. const Vector& position = transform[3];

Share this post


Link to post
Share on other sites
AntiGuy    267
Ah I see! I believe I had a mixed system in mind.

With a pure component system it seems you're holding a list to the root off all the component systems in all the classes based off entity. You make the class with the exact components you need and when you reference an object by the entity type you can check through the components and see which ones you have support for when you need to.

Even with that, I never lose the ability to place entity objects into subclasses where known components can be in place. I like it!

Thanks this has been a very helpful post.

Share this post


Link to post
Share on other sites
aaron_ds    486
Quote:
Original post by Hodgman

What about logic entities that don't need positions? What about marker entities that need a position, but not rotation? I'd move the matrix into your physics component instead (in mine, both the physics component and the rendering component have their own matrix -- when physics changes, it updates rendering).


I'd move the matrix into a position/orientation component. Then I wouldn't have to remember to update two matrices. This wouldn't stop someone from having a position/orientation component and then pointing to that component from the physics and rendering components, maybe initializing the pointers using dependency injection.

Copying data to more than one location has the tendency to not scale well. If he wanted to attach a sound emitter component and a logic component and a lighting component, there would be a need for the physics engine to do 5 matrix updates. It's just too much to remember.

How about this?

class PositionAndOrientationComponent
{
public:
Matrix Transform //The Position and direction etc..
};
class RenderingComponent{
public:
PositionAndOrientationComponent* PositionAndOrientation;
RenderingComponent(PositionAndOrientationComponent* positionAndOrientation):PositionAndOrientation(positionAndOrientation){

}
};
class PhysicsComponent{
public:
PositionAndOrientationComponent* PositionAndOrientation;
PhysicsComponent(PositionAndOrientationComponent* positionAndOrientation):PositionAndOrientation(positionAndOrientation){

}
};
class Entity //A Game Object with special features
{
public:
PositionAndOrientationComponent* PositionAndOrientation;
RenderingComponent* Renderer; //Component used to draw the object
PhysicsComponent* Physics; //Component used for collision and such
};


void Initialization()
{
RenderManager = new RenderManager();
PhysicsManager = new PhysicsManager();
Entity* ent = new Entity();
ent->PositionAndOrientation = new PositionAndOrientationComponent();
//Inversion of control with dependency injection
ent->Renderer = new Renderer(ent->PositionAndOrientation);
ent->Physics = new Physics(ent->PositionAndOrientation);

PhyicsManager.AddObject(ent->Physics);
RenderManager.AddObject(ent->Renderer);
}


void MainUpdate()
{

PhysicsManager.Update(); //Update all the objects in the physics Manager
RenderManager.Update(); //Updates all the objects in the render Manager

}



Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this