El diseño tradicional del juego , como lo sé, utiliza polimorfismo y funciones virtuales para actualizar los estados de los objetos del juego. En otras palabras, el mismo conjunto de funciones virtuales se llama en intervalos regulares (por ejemplo, por cuadro) en cada objeto en el juego.
Descubrí recientemente que hay otro sistema de mensajería controlado por eventos disponible para actualizar los estados de los objetos del juego. Aquí, los objetos generalmente no se actualizan por cuadro. En cambio, se crea un sistema de mensajería de eventos altamente eficiente , y los objetos del juego se actualizan solo después de recibir un mensaje de evento válido.
Event Driven Game Architecture se describe bien en: Game Coding Complete por Mike McShaffry .
¿Podría pedir ayuda con las siguientes preguntas?
- ¿Cuáles son las ventajas y desventajas de ambos enfoques?
- ¿Dónde está uno mejor que el otro?
- ¿Es el diseño del juego dirigido por eventos universal y mejor en todas las áreas? ¿Se recomienda su uso incluso en plataformas móviles?
- ¿Cuál es más eficiente y cuál es más difícil de desarrollar?
Para aclarar, mi pregunta no es sobre eliminar completamente el polimorfismo del diseño de un juego. Simplemente deseo entender la diferencia y beneficiarme del uso de mensajes dirigidos por eventos versus llamadas regulares (por cuadro) a funciones virtuales para actualizar el estado del juego.
Ejemplo: esta pregunta causó un poco de controversia aquí, así que déjame ofrecerte un ejemplo: según MVC, el motor del juego se divide en tres partes principales:
- Capa de aplicación (comunicación de hardware y sistema operativo)
- Game Logic
- Vista del juego
En un juego de carreras, Game View es responsable de renderizar la pantalla lo más rápido posible, al menos 30 fps. Game View también escucha las opiniones de los jugadores. Ahora esto sucede:
- El jugador presiona el pedal de combustible al 80%
- GameView construye un mensaje "Pedal de combustible del automóvil 2 presionado al 80%" y lo envía a Game Logic.
- Game Logic recibe el mensaje, evalúa, calcula la posición y el comportamiento del nuevo automóvil y crea los siguientes mensajes para GameView: "Dibujar el pedal de combustible del automóvil 2 presionado al 80%", "Aceleración del sonido del automóvil 2", "Coordenadas del automóvil 2 X, Y". .
- GameView recibe los mensajes y los procesa en consecuencia
fuente
update
). Lo segundo que puedes hacer con la mensajería por varias razones.Respuestas:
Creo plenamente en la necesidad de ser la madre de la invención. No me gusta codificar nada a menos que su necesidad sea clara y esté bien definida. Creo que si comienzas tu proyecto configurando un sistema de mensajería de eventos, lo estás haciendo mal. Creo que solo una vez que haya creado y probado su infraestructura y tenga todas las piezas de su proyecto como módulos de trabajo bien definidos, debe centrarse en cómo conectará estos módulos entre sí. Intentar diseñar un sistema de mensajería de eventos antes de comprender la forma y las necesidades de cada módulo está fuera de servicio.
¿Cuáles son las ventajas y desventajas de ambos enfoques?
Creo que algunas personas argumentarían que existen buenos sistemas de mensajería listos para ser instalados y utilizados. Quizás esto es cierto. Ciertamente, el rendimiento de una solución de construcción personalizada específicamente adaptada a sus necesidades sería mayor que un bus de mensajes de uso general. La gran pregunta es: ¿cuánto tiempo pasará construyendo un sistema de mensajería en lugar de usar algo que ya se ha construido? Obviamente, si puede encontrar algún tipo de sistema de eventos con exactamente el conjunto de características que necesita, entonces es una decisión bastante fácil. Es por eso que me aseguro de entender exactamente lo que necesito antes de tomar esa decisión.
¿Dónde está uno mejor que el otro?
Podríamos hablar de memoria y recursos aquí. Si está desarrollando para cualquier hardware con recursos limitados, ciertamente es un problema utilizar un sistema de eventos que reducirá eso significativamente. Realmente, sin embargo, creo que el problema se reduce a lo que necesitas, que como ya mencioné es algo que no sabes hasta que ves cómo se ven todas las piezas. Si tiene suficiente experiencia en la construcción de estos sistemas y sabe de antemano exactamente cómo se verán todas las piezas, también puede responder esta pregunta con anticipación. Supongo que no tienes esta experiencia, ya que no harías esta pregunta si la tuvieras.
¿Es el diseño del juego dirigido por eventos universal y mejor en todas las áreas? Por lo tanto, ¿se recomienda su uso incluso en plataformas móviles?
¿Universal y mejor en todas las áreas? Una declaración bastante general como esa es fácilmente rechazada. Cualquier cosa que agregue gastos generales debe llevar su parte de la carga de trabajo. Si no está utilizando eventos lo suficiente como para garantizar la sobrecarga del diseño, entonces es el diseño incorrecto.
¿Cuál es más eficiente y cuál es más difícil de desarrollar?
La eficiencia depende de cómo se implemente. Creo que un diseño tradicional bien desarrollado superará a un sistema basado en eventos cualquier día de la semana. Esto se debe a que la comunicación entre las piezas puede ser microgestionada y hacerse súper eficiente. Por supuesto, esto también dificulta el diseño desde el punto de vista de la experiencia y el tiempo necesarios para completarlo y hacerlo más eficiente. Por otro lado, si carece de esta experiencia o no tiene el tiempo para desarrollar bien la aplicación, utilizar un diseño basado en eventos que satisfaga sus necesidades será más eficiente. Si tiene necesidades de eventos personalizados que no encajan fácilmente en una estructura basada en eventos, esto podría hacer que la estructura basada en eventos sea muy difícil de diseñar, especialmente para mantener el diseño eficiente.
fuente
Creo que estás comparando manzanas y naranjas aquí. El polimorfismo no se reemplaza por mensajes en absoluto. Probablemente desee que los eventos / mensajes conecten componentes acoplados libremente. P.ej. para enviar un mensaje desde una entidad cuando se produce una colisión, para actualizar el puntaje del jugador o tal vez para activar un efecto de sonido. Para que estas clases individuales no conozcan las otras clases y simplemente envíen y / o manejen mensajes.
Pero lo más probable es que su juego tenga un ciclo de actualización en algún lugar y, dado que tiene ese ciclo de actualización, puede usarse fácilmente para actualizar todas las entidades del juego que también deben actualizarse en cada cuadro. Sin embargo, esto no evita que uses mensajes ...
Si tiene algún tipo de estructura donde agrega / elimina entidades de juego, puede incluirlas en su ciclo de actualización en lugar de enviarles un mensaje de actualización en cada cuadro. Entonces, ¿por qué no llamar a la actualización de sus entidades de juego directamente mientras está usando la mensajería para conectar diferentes subsistemas de su juego? También me gusta el concepto de señal / ranura ( ver ejemplo qt ) para sistemas similares a eventos.
En pocas palabras: no hay un mejor enfoque, ni son exclusivos.
fuente
Esto comenzó como un comentario a la respuesta de bummzack, pero se alargó.
A menos que realmente lo haga asíncrono (despachar eventos en un nuevo hilo), sus objetos aún reciben el memo de forma sincrónica. Suponiendo que su despachador de eventos use una tabla hash básica con una lista vinculada en una celda, el orden será el orden en que se agregaron los objetos a esa celda.
Además, a menos que decida usar punteros de función por alguna razón, todavía está usando llamadas de función virtuales ya que cada objeto que recibe un mensaje debe implementar IEventListener (o como se llame). Los eventos son una abstracción de alto nivel que se construye utilizando polimorfismo.
Use eventos en los que tenga que llamar a una larga lista de métodos para varios eventos en el juego para sincronizar diferentes sistemas en el juego o donde varios objetos y sistemas reaccionen para que dichos eventos no puedan definirse claramente o desee para agregar más reacciones a dichos acontecimientos en el futuro.
Son una gran herramienta, pero como dijo bummzack, no asuma que el polimorfismo y los eventos resuelven el mismo problema.
fuente
Yo diría que elegir uno u otro está bastante mal. Algunos objetos necesitan llamar a cada cuadro, otros no. Si tiene un objeto que desea renderizar, debe realizar una llamada de renderizado en cada fotograma. Los eventos no pueden hacer este cambio. Lo mismo es cierto para cualquier objeto de física basado en el tiempo: debe llamarlos cada cuadro.
Sin embargo, no hago llamadas en cada cuadro a mis objetos de administración de objetos, ni a mis objetos de entrada de usuario, ni nada de eso. Las llamadas virtuales masivas a cada objeto en el marco son una idea terrible.
El diseño utilizado para cualquier objeto en particular debe basarse en las necesidades de esos objetos y no en alguna ideología para el sistema en su conjunto.
Editado para ser más claro en mi primera oración.
fuente