2010-02-03 5 views
16

¿Las entidades deberían saber dibujar por sí mismas? He utilizado este enfoque: es simple y funciona, pero después de aprender patrones MVC me siento incómodo con esto. Es difícil cambiar el estilo artístico cuando toda la lógica de la pantalla está oculta en el modelo.Juegos: ¿Quién es el responsable de mostrar?

Se podría introducir una clase de vista, que toma el nivel como argumento y lo dibuja, pero esto significa que tiene que identificar los tipos de entidad e introducir una declaración de "cambio", que también he averiguado.

¿Dónde debe colocarse un código para dibujar, de forma que sea extensible, fácil de cambiar, limpio y seco?

+1

No hay nada de malo con una instrucción de cambio. Hay algo mal con una declaración de cambio que tiene la misma estructura en varios lugares, lo que generalmente implica que debe usar una función virtual en su lugar. – MSN

+0

Una declaración de cambio es solo un goto disfrazado. Las declaraciones de cambio no son malas. Simplemente conducen a enormes líos con el tiempo, por ejemplo, son imanes de copiar/pegar *. – sylvanaar

+0

+1 - excelente pregunta. – Finglas

Respuesta

5

No hay nada intrínsecamente incorrecto en tener un método de estilo abstracto Draw() en sus entidades que les permita decidir cómo se dibujarán, especialmente para juegos pequeños que probablemente no se extenderán significativamente. He usado este método en una tonelada de pequeños proyectos y funciona muy bien.

Una mejora que puede realizar con esa estrategia es utilizar los recursos de su juego como un proxy para las operaciones de dibujo reales. Por ejemplo, una entidad enemiga puede diferir toda la representación a través de un objeto de recurso que posee y que representa la malla; lo mismo ocurre con la textura/piel y los efectos.

Recientemente he cambiado al uso de mis entidades como contenedores "tontos" para interfaces que definen sus comportamientos. Una entidad de jugador puede contener IMvoable, IControllable, IRenderable y muchas más interfaces que simplemente aplican una operación especializada a esa entidad según los datos que contiene. La entidad no sabe mucho sobre esto y toda la ejecución ocurre cuando el gráfico de escena se atraviesa para descartar/renderizar.

3

MVC no es necesariamente adecuado para juegos. MVC se diseñó para GUI tradicionales que, por lo general, se actualizan con poca frecuencia en función de eventos discretos, mientras que los juegos son más como simulaciones donde hay actualizaciones constantes y la presentación debe reflejarse de manera instantánea.

Aún así, no hay ninguna razón por la que no deba esforzarse por separar el estado de la presentación. Las entidades no necesitan saber cómo dibujarse como tal, eso quiere decir que conocen las operaciones de renderizado, lo cual es innecesario, pero debería ser posible preguntarles cómo se ven en este punto en el tiempo y luego usar esa información para renderiza la escena. p.ej. una entidad 2D debería ser capaz de devolver su marco de animación actual. O una entidad 3D debería poder devolver su malla 3d, posición y orientación. No hay necesidad de la declaración de cambio aquí, siempre que tenga representaciones genéricas que pueda devolver al procesador. Las entidades con algoritmos de representación muy diferentes pueden tener que devolver objetos bastante diferentes en este punto.

+0

Esto no está directamente relacionado con la pregunta, pero si sigue el enfoque que describió, ¿quién debería encargarse de manejar recursos como texturas? La entidad, el renderizador u otro objeto? –

+0

Las texturas son un detalle de implementación de la presentación, por lo que no estarían en la entidad directamente. Normalmente tendrías aquellos en algún tipo de administrador de recursos que se cargan en el punto donde cargas el sprite o malla para la entidad. La entidad sabe qué elemento o malla utiliza, y el elemento o malla sabe qué textura (s) utiliza. – Kylotan

3

Normalmente resuelvo este problema con herencia.

Por ejemplo, en un proyecto con el que estoy trabajando en este momento estoy usando Test-Driven Development para escribir la lógica del juego, con pruebas manuales para el renderizado. Este ejemplo a continuación en C# muestra la idea aproximada.

class GameObjecet { 
    // Logic, nicely unit tested. 
} 

class DrawableGameObject : GameObject { 
    // Drawing logic - manual testing 
} 

Esto es generalmente lo que he encontrado para ser la mejor solución. Esto permite que el código sea probado, sin saturar la lógica del juego con código de presentación, como dibujo y carga de modelos, etc.

+0

De alguna manera esta es la primera vez que la veo, y realmente me gusta. – Ricket

+0

+1 por mencionar la capacidad de prueba. Muy pocos programadores lo consideran al hacer elecciones de diseño. –

7

Esta pregunta todavía aparece con frecuencia en el desarrollo de juegos, ya que varios estudios y grupos comienzan con nuevos motores.

La respuesta corta es que depende de cuán complejas serán las entidades de tu juego. Para entidades simples, realmente no importa.

Cuando te metes en entidades mucho más complicadas, tienes que reconsiderar tu enfoque. En general, querrás resistir la tentación de tener el bucle uber que itera sobre cada entidad y llama a alguna función de actualización/renderizado/lo que sea. Eso no escala en absoluto, a menos que cada actualización, procesamiento o jerarquía sea exactamente la misma. Lo cual está bien para un juego como Geometry Wars, pero no para nada más complicado que eso.

Lo que quiere hacer es darle a la colección de entidad más general la extracción de un recorrido específico de uso. Por ejemplo, si desea renderizar la escena, debe tener una forma de extraer todas las entidades que se pueden renderizar de la colección de entidades y luego renderizar todas ellas en un orden de batches arbitrario. Lo mismo va para la física, colisión, AI, etc

Algunos enlaces útiles:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf

recomiendo encarecidamente tanto; el primero entra en la lógica de diseño para construir entidades de juego a partir de componentes, es decir, componente de renderizado, componente de física, componente AI. El segundo se refiere a las características de rendimiento de varios enfoques de entidades de juego.

Cuestiones relacionadas