pattern patron imediator example comportamiento design design-patterns coupling

design - patron - Separación de lógica de juego y representación



mediator pattern example (3)

Me esforzaría por hacer tus objetos lo más genéricos posibles y evitar codificar hechos de juego en tu código tanto como sea posible.

Por ejemplo, tiene una clase Entity o Object o Actor, y esa clase tiene un puntero a su toma de decisiones (su AI) y un puntero a su representación gráfica.

Su toma de decisiones se combina necesariamente con los hechos del juego; de hecho, es parte de los hechos del juego. Así que este es un lugar donde puedes nombrar a tu responsable de tomar decisiones "KnightAi" o algo así.

Por otro lado, la representación gráfica es solo un poco de gráficos. Se dibujará igual que cualquier otra entidad. Usted tiene un modelo o algunos mapas de bits y algunas animaciones o no ... Esto podría / podría simplemente llamarse algo así como "Modelo" y cargará la información que se le dice que cargue define cómo se ve la entidad para el jugador. Cuando se trata de representar a un caballo contra un caballo en lugar de un castillo, es probable que todos hagan lo mismo con diferentes datos. El tipo de datos que tienen es incluso el mismo, solo son los contenidos los que son diferentes.

Diga que sus entidades fueron todas representadas como círculos. Simplemente harías que señalen a un CircleRenderer que tomó el tamaño que deberían dibujar. ¡No crearías una clase de procesador diferente para cada tamaño diferente (o color, o lo que sea) del círculo que quisieras!

¿Cuál es la mejor manera de separar el código de representación del motor / código lógico del juego? ¿Y es incluso una buena idea separarlos?

Supongamos que tenemos un objeto de juego llamado Knight. El Knight tiene que mostrarse en la pantalla para que el usuario lo vea. Ahora nos quedan dos opciones. O le damos al Caballero un método de Render/Draw que podemos llamar, o creamos una clase de renderizador que se encarga de representar a todos los caballeros.

En el escenario donde los dos están separados, el Caballero debería el Caballero aún contener toda la información necesaria para representarlo, ¿o debería separarse también?

En el último proyecto que creamos, decidimos dejar que toda la información requerida para procesar un objeto se almacenara dentro del objeto mismo, pero teníamos un componente separado para leer realmente esa información y representar los objetos. El objeto contendría información tal como el tamaño, la rotación, la escala y qué animación se estaba reproduciendo en ese momento y, en base a esto, el objeto del procesador debería componer la pantalla.

Los marcos como XNA parecen pensar que unir el objeto y renderizar es una buena idea, pero tememos estar atados a un marco de renderizado específico, mientras que construir un componente de renderización separado nos da más libertad para cambiar el marco en un momento dado.



KnightRenderer clase de KnightRenderer separado. Ventajas:

  • Separación limpia entre la lógica del juego y la representación. El propio Knight podría incluso correr en un servidor de juegos y no saber nada sobre el renderizado.
  • Clases más pequeñas y sencillas, relacionadas con una y única pieza de funcionalidad.

Todo lo que KnightRenderer necesita saber sobre Knight (posición, estado) tiene que ser legible públicamente en Knight .

Las propiedades específicas de la representación entrarían en la clase KnightRenderer . Por ejemplo, tal vez quieras hacer que el caballero destelle cuando lo golpeen, por lo que necesitarías almacenar un contador o valor de tiempo.