Currently I am facing the following problem:
I am trying to write a pong clone by using an entity component system (ECS). I wrote the "framework" all by myself. So there is a class which manages the entities with all the components. Then there are the component classes themselves. And last there are my systems which just get all the entities which have components which the system needs.
So for example my movement system looks for all entities which have a position component and a movement component. The position component just holds the position and the movement component holds the speed.
But the actual problem is my collision system. This class is like a logical blob. I have so much special cases in this class.
For example: My paddles can collide with the borders. If this happens their speed is set to zero. My ball can as well collide with the borders. But in this case its speed is just mirrored at the normal of the border so it is reflected. To do this I gave the ball an extra physics component which just tells: "Hey, this thing does not stop, it reflects." So actually, the physics component has no real data. It is an empty class which is just there to tell the system if an object reflects or stops.
Then there comes this: I want to render some particles when the ball collides with the paddles or the borders. So I think the ball has to get another component which tells the collision system to create particle on collision.
Then I want to have power ups which can collide with the paddles but not with the borders. If that happens the power-ups have to disappear. So I would need much more cases and components (to tell the system that some entities can only collide with certain others, bot not with all even if some others are actually able to collide, furthermore the collision system had to apply the power-ups to the paddles, etc., etc., etc.).
I see that the entity component system is a good thing because it is flexible and you do not have problems with inheritance. But I am totally stuck currently.
Am I thinking too complicated? How should I cope with this problem?
Sure, I have to create systems which are actually responsible for "post-collision", so the collision system only tells "Yes, we have a collision in the last frame" and then there is a bunch of "post-collision" systems which all require different (combinations of) components and then change the components. For example there would be a movement post-collision system which stops things which have to stop when collision happens. Then a physics post-collision-system which reflects things, etc.
But this does not seem to be a proper solution to me either, because for example:
- My movement post-collision system would need entities which have a position component, a movement component and collision component. Then it would set the speed of the entity to zero.
- The physics post-collision system would need entities which have a position component, a movement component, a collision component and a physics component. Then it would reflect the speed vector.
The problem is obvious: Movement post-collision needs entities which are a subset of the entities in physics post-collision system. So two post-collision systems would operate on the same data, the effect being: Although an entity has a physics component, it speed would be zero after a collision.
How are these problems solved in general in an entity component system? Are those problems even usual or am I doing something wrong? If yes, what and how should it be done instead?