Mi pregunta es:
¿Cómo puedo manejar los estados de juego en mi sistema de entidades, sin recurrir a mantener una pila de objetos de estado de juego?
Por lo tanto, el diseño de mi sistema de entidad significa que cuando una entidad necesita registrarse para eventos de entrada, por ejemplo, el componente de entrada llama al sistema de entrada y dice "registrar esta entidad para esta entrada". Todo esto está muy bien, sin embargo, si agrega a esto el concepto de estados del juego (digamos una pantalla de pausa), se convierte en un problema determinar si una entidad está en el estado actual y debe recibir la entrada.
Podría aumentar el componente / sistema de entrada para que diga: "registre esta entidad para esta entrada mientras esté en estos estados del juego", pero esto requiere que cada entidad sepa en qué estados se va a usar, y eso puede no ser obvio. Además, mantener una lista de estados de juego por entrada registrada (y otros sistemas que usan devoluciones de llamada) no parece demasiado eficiente.
Otra idea que tuve es que habrá una entidad que representa el estado del juego, márquelo como deshabilitado, luego, al generar el evento de entrada, verifique que la entidad no sea descendiente de una entidad con estado de juego deshabilitado. Parece costoso trabajar con el padre para cada devolución de llamada.
Otra idea es que todos los sistemas almacenen sus datos en clave contra el estado actual, de esa manera, al generar la entrada, la entidad objetivo ni siquiera será candidata. Sin embargo, esto realmente perjudica la capacidad de permitir la comunicación entre entidades en diferentes estados (no es tanto un problema para las pantallas de pausa, sino pensar en la selección de bloqueo en Oblivion / Skyrim).
La única otra idea que he tenido es que todos los componentes manejen los eventos de cambio de estado y se comuniquen con su sistema relevante para deshabilitar todo lo que hayan registrado y volver a habilitarlo al volver a este estado.
El segundo (marcar un objeto como deshabilitado) y el siguiente (hacer que cada componente se ocupe de los cambios de estado) parece ser la mejor de mis ideas, pero ninguna de ellas me llama especialmente la atención.
¿Alguien más tiene alguna otra idea sobre cómo hacer esto?
editar Mientras hablo de entrada específicamente en esta pregunta, puede significar cualquier sistema capaz de enviar mensajes / eventos a entidades, como colisiones, eventos de temporizador, etc.
fuente
Respuestas:
Lo que se usa a menudo es un intermedio
Intent System
que abstrae la entrada y realiza un seguimiento del contexto y los estados de juego relevantes.El sistema Intent dejará de transmitir entradas cuando la simulación esté en pausa, por ejemplo. También maneja el mapeo entre eventos e intenciones del controlador (moverse en dirección, correr, disparar, recargar ...).
De esta manera, sus otros componentes no dependen de entradas / gamepads específicos (BUTTON_A, BUTTON_B vs BUTTON_X, BUTTON_O ...) pero todos reaccionan a los mismos intentos (IntentRun, IntentReload ...).
Otra ventaja es que el sistema de intención puede estar al tanto de los controladores disponibles que se agregan / eliminan, ya que puede enviar intentos a cualquier suscriptor, incluso fuera de la simulación, puede manejar intentos similares
AddPlayer(controllerID)
.La cantidad de información sobre el estado del juego que proporciona al sistema a través de eventos / mensajes o directamente depende de usted. Pero el tiempo invertido en el sistema de intención generalmente vale la pena.
Puede gestionar los contextos de intención que generarán intenciones cuando estén conectados al sistema.
El contexto puede ser priorizado, es decir:
De esta manera, puede agregar y eliminar los contextos que actualmente son relevantes.
Y una cosa sobre todos los sistemas de intención es que debe ejecutarse mientras la simulación está en pausa.
Una forma que se usa a menudo para jugar / pausar la simulación del juego sin interrumpir las actualizaciones no relacionadas con la simulación es usar un conjunto diferente de veces. es decir
GenericSystem::onTime(Long time, Long deltaTime, Long simTime, Long simDeltaTime)
.Con este enfoque, su motor puede simplemente bloquear los incrementos en el simTime de los juegos, lo que a su vez bloqueará las actualizaciones en los motores de animación y física relevantes que se usan al
simTime and simDeltaTime
tiempo que permite actualizaciones continuas del efecto de resorte de su cámara si tiene que moverse incluso durante la pausa, la animación de el efecto de carga en una cartelera virtual en el juego mientras se descargan los datos ...fuente
¿Qué tal crear un sistema de eventos global y luego tener un componente de escucha de eventos para cada entidad? Después de un evento "Game State Change", podría jugar con componentes individualmente para cada entidad en particular.
Digamos que tiene un componente de entrada. Después de que el componente de escucha de eventos recibe el evento de cambio de estado del juego, cambia valores muy específicos para ese componente de entrada en particular, por lo que no recibirá ninguna llamada de entrada o no hará ningún movimiento o llamadas de respuesta al sistema o su propietario.
Esto funciona para mí, ya que la mayoría de mis componentes están programados (a través de Lua). Es decir, tengo un componente de entrada, que se dispara una vez cuando se presiona una tecla y se dispara de un movimiento + dirección y luego se dispara cuando se suelta la tecla y se dispara una parada + dirección. También hay un componente de escucha de eventos que contacta con el componente de entrada (si el juego está en pausa) para dejar de disparar cualquier función y detenerse si es necesario. Podría agregar fácilmente otra entidad con una reacción diferente a los mismos eventos y pulsaciones de teclas usando otro script. De esta forma, guardaría la interacción entre diferentes entidades en diferentes estados e incluso la haría mucho más personalizable. Lo que es más, algunas entidades pueden incluso no tener el componente de escucha de eventos en ellas.
Lo que acabo de explicar es básicamente un ejemplo práctico de su cuarta solución.
fuente