¿Cómo puedo diseñar un esquema de interacción de objetos de juego efectivo con una arquitectura basada en componentes?

14

Esta es una pregunta de diseño ... Estoy seguro de que esto podría generalizarse más, pero me está costando mucho. Me pregunto sobre el diseño para las interacciones de objetos del juego: aquí está mi ejemplo (rompecabezas 2D-plataforma).

Digamos que el jugador está intentando progresar a través de un nivel. Hay muchas luces que pueden apuntar en diferentes direcciones. Aquí hay un ejemplo de cómo estos objetos ligeros podrían interactuar ...

  • One light proyecta una plataforma que permite al jugador cruzar una brecha
  • Una luz disminuye los coeficientes de fricción de todo lo que toca, otra la aumenta.
  • Una luz anula los efectos de todas las luces, lo que haría que la plataforma desapareciera mientras la luz está encendida y anulara los modificadores de fricción.
  • Etc ...

¿Cuál es la mejor manera de abordar este problema cuando se utiliza una arquitectura de componentes? Los componentes para cada objeto principal parecen obvios, así como una forma limpia de definir sus efectos en el medio ambiente. ¿Una clase para "resolver" la interacción (parece que eso podría convertirse en un desastre rápidamente)? ¿Algún uso del patrón decorador para crear objetos combinados para aquellos que están interactuando en un momento dado? ¿Una estructura de datos que se presta a esto?

Además, ¿conectar audio a estas interacciones? Parece que conectar audio al sistema sería como conectar cualquier otra propiedad, como la visibilidad o el movimiento / colisión del jugador.

Obviamente, a medida que se agreguen más componentes, sería bueno si hubiera un sistema robusto que pudiera manejar otros nuevos con poca modificación, pero no estoy familiarizado con cómo diseñarlo.

Otra información: El motor que estoy usando es un motor XNA llamado IceCream .

Christopher Horenstein
fuente
2
Sin embargo, hay una pregunta real aquí, a diferencia de la "pregunta" en el enlace que Joe da.
dash-tom-bang
2
no veo el engaño, la pregunta es sobre cómo diseñar los requisitos específicos de un juego en código, usando un sistema de componentes (@Christopher: mencionando cuál ayudaría, ¿estás usando Unity? Torque? Propietario?)
LearnCocos2D
2
Por cierto, me gusta tu idea de juego =)
Nailer

Respuestas:

5

En un sistema orientado a objetos, la única respuesta real a la pregunta de cuál es la mejor manera de hacer X es que debe hacerlo de la manera más directa que pueda pensar para poner en marcha algo y luego cambiarlo cuando se hace más fácil la expresión. Preocuparse por elegir el patrón correcto antes de escribir cualquier código es una buena manera de cargar con la respuesta incorrecta desde el principio; deje que todos los pensamientos sobre patrones y componentes se desvanezcan y solo siga estos pasos, comenzando desde donde se encuentra hoy (suponiendo que haya implementado un componente ligero):

  1. Agregue código al componente ligero a las plataformas de proyecto. (Haz que esto funcione)
  2. Copie ese componente en un nuevo componente, elimine las cosas de la plataforma y agregue código para disminuir la fricción de los objetos apropiados. (Haga que esto funcione, verifique que el n. ° 1 siga funcionando).
  3. Copie ese componente en un nuevo componente, eliminando el código "nuevo" y agregue cosas para deshabilitar los efectos de los otros componentes. (Haga que esto funcione, luego verifique que # 1 y # 2 todavía funcionan).

En este punto, (probablemente) tendrá un montón de código duplicado. Extraiga código común en funciones u otra clase (tal vez una clase base) o lo que parezca apropiado. Sin embargo, el hecho de que haya comenzado con un "componente ligero" no significa que LightComponent sea una base adecuada; podría ser que cualquier código que componga el componente ligero no sea realmente un "componente" per se y tal vez eso esté mejor representado por un conjunto de funciones o incluso una clase separada que se agregue a sus nuevos componentes (como una variable miembro )

dash-tom-bang
fuente
Estoy marcando esto como la respuesta porque realmente responde "¿Cómo debería diseñar ...". Gracias por esto, definitivamente me puso en el camino correcto.
Christopher Horenstein
2

En términos generales, cuando un objeto de tipo A interactúa con un objeto de tipo B, desea tener algún efecto C. Esto se llama "despacho doble" y es muy difícil de hacer de manera elegante en lenguajes tipo C.

La forma efectiva pero difícil de mantener es solo un montón de instrucciones de cambio y if, dependiendo de los tipos de sus objetos. Te sentirás sucio al escribirlo, pero hará el trabajo.

El patrón de visitante es una solución más robusta que oculta el cambio de tipo desagradable, pero puede ser complicado de configurar.

Normalmente, cualquier tipo de cambio de tipo en su código es un olor, pero aquí está tratando de generalizar el polimorfismo, que normalmente cambia las funciones basadas en un solo tipo, para cambiar las funciones basadas en dos tipos. El polimorfismo es una base de OOP, por lo que no es un olor.

tenpn
fuente
2

Déjame ver. Esto es algo que cociné en mi cabeza mientras escribía, lo siento si me falta algo.

Obtenga todos los nodos de luz a una distancia razonable alrededor de su amigo.

Para cada luz, representa un polígono que representa su área de efecto a un objeto framebuffer. Entonces, un cono de luz crearía un cono de un tipo de píxeles en su FBO. Haga que cada tipo de nodo pase en prioridad apropiada Podrías codificar información en cada píxel como si el canal verde pudiera ser fricción, el rojo sería la gravedad, el azul y el alfa serían otra cosa.

Las técnicas inteligentes de mezcla de colores podrían crear efectos interesantes. Cada nivel podría tener sus propias reglas de mezcla. También puede agregar sombreado de fragmentos para efectos dinámicos psicodélicos como la gravedad pulsante, etc.

Por último, solo verifique qué píxeles está tocando su mandude y vuelva a calcular el mapa de bits cada vez que se acerque a los bordes del área precalculada.

Scetch áspero hecho en 2 minutos para ilustrar mi idea:

Ilustración

Editar: en la práctica, esto significa que lo único que necesita es un componente de luz que emita un determinado color. Las reglas conectadas a qué color hace lo que puede estar en otro lugar por completo. Puede codificar una gran cantidad de datos en los 32 bits que tiene por píxel. Alternativamente, puede tener múltiples FBO que contienen diferentes atributos que no se afectan entre sí. Podría tener un FBO de gravedad / fricción y un FBO de colisión de 1 bit. Si elige esto, por supuesto, tendrá que marcar en qué FBO debe representar su luz.

Fabricante de clavos
fuente
Gracias por su aporte. Realmente aprecio las imágenes, y esto realmente me hizo pensar en cómo el mecánico podría trabajar detrás de escena.
Christopher Horenstein
Je, no hay problema. Sé que no respondió su pregunta exacta, pero algunos problemas requieren soluciones especializadas. ¡Buena suerte!
Clavador
0

Patrón de observador es una de las mejores soluciones. El mensaje se enviará solo a aquellos objetos (componentes) que realmente estén interesados ​​en él. Por lo tanto, el receptor debe suscribirse en este tipo de mensaje / evento.

Hay muchas implementaciones de señal / ranura. Por ejemplo, en C ++ hay una biblioteca sigslot

Para obtener más información, lea acerca de las señales Qt y las ranuras .

parte superior derecha
fuente