I'm trying to design a component-based entity system for learning purposes (and later use on some games) and I'm having some troubles when it comes to updating entity states.
I don't want to have an update() method inside the Component to prevent dependencies between Components.
What I currently have in mind is that components hold data and systems update components.
So, if I have a simple 2D game with some entities (e.g. player, enemy1, enemy2) that have Transform, Movement, State, Animation and Rendering components I think I should have:
- A MovementSystem that moves all the Movement components and updates the State components
- And a RenderSystem that updates the Animation components (the animation component should have one animation (i.e. a set of frames/textures) for each state and updating it means selecting the animation corresponding to the current state (e.g. jumping, moving_left, etc), and updating the frame index). Then, the RenderSystem updates the Render components with the texture corresponding to the current frame of each entity's Animation and renders everything on screen.
I've seen some implementations like Artemis framework, but I don't know how to solve this situation:
Let's say that my game has the following entities. Each entity have a set of states and one animation for each state:
- player: "idle", "moving_right", "jumping"
- enemy1: "moving_up", "moving_down"
- enemy2: "moving_left", "moving_right"
What are the most accepted approaches in order to update the current state of each entity? The only thing that I can think of is having separate systems for each group of entities and separate State and Animation components so I would have PlayerState, PlayerAnimation, Enemy1State, Enemy1Animation... PlayerMovementSystem, PlayerRenderingSystem... but I think this is a bad solution and breaks the purpose of having a component-based system.
As you can see, I'm quite lost here, so I'd very much appreciate any help.
EDIT: I think the solution to make this work as I intend is this one:
You make statecomponent and animationcomponent generic enough to be used for all entities. The data they contain will be the modifier for changing things like which animations are played or which states are available. – Byte56
Now, I'm trying to figure out how to design these 2 components generic enough so I can reuse them. Might having an UID for each state (e.g. walking, running...) and storing animations in a map into the AnimationComponent keyed by this identifier be a good solution?
Answer
IMHO the Movement
component should hold the current state (Movement.state
) and the Animation
component should observe changes of Movement.state
and update its current animation (Animation.animation
) accordingly, using a simple lookup of state id to animation (as suggested at then end of the OP). Obviously this means Animation
will depend on Movement
.
An alternative structure would be to have a generic State
component, which Animation
observes, and Movement
modifies, which is basically model-view-controller (state-animation-movement in this case).
Another alternative would be to have the entity dispatch an event to its components when its state changes. Animation
would listen to this event and update its animation accordingly. This eliminates the dependency, although you could argue that the dependent version is a more transparent design.
Good luck.
No comments:
Post a Comment