2010-05-03 13 views
26

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

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 Knight un método Render/Draw al que podemos llamar, o creamos una clase de renderizador que se encarga de representar a todos los caballeros.

En el escenario en el que 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 toda la información necesaria para representar un objeto dentro del objeto, pero teníamos un componente separado para leer 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.

Frameworks 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 en cualquier momento.

+3

Ignorar las implementaciones de XNA. Por mucho que me guste, la forma "predeterminada" de ver ejemplos en la web y en los libros es horrible. Cada objeto conoce la clase base del juego y, a su vez, todo sabe cómo dibujar, etc. Esto no está bien. La solución de Thomas es ideal y lo que mucha gente hace. – Finglas

Respuesta

5

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

E.g. 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 es una 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.

Digamos 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!

20

Crearía una clase KnightRenderer por separado. Ventajas:

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

Todo los KnightRenderer necesita saber acerca de la Knight (posición, situación) 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.

+0

Así es exactamente como lo hago. – Finglas

+3

Me gustan tus pensamientos. Pregunta: ¿Dónde creas el Knight Renderer? ¿Lo referencia directamente en Knight, o lo crea en otro lugar y lo pasa? – lochok

+0

@Thomas ¿KnightRenderer contendría código real (gl */directx/lo que sea)? En caso de que contenga, parece difícil aplicar algunas optimizaciones y cambiar la implementación. Al igual que KnightRenderOpelGL, etc. – GorillaApe

Cuestiones relacionadas