¿Qué filosofía de código / estructura de abstracción / diseño de programa permitiría utilizar un juego con gráficos 2D y 3D (por separado) SIN tener que volver a codificar la lógica del juego?
Estamos hablando de tomar el mismo código, cambiar un mínimo de cosas (por ejemplo, intercambiar nombres de archivos por activos 2D con nombres de archivos por activos 3D), y tal vez conectar algunas especializaciones de una clase base por genéricos / plantillas.
Para ponerlo en un contexto real en el que tiene sentido: imagine un juego LAN multijugador en el que hay un cliente 3D de primer nivel y ávido de rendimiento para los jugadores con algunas plataformas de juego realmente buenas, y un cliente 2D más humilde para los viejos cajas polvorientas que alguien encontró en su ático. Pero sigue siendo el mismo juego: se registran los mismos eventos (alguien recogió una moneda), se usa el mismo protocolo de red, los mundos son proporcionales, etc.
Para ponerlo en un contexto MVC: los Controladores son exactamente iguales (presionar la tecla "Arriba" establecerá la aceleración de los jugadores en 3.5 unidades / segundo), las Vistas son totalmente diferentes (2D versus 3D), y el Modelo es el mismo a excepción de cualquier cosa directamente relacionada con los gráficos (se realiza una verificación de colisión para el entorno cada 5 segundos, y utiliza el mismo algoritmo. Tenga en cuenta que esto significaría que hay una coordenada Z para todos los objetos del juego en la versión 2D, pero es simplemente ignorado o mostrado al usuario de otra manera, por ejemplo, por una sombra que se muestra más a la izquierda cuando el jugador está en el aire).
Lo que hace que este tema sea tan fascinante es que FORZARÍA al desarrollador a tener una idea muy clara de cómo se estructuran sus datos y cómo fluye el control. Tenga en cuenta que esto no implica usar otra cosa que no sea una biblioteca de gráficos como SDL, D3DX u OpenGL. No hay motores de juego!
Dado que esta es una pregunta mayormente teórica, dejaré los lenguajes de programación, pero si quieres dar un ejemplo, puedes usar el lenguaje que quieras, C ++ si quieres ir a por completo, o incluso Brainfuck si sientes a la altura del desafío (¡Cualquier respuesta concreta será apreciada, así como cualquier respuesta abstracta!).
fuente
Respuestas:
Creo que todo lo que necesitaría sería una capa de abstracción que envolviera su biblioteca de gráficos; necesitaría una nueva para cada biblioteca que usaría, y cada una necesitaría tener exactamente la misma API externa.
Piense en la localización de cadenas: en lugar de codificar la cadena "Inventario" en su juego, debería llamar a su biblioteca de localización (posiblemente personalizada), que haría algunos procesos y devolvería una cadena adecuada, dependiendo del contexto de el juego.
Del mismo modo, todas las llamadas a su motor de gráficos se realizarían a través de su envoltorio a su alrededor.
Al hacer esto, limita / restringe los comandos que puede dar a su motor gráfico. Aquí hay algunos esenciales:
Y algunos otros, que encontrará mientras trabaja en su proyecto.
Si está utilizando un lenguaje orientado a objetos de tipo estricto, llamaría a los comandos anteriores la interfaz que implementarán todos sus contenedores. Preferiblemente, estos serán los únicos métodos no protegidos / públicos.
Ahora, cree un nuevo contenedor para cada una de sus bibliotecas de gráficos e implemente la API . Cuando se le da un comando para dibujar __ en __ , debe usar el código para crear el sprite o modelo, y dibujarlo en su entorno. Esto podría requerir algunos trucos, como el almacenamiento de cada sprite en un hash para que se pueda volver a acceder en otro momento mediante un símbolo dado.
En cuanto a la construcción de mapas, la forma más eficiente sería pre-construir cada mapa para cada motor gráfico de antemano y hacer una búsqueda. Alternativamente, puede almacenar el mapa en su propia estructura de datos personalizada y luego usar su contenedor para construir un mapa a partir de esa estructura de datos.
Espero que esto te ayude a comenzar =]
fuente
Construir la arquitectura de su juego con un paradigma lo suficientemente cercano a MVC para permitir la abstracción completa del código de visualización probablemente sea bastante difícil para cualquier proyecto grande. Sin embargo, parece que el mayor impedimento para crear un juego que sea compatible con un cliente 2D y 3D sería diseñar un juego en el que ambos clientes sean igualmente capaces.
Sería necesario comenzar el diseño de su juego con la intención de crear y apoyar a los dos clientes, y probablemente sería más seguro restringir toda la funcionalidad del juego a lo que tiene sentido para el cliente 2D.
Como ejemplo, si no estaba diseñando para un conjunto de funciones restringidas, podría crear niveles en los que la información u objetos importantes solo fueran visibles desde ángulos específicos. Si bien eso estaría bien para los clientes 3D que tienen una libertad de visualización de 360 grados a menos que su cliente 2D admitiera explícitamente un ángulo de visión que tuviera visibilidad en cada uno de esos objetos importantes, estaría perjudicando a los usuarios del cliente.
Sería mejor establecer un número específico de ángulos de visión para el cliente 2D (8 o 16 o similar) y desarrollar todo el contenido para que se ajuste a esas restricciones. Desafortunadamente, si tiene niveles y objetos diseñados para ser visibles solo desde un conjunto específico de ángulos, puede parecer bastante extraño desde un cliente 3D.
En mi opinión, sería una mala elección intentar un diseño de juego que permita clientes 2D y 3D que tengan la misma capacidad. Creo que sería un mejor uso de los recursos para diseñar opciones de juego asimétricas y permitir que cada cliente juegue con sus puntos fuertes. Por ejemplo, si el cliente 2D se centraba principalmente en una perspectiva de nivel estratégico en el mundo del juego, y el cliente 3D se usaba para un juego de nivel táctico.
fuente
Creo que prácticamente has respondido tu propia pregunta:
Entonces, al proporcionar una abstracción adecuada entre la entrada, la lógica del juego, etc. y los gráficos, habrá resuelto el problema.
Este es básicamente el punto del modelo MVC, especialmente en lo que respecta a las aplicaciones de escritorio y web: puede haber múltiples clientes accediendo y manipulando los mismos datos (una interfaz web, cliente móvil y cliente de escritorio para correo electrónico, por ejemplo).
fuente
Mantenlo simple si lo quieres simple: - Escribe la lógica del juego para mover los objetos. No almacene ningún dato relacionado con el renderizado. - Escriba renderizadores que tengan la oportunidad de ver el estado de los datos del juego y dibujarlos.
Puede usar técnicas de programación más o menos complicadas para esto. Lo único que necesita es una forma de obtener los datos "adicionales" que necesita para cada objeto del juego. ¡La forma más simple es tener cero datos adicionales requeridos! Si el objeto del juego es un "Asistente", dibuja un Asistente.
Si necesita métodos más complicados, tenga en cuenta el polimorfismo, el patrón de recuerdo, las tablas hash, los indicadores de vacío *, etc.
fuente