¿Cuál es el enfoque correcto orientado a objetos para el diseño de clases en el desarrollo de juegos?

31

Estoy a punto de desarrollar un juego 2D basado en sprites para Windows 7 Phone, usando XNA. La capacitación y los tutoriales disponibles son bastante útiles, pero el problema que enfrento es que cada uno de ellos aborda su diseño de clase de manera diferente, y el código no está particularmente bien factorizado. Como resultado, me ha resultado difícil comprender bien qué responsabilidades debo asignar a una clase en particular.

Por ejemplo, podría tener una clase de sprite base BaseSpriteque sepa cómo dibujarse, verificar colisiones, etc. Entonces podría tener una AnimatedSpriteclase que supiera cómo navegar por su hoja de sprites, una ExplodingSpriteclase, etc. Esta técnica se demuestra en el ejemplo de Space Invaders en los materiales de Windows 7 Phone Jumpstart Session 2 .

Alternativamente, podría colocar la mayor parte de la representación y ejecución de la responsabilidad del juego en una GameScreenclase; esa clase y sus clases derivadas se comportan más como formularios o páginas web en términos de sus responsabilidades. Las clases de Sprite son contenedores más simples con mucha menos lógica.

Esta es la técnica utilizada en el juego Alien Sprite de Windows 7 Phone Training Kit y en otros ejemplos de administrador de estado del juego.

¿Cuál es el enfoque correcto orientado a objetos para el diseño de clases en el desarrollo de juegos?

Josh E
fuente

Respuestas:

26

Utilizo un enfoque más orientado a componentes, donde tendrías una clase Sprite que tiene componentes como Visual, Colisión, Animación, Entrada, etc. Con este enfoque no termino teniendo una jerarquía de clases profunda (lo cual es bueno) .

Para obtener información sobre el diseño orientado a componentes, consulte aquí .

thbusch
fuente
2
+1 el artículo que vinculaste fue fantástico. Estaba tan concentrado en el diseño puro de OO que pasé por alto completamente el modelo de tipo componente / decorador.
Josh E
1
El patrón de componentes no es realmente "menos puro" OO :)
Srekel
2
En efecto. OO a menudo se equipara con la herencia. Pero la herencia es solo una herramienta que ofrece OO, la composición es otra.
haffax
Tan. Debería haber sido más preciso en mi redacción; lo que quise decir es que me concentré demasiado en el lado de la herencia de OO en lugar de pensar en los patrones de diseño de OO / otros aspectos de OO que podrían ayudarme a lograr lo que quería.
Josh E
Si bien un enfoque basado en la comoposición es bastante obvio y se usa con frecuencia, aún no he visto una solución para mantener el componente de representación portátil. Cualquier pista sería genial.
Andreas
11

En los juegos, el patrón Componente es una solución común.

munificente
fuente
ese es otro artículo fantástico, vale la pena leerlo.
Josh E
1
¡Genial, genial, gran artículo!
Kevin
6

Los Principios SÓLIDOS se aplican tanto al diseño del código del juego como a cualquier otra profesión, al menos hasta que llegue a optimizar, por lo que usaría su primer ejemplo como punto de partida.

Sin embargo, iría más lejos, porque BaseSprite parece que tiene la tendencia a convertirse en una megaclase. El Principio de Responsabilidad Única dicta que la colisión, el renderizado y la navegación deben ser manejados por componentes, en lugar de entradas individuales en una jerarquía de clases. La clase holding de todos estos componentes solo debe manejar empujar posiciones mundiales entre ellos.

tenpn
fuente
5

En los últimos proyectos, me he inclinado más hacia un enfoque de estilo MVC.

Al principio no estábamos seguros de si esto funcionaría, pero funcionó perfectamente.

Modelo

Los objetos de datos. Solo los datos puros. Sin comportamiento, sin renderizado.

Administrador de datos. Solo manejo de "listas" de objetos de datos. (También se puede mejorar para admitir la agrupación).

Ver

Los llamamos renderizadores. Para cada tipo de objeto de datos hay un renderizador. Cuando se llama con un administrador, representará todos los objetos de esa lista.

Controlador

Igual que los renderizadores, pero controla el comportamiento.

Ejemplo

El ShipManager tiene una lista de barcos. El ShipController moverá las Naves de acuerdo a su estado. El ShipRenderer representará las Naves de acuerdo a su estado.

Por qué

De esta manera, la vista y la lógica están estrictamente separadas. Hace que portar a una nueva plataforma sea bastante fácil. La optimización del diseño de datos dentro del XxxManager también es muy fácil.

Andreas
fuente
2
Te voy a rechazar porque estoy harto de ver más o menos "Usar MVC" como una respuesta aceptable. Si está desarrollando en cualquier plataforma moderna, ya está utilizando MVC en múltiples niveles. No es una respuesta específica, y no es una buena respuesta, porque en realidad no le dice a la gente cómo estructurar las clases, que es específica de la tarea / dominio. Simplemente terminas con mucha gente escribiendo "class Modal ...; class View ...; class Controller ..." MVC es un patrón con mucho poder explicativo de alto nivel cuando se habla de código existente. No es un patrón con mucho poder de planificación.
44
@ Joe, entiendo tu punto, pero considero que tu elección de palabras es innecesaria y grosera. Acabo de explicar cómo lo hacemos. Dado que la opción de arquitectura de nivel superior hace que la opción de diseño de nivel inferior sea obsoleta, la considero una respuesta válida.
Andreas