Suponga que tiene un juego en el que hay muchas (muchas, muchas) entidades que desempeñan algunas funciones, no todas las cuales son constantemente necesarias o deben considerarse en cada marco. El problema concreto en el que estoy trabajando en el que está presente este problema es una simulación detallada de un cuerpo que incluye sus órganos.
En el juego, cada criatura tiene su propio cuerpo que está separado en partes más pequeñas (torso, piernas, etc.) y, a veces, estas partes contienen órganos, que cumplen una función específica dentro del cuerpo. Si un órgano actualmente cumple o no un propósito o si está activo, nunca está claro. Después de todo, un animal puede tener el estómago vacío, por lo que no necesita digerir nada. Sería bastante ridículo verificar o simular cada objeto en cada cuadro y muy costoso tan pronto como tenga muchas criaturas en el mundo. Así que estaba pensando en una forma de diferenciar inteligentemente entre los objetos que necesitan actualizarse y los que no.
Lo que se me ocurrió parece una solución al menos aceptable. Crea una cola / pila simple (lo esencial es que cada elemento se elimine tan pronto como se lea; el orden es irrelevante) llamado "pila de atención" donde residen los objetos que necesitan ser simulados. Los objetos que necesitan atención simplemente se colocarían en la pila o otros objetos los colocarían allí. Estos objetos probablemente implementarían una interfaz simple con una función simulate ().
Aplicado a mi ejemplo de digestión anterior, esto significaría:
El jugador elige algo para comer (supongamos que es pan) del inventario y lo pone en la boca de su personaje y la boca se coloca en la pila de atención. En el siguiente cuadro, la boca se toma de la pila y se llama a su función simulate (). Como es una boca, sería razonable simular masticar aquí. Esto podría continuar durante unos pocos cuadros en los que la boca sigue poniéndose en la pila hasta que decida que la comida está lista para ser tragada. En este caso, la boca pone el pan masticado en el estómago (sé que no va allí directamente, pero el esófago se deja para simplificar), que luego se coloca en la pila de atención. En el siguiente cuadro se inicia la simulación del proceso de digestión. Y así sucesivamente para el resto de los órganos necesarios.
Un problema previsible con esto son los objetos inactivos. Un animal dormido es un buen ejemplo de esto. Podría hacerse como se describió anteriormente manteniendo al animal dormido en la pila y verificando cada vez si necesita despertarse, pero eso parece un desperdicio ya que eso es lo único que se hace. Para hacer que los objetos inactivos fueran más eficientes, estaba planeando agregar una especie de programación que almacena los trabajos que se realizarán en un momento específico. Si un animal se duerme, colocaría un trabajo en ese horario, que se programaría durante un cierto tiempo después de que el animal se durmiera. Este trabajo se encargaría de poner nuevamente al animal dormido en la pila de atención. Ahora, se podría decir que un animal dormido que no está en la pila de atención podría perder ser atacado por algo porque su IA no es simulada,
Ahora, honestamente, no sé si esto está cerca de una solución elegante a este problema debido a la falta de experiencia. ¿Estoy cerca de algo utilizable? ¿Cómo se hace esto o alguien tiene alguna sugerencia o mejores soluciones?
fuente
Suena como un problema similar al de las entradas: tiene más de 100 teclas en el teclado pero no desea verificar cada tecla individual en cada cuadro, entonces, ¿qué hace?
Dos respuestas: encuestas o mensajes del sistema.
Sondeo = en cualquier momento en el que realmente importe en el juego, consulta el estado de las teclas del teclado (o de los objetos, en tu caso). El resto del tiempo, ignóralos.
Mensajes = hacer que cada tecla del teclado (objeto) ponga algo en una cola de mensajes cuando se presiona o se suelta (cuando necesita atención). En cada iteración del ciclo del juego, mira a través de la cola y resuelve todos los mensajes antes de continuar.
fuente
Así que voy a dar un paso atrás de la implementación y revisar la pregunta desde una perspectiva de diseño. ¿Tiene un plan sólido para mostrar todos los detalles que desea incluir en esta simulación?
Por ejemplo:
Básicamente, la regla general es no hacer que su simulación sea más complicada que sus resultados. Al final del día, si las únicas animaciones que tienes para las ovejas son pastar, dormir, huir. Entonces realmente no importa cuántos factores intervienen en la decisión sobre qué estado elegir. Todos los jugadores verán ovejas que duermen de noche, corran del peligro y coman durante el día.
La simulación de comportamiento es muy divertida, pero siempre tenga en cuenta la experiencia del usuario final.
fuente
Tuve un problema similar en un juego en el que trabajé hace unos años: la simulación de objetos era compleja y no podía realizarse en detalle en cada objeto del mundo.
La solución fue utilizar el concepto LOD para la simulación. Los objetos dentro de la vista del jugador ejecutarían la simulación completa. Los objetos muy alejados del jugador ejecutaban una simulación altamente simplificada periódicamente. A medida que los objetos entraban en la vista del jugador, pasarían del curso, la actualización periódica de la simulación a actualizaciones detalladas y regulares.
fuente
La solución con un horario es buena. Tenga en cuenta que cada entidad debe tener una lista de punteros a sus acciones futuras, lo que da la posibilidad de invalidar acciones futuras si es necesario. Es decir. el animal dormido se despierta instantáneamente cuando es atacado, por lo que debe invalidar su acción de despertar en el futuro.
fuente
Hay un patrón de diseño para esto. Creo que se llama objetos de base de datos?
Básicamente, mantienes una oveja "plantilla" que puede representar a todas las ovejas no especiales en el mundo del juego, las dibujas de la misma manera, manteniendo los datos únicos dentro del objeto de la plantilla, por ejemplo, como una tabla de ubicaciones y / o tiempo de ovejas -desde cizalla. Luego, cada vez que necesite hacer que una oveja sea única, puede crear una instancia específica para rastrear esa oveja única.
Lo mismo ocurre con las animaciones. Si se trata de una animación o evento inactivo común a cada instancia, puede residir en la instancia de plantilla, donde se pueden programar animaciones más específicas por separado.
Hace mucho tiempo, escribí un juego para un concurso de programación cuyo ciclo principal acababa de llamarse animate () en toda la escena. Usó punteros de función para reemplazar animaciones inactivas con otras según sea necesario, y utilizó la técnica para admitir animaciones heredadas (por ejemplo, girar un personaje que está parado en un disco giratorio).
Es similar en naturaleza al uso de un delegado para la animación.
fuente
¿Funcionaría una máquina de estado? El animal se encuentra, por ejemplo, en estado de sueño, estado de alimentación, estado de ejecución, etc. Para cada estado se asocia una lista de órganos activos. Entonces, cada cuadro que visita a cada animal, enciende el estado, busca la lista de órganos para ese estado y ejecuta la actualización en cada uno de los órganos.
fuente