Estoy planeando un juego de aventuras, y no puedo entender cuál es la forma correcta de implementar el comportamiento de un nivel dependiendo del estado de la progresión de la historia.
Mi juego para un jugador presenta un mundo enorme donde el jugador tiene que interactuar con personas de una ciudad en varios puntos del juego. Sin embargo, dependiendo de la progresión de la historia, se le presentarían diferentes cosas al jugador, por ejemplo, el Líder del Gremio cambiará de lugar desde la plaza del pueblo a varios lugares alrededor de la ciudad; Las puertas solo se desbloquearían en ciertos momentos del día después de terminar una rutina en particular; Los diferentes eventos de corte de pantalla / activación ocurren solo después de que se haya alcanzado un hito en particular.
Inicialmente pensé en usar una declaración switch {} inicialmente para decidir qué debería decir el NPC o en qué se podía encontrar, y hacer que los objetivos de búsqueda interactuaran solo después de verificar la condición de una variable global game_state. Pero me di cuenta de que rápidamente me encontraría con muchos estados de juego y casos de cambio diferentes para cambiar el comportamiento de un objeto. Esa declaración de cambio también sería enormemente difícil de depurar, y supongo que también podría ser difícil de usar en un editor de niveles.
Entonces pensé, en lugar de tener un solo objeto con múltiples estados, tal vez debería tener múltiples instancias del mismo objeto, con un solo estado. De esa manera, si uso algo como un editor de niveles, puedo poner una instancia del NPC en todas las diferentes ubicaciones en las que podría aparecer, y también una instancia para cada estado de conversación que tenga. Pero eso significa que habrá muchos objetos de juego invisibles e inactivos flotando alrededor del nivel, lo que podría ser un problema para la memoria o simplemente difícil de ver en un editor de niveles, no lo sé.
O simplemente, crea un nivel idéntico pero separado para cada estado del juego. Esta es la forma más limpia y libre de errores para hacer las cosas, pero se siente como un trabajo manual masivo para asegurarse de que cada versión del nivel sea realmente idéntica entre sí.
Todos mis métodos se sienten tan ineficientes, así que para recapitular mi pregunta, ¿hay una manera mejor o estandarizada de implementar el comportamiento de un nivel dependiendo del estado de la progresión de la historia?
PD: Todavía no tengo un editor de niveles, pensando en usar algo como JME SDK o hacer el mío.
fuente
Las opciones que consideraría son hacer que los objetos individuales respondan a diferentes estados de juego o servir diferentes niveles en diferentes estados de juego. La elección entre esos dos dependerá de qué es exactamente lo que estoy tratando de hacer en el juego (¿cuáles son los diferentes estados? ¿Cómo hará la transición del juego entre estados? Etc.)
De cualquier manera, sin embargo, no lo haría codificando los estados en el código del juego. En lugar de una declaración de cambio masivo en objetos NPC, en lugar de los comportamientos NPC cargados en una matriz asociativa desde un archivo de datos y luego usar esa matriz asociativa para ejecutar un comportamiento diferente para sus estados asociados, algo como esto:
fuente
¿Qué pasa con el uso de un patrón de observador para buscar cambios importantes? Si ocurre un cambio, alguna clase lo reconocería y manejaría, por ejemplo, un cambio que debe hacerse a un npc.
En lugar del patrón de diseño de estado mencionado, usaría un patrón de estrategia.
Si un npc tiene n formas de interactuar con el personaje ym posiciones donde podría estar, hay un máximo de (m * n) +1 clases que debes diseñar. Usando el patrón de estrategia, terminaría con n + m + 1 clases, pero estas estrategias también podrían ser utilizadas por otros npcs.
Entonces, podría haber una clase manejando los hitos, y clases que observen esta clase y manejen npc o enemigos o lo que sea que deba cambiarse. Si los observadores se actualizan, decidirán si tienen que cambiar algo a las instancias que gobiernan. La clase NPC, por ejemplo, en el constructor, informaría al NPC-Manager cuándo debe actualizarse y qué debe actualizarse ...
fuente
Todos los enfoques dados son válidos. Depende de la situación en la que se encuentre en un momento dado. Muchas aventuras o MMOs usan una combinación de estos.
Por ejemplo, si un evento crucial cambia una gran parte del nivel (por ejemplo, un cobrador de deudas limpia su apartamento y todos los que están en él son arrestados), generalmente es más fácil reemplazar toda la habitación con una segunda habitación que se ve similar.
OTOH, si los personajes caminan por el mapa y hacen cosas diferentes en diferentes lugares, a menudo tienes un solo actor que rota a través de diferentes objetos de comportamiento (por ejemplo, caminar hacia adelante / sin conversaciones frente a pie / conversación sobre la muerte de Mitch), que podría incluir "oculto" si su propósito se ha cumplido.
Dicho esto, generalmente tener duplicados de un objeto que creas manualmente no debería causar ningún problema. ¿Cuántos objetos puedes crear? Si puedes crear más objetos de los que tu juego puede recorrer, mira su propiedad "oculta" y salta, tu motor es demasiado lento. Así que no me preocuparía demasiado por eso. Muchos juegos en línea realmente hacen esto. Ciertos personajes o elementos siempre están ahí, pero no se muestran a los personajes que no tienen la misión correspondiente.
Incluso puede combinar los enfoques: tenga dos puertas en su edificio de apartamentos. Uno conduce al apartamento "antes del cobrador de deudas", uno al apartamento después. Cuando ingresas al corredor, solo se muestra el que se aplica a tu progresión en la historia. De esa manera, puede tener un mecanismo genérico para "el elemento es visible en el punto actual de la historia" y una puerta con un único destino. Alternativamente, puede hacer puertas más complicadas que pueden tener comportamientos que se pueden intercambiar, y una de ellas es "ir al departamento completo", la otra "ir al departamento vacío". Esto puede parecer absurdo si realmente cambia el destino de la puerta, pero si su apariencia también cambia (por ejemplo, una gran cerradura frente a la puerta que primero tiene que romper),
fuente