Después de repasar algunos patrones de diseño del juego, me decidí por Entity-Component-System (ES System) para mi motor de juego. He leído artículos (principalmente T = Machine ) y reviso algunos códigos fuente y creo que tengo suficiente para comenzar.
Solo hay una idea básica con la que estoy luchando. ¿Cómo trato con grupos de entidades que dependen unas de otras?
Dejame usar un ejemplo:
Suponga que estoy haciendo un tirador aéreo estándar (piense en Jamestown ) y quiero construir una "entidad de jefe" con múltiples partes distintas pero conectadas. El desglose podría verse así:
- Cuerpo del barco: movimiento, renderizado
- Cañón: posición (bloqueado en relación con el cuerpo del barco), seguimiento \ disparar al héroe, recibir daño hasta deshabilitar
- Núcleo: posición (bloqueada en relación con el cuerpo de la nave), seguimiento \ disparar al héroe, recibir daño hasta deshabilitar, deshabilitar (er ... destruir) todas las demás entidades en el grupo de la nave
Mi objetivo sería algo que sería identificado (y manipulado) como un elemento distinto del juego sin tener que reescribir el subsistema desde cero cada vez que quiera construir un nuevo Elemento agregado.
¿Cómo implemento este tipo de diseño en ES System?
- ¿Implemento algún tipo de relación de entidad padre-hijo (las entidades pueden tener hijos)? Esto parece contradecir la metodología de que las entidades son solo contenedores vacíos y lo hace sentir más POO.
- ¿Los implemento como entidades separadas, con algún tipo de componente de conexión (BossComponent) y sistema relacionado (BossSubSystem)? No puedo evitar pensar que esto será difícil de implementar, ya que la forma en que los componentes se comunican parece ser una gran trampa para los osos.
- ¿Los implemento como una sola entidad, con una colección de componentes (ShipComponent, CannonComponents, CoreComponent)? Este parece desviarse de la intención del Sistema ES (los componentes aquí se parecen demasiado a entidades pesadas), pero sé esto, así que pensé que lo pondría ahí.
- ¿Los implemento como algo más que he mencionado?
Sé que esto se puede implementar muy fácilmente en OOP, pero mi elección de ES sobre OOP es una con la que me quedaré. Si necesito romper con la teoría pura de ES para implementar este diseño, lo haré (no es que no haya tenido que comprometer el diseño puro antes), pero preferiría hacerlo por razones de rendimiento en lugar de comenzar con un mal diseño.
Para obtener un crédito adicional, piense en el mismo diseño, pero cada una de las "entidades de jefe" estaba realmente conectada a una "entidad de BigBoss" más grande hecha de un cuerpo principal, núcleo principal y 3 "Entidades de jefe". Esto me permitiría ver una solución para al menos 3 dimensiones (abuelo-padre-hijo) ... que debería ser más que suficiente para mí.
fuente
Respuestas:
Si estuviera en esta situación, crearía cada parte del jefe como una entidad separada. Estos "sub-entidades" incluirían algún tipo de
AttachmentPoint
oParentEntity
componente. Este componente incluiría una referencia a la entidad matriz y un desplazamiento de la posición de los padres. Al actualizar la posición, verifican la posición principal y aplican el desplazamiento para generar su propia posición. Además, podría realizar comprobaciones para garantizar que la entidad principal aún exista. Además, puede tener unSubEntity
componente que rastrea la existencia de subentidades para la entidad principal. Esto le permite hacer cosas como hacer que el núcleo del jefe sea vulnerable cuando se destruyen los brazos con escudos.Actualmente uso un
TargetEntity
componente en mi juego, que se usa para el seguimiento de torretas y cuando los duendes van a recoger un recurso. Puede verificar la posición de la entidad objetivo y cambiar su comportamiento en consecuencia. Las entidades que no tienen posición nunca se agregan como objetivo, por lo que no hay preocupaciones allí. Sin embargo, cuando llegue a ser más profundo, como verificar la salud, el escudo, las reservas de energía o lo que sea de la entidad principal o secundaria, deberá asegurarse de que la entidad principal o secundaria realmente tenga el componente relacionado.Al hacer que cada parte sea su propia entidad, se mantiene la flexibilidad del marco de la entidad / componente al permitirle agregar componentes adicionales y diferentes a cada parte del jefe. Por ejemplo, una parte del jefe podría tener un componente de arma y un componente de salud, mientras que otra tendría un componente de escudo y un componente de salud.
Encontré otra discusión sobre este tema aquí . En el cual los usuarios están discutiendo agregar múltiples componentes del mismo tipo a una entidad (lo cual me parece una mala idea). Parece una conversación útil, aunque no he leído toda la discusión.
fuente
Sin conocer demasiados detalles sobre sus sistemas existentes, la forma en que modelaría esto (y hasta cierto punto en mi propio sistema de entidades) es tener un componente como AttachedTo (parentEntity). A cualquiera de los niños se les puede asignar el componente AttachedTo (jefe).
El sistema de renderizado (o lo que sea) toma entidades con componentes: Position, AttachedTo, etc. y forma las jerarquías adecuadas.
fuente
Si desea tener una entidad representada solo por una ID, la contención de entidades se puede hacer a través de un componente especial. Podría llamarlo CompositeComponent, y este contiene una lista de ID de entidades secundarias e interfaces para agregar / eliminar elementos secundarios de esa lista.
Obviamente, cualquier componente que dependa de la posición, etc. deberá trabajar con este para colocar la entidad correctamente. Cómo implementar esto dependerá un poco de cómo implemente el posicionamiento actualmente.
Por cierto, no existe una "teoría de ES pura": hacer entidades a partir de componentes es un enfoque popular, pero el método preciso de ninguna manera está estandarizado todavía.
fuente