Tengo algunos problemas para encontrar la manera de tratar con la administración estatal en mis entidades.
No tengo problemas con la administración del estado del juego, como la pausa y los menús, ya que estos no se manejan como un sistema de componentes de la entidad; solo con estado en entidades / componentes.
Dibujando de Orcs Must Die como ejemplo, tengo mis entidades MainCharacter y Trap que solo tienen sus componentes como PositionComponent, RenderComponent, PhysicsComponent.
En cada actualización, la Entidad llamará a la actualización de sus componentes. También tengo un EventManager genérico con escuchas para diferentes tipos de eventos.
Ahora necesito poder colocar las trampas: primero seleccione la trampa y la posición de la trampa, luego coloque la trampa.
Al colocar una trampa, debe aparecer frente al personaje principal, renderizada de una manera diferente y siguiéndola. Cuando se coloca, debe responder a las colisiones y presentarse de la manera normal.
¿Cómo se maneja esto generalmente en sistemas basados en componentes?
(Este ejemplo es específico, pero puede ayudar a descubrir la forma general de tratar con estados de entidades).
fuente
Respuestas:
Una aplicación interesante de un sistema de componentes es que puede cambiar los componentes de una entidad en tiempo de ejecución si la diseñó para poder manejarlos. El estado de una entidad se convierte así en la suma de los componentes que se le asignan y los valores que tienen.
Para su ejemplo, primero puede crear la trampa con un
BuildControllerComponent
(que rige la reacción a los controles del jugador en la fase de construcción), ayPositionComponent
aRenderComponent
. El último tiene un campo de datos que gobierna los sombreadores de píxeles utilizados, y uno de ellos le da a la trampa-a-ser-construir un aspecto "fantasmal". Notarás que todavía no hay componentes de física asignados.Al colocar la trampa, los componentes se intercambian. El
BuildControllerComponent
ya no es necesario, por lo que se elimina. LosRenderComponent
sombreadores del 's se reemplazan con su vista estándar normal de la trampa. Finalmente,PhysicsComponent
además de lo que sea necesario para que funcione la trampa, se agregan a la entidad.En un enfoque basado en la herencia, esto es equivalente a tener un constructor para una
ActiveTrapEntity
clase que toma unaBuildTimeTrapEntity
clase como argumento, el segundo se usa para representar la trampa durante su construcción, el primero se usa para la trampa después de que esté en su lugar .fuente
BuildControllerComponent
?" o "¿Cuál es la posición de esta entidad como se registra en suPositionComponent
, si tiene alguna?" - los que hace al verificar la lista de componentes para los que le interesan y, opcionalmente, consultar (algunos de) sus valores.BuildControllerComponent
s. Ya necesita procesar los cambios en el punto de vista del personaje del jugador (o de la cámara) y los eventos de pulsación de tecla y mouse.No me gusta la idea de que las entidades soliciten actualizaciones en sus componentes (los sistemas deberían estar haciendo el trabajo), y eso conducirá a problemas para mantener a los componentes inconscientes entre sí.
Puede agregar un componente adicional llamado "Estado". Sus sistemas de renderizado y colisión accederán a él. El componente de estado es solo un indicador que tiene varios estados disponibles. Para la situación que describe, los estados serían
Play
yBuild
. Cuando el sistema de renderizado ve que el estado esBuild
, dibujará el objeto translúcido. Cuando el sistema de colisión ve elBuild
estado, no procesará colisiones con el jugador.Pero realmente, si no tiene sistemas y depende de componentes para hacer todo el trabajo, se encontrará con muchos problemas. Los componentes no deberían conocerse entre sí y no deberían estar procesando.
fuente
StateComponent
que puede ser consumida por múltiples sistemas.