Por lo que puedo decir, la mayoría de los juegos tienen algún tipo de "sistema de estado del juego" que cambia entre los diferentes estados del juego; Estos pueden ser cosas como "Introducción", "Menú principal", "Selección de personaje", "Cargando" y "Juego".
Por un lado, tiene mucho sentido separarlos en un sistema de estado. Después de todo, son dispares y de lo contrario tendrían que estar en una declaración de cambio grande, lo que obviamente es desordenado; y ciertamente están bien representados por un sistema estatal. Pero al mismo tiempo, miro el estado del "Juego" y me pregunto si hay algo malo en este enfoque del sistema de estados. Porque es como el elefante en la habitación; es ENORME y obvio, pero nadie cuestiona el enfoque del sistema de estado del juego.
Me parece una tontería que "Juego" esté en el mismo nivel que "Menú principal". Sin embargo, no hay una manera de romper el estado del "Juego".
¿Es un sistema de estado del juego la mejor manera de hacerlo? ¿Existe alguna técnica diferente y mejor para administrar, bueno, el "estado del juego"? ¿Está bien tener un estado de introducción que dibuje una película y escuche la entrada, y luego un estado de carga que se repita en el administrador de recursos, y luego el estado del juego que hace prácticamente todo ? ¿No te parece un poco desequilibrado también? ¿Me estoy perdiendo de algo?
fuente
Claro, el estado del juego sería enorme, pero no hay razón para que el estado del juego en sí no pueda contener una máquina de estado para administrar sus datos. Las máquinas de estado jerárquicas son útiles.
fuente
Siempre me gusta pensar en cada "estado" como una "escena". Entonces, el video de apertura es una escena, solo estática. Los créditos son una escena. El menú es una escena. La única diferencia entre todos ellos es el nivel de interactividad y la lógica del juego.
fuente
Tengo problemas con eso también, en realidad.
Digamos que tienes un juego.
En lugar de hacer que 'Juego' sea un estado como 'Cargando', 'Menú principal', etc. - En mi opinión, es mejor dejar que el Juego tenga varios estados:
"Cargando" - "mostrando el menú" - "en pausa" , etc.
El juego todavía se está ejecutando, pero cuando muestra el menú principal estaría en modo 'mostrar menú'.
Y cuando el juego no está en ningún estado en particular, simplemente se está ejecutando.
Tiene mucho más sentido, al menos para mí. :)
fuente
Un programa en línea (en el sentido tradicional de en línea, es decir, que se ejecuta y responde continuamente a la entrada, en lugar del significado conectado a Internet) generalmente consta de 3 cosas:
En términos generales, estos 3 están relacionados y cambian al mismo tiempo. Por ejemplo, al mostrar una pantalla de inicio, puede asignar todas sus teclas a un comando de 'cerrar pantalla' y la actualización puede estar desvaneciendo lentamente un gráfico con la salida solo mostrando ese gráfico. Pero cuando se juega un juego, todas las teclas se pueden asignar a diferentes comandos y la actualización está cambiando las propiedades de muchos objetos del juego.
Cuando lo ves de esta manera, tiene sentido separar una introducción de la creación de personajes y del juego propiamente dicho: cada uno tiene su propio conjunto de reglas de entrada, actualización y salida. Son casi como programas independientes que comparten datos y código de la biblioteca. Y, con esto en mente, generalmente tiene sentido tener un solo estado de Juego, ya que la jugabilidad es bastante homogénea en todo momento.
Por supuesto, si realmente tiene tipos de juego separados (por ejemplo, un ejemplo de RPG: Mapa del mundo, Mapa de la ciudad, Cutscene, Combate), con diferentes entradas, actualizaciones y salidas, no hay razón para que no pueda tener múltiples estados allí también en lugar de solo 1 estado de juego. Pero depende de tu juego.
fuente
Lo miro al otro lado. 'Menú', 'HighScores', "créditos" o lo que sea, podría considerarse como otro nivel, y ese estado no es necesariamente más ligero que su estado de "juego" (el estado del juego tiene más entidades en general, y diferentes, pero al final es solo otro nivel en el que las entidades muestran un comportamiento más predecible y los 'mapas' son generalmente menos intrincados).
Hacer ese cambio en su pensamiento definitivamente lo saca del síndrome del "menú aburrido".
fuente
En mi juego, tengo:
Execution Manager , que inicializa la aplicación (juego), carga recursos, libera recursos al salir de la aplicación, etc. Inicializa Application Engine, GameViewEngine, GameLogicEngine.
Game State Manager , que reside en GameLogicEngine, y es responsable de controlar las cosas relacionadas con el bucle principal del juego: detección de colisiones, cálculo de física, lectura de teclado, operaciones matemáticas, etc.
Inicialmente, tendía a tener solo un Game State Manager que era parte de mi GameLogicEngine. Sin embargo, tuve algunas dificultades para controlar la inicialización de los subsistemas principales (GameLogic, ApplicationEngine, ...). Podría haberse hecho, pero era más desordenado, en mi opinión.
Ahora las cosas me parecen más transparentes y estoy contento con el diseño.
fuente
Cambie el nombre del estado 'Juego' a algo como 'Gameplay'. Entonces tu lógica parece mejor; Dejas de jugar para ir al menú: sales del estado de Juego para ir al estado MainMenu.
Además, creo que cosas como la pausa, que requerirían que el juego esté en el mismo estado que cuando detuviste el juego, no deberían ser estados separados. ¿Estado infantil y anidación, tal vez? El juego tiene un menú de pausa.
fuente
Creo que hay un buen método llamado pila de estado del juego. No he visto ningún documento o artículo al respecto, pero se ha extendido un poco por voz. Esencialmente, el estado de juego más alto en la pila se llama primero y puede hacer lo que quiera con entrada / representación, etc. El estado de juego más alto es el único que se permite empujar o reventar estados.
En mi motor, los estados de juego son en realidad solo listas de entidades de juego. Entonces tengo entidades que funcionan como menús. Mis estados de menú pausan el juego (al no actualizar el siguiente elemento en la pila) pero dejan que los otros estados empujen sus modelos al renderizador para que mi menú de pausa (que no cubre toda la pantalla) todavía tiene la representación del juego en la parte posterior.
Espero que eso dé una idea de un sistema un poco diferente que no se base en una máquina de estado.
fuente
Esto está perfectamente bien. O al menos, es una mejora sobre "tener un gran cambio feo dependiendo del estado del juego".
Me gustaría señalar que en la mayoría de los juegos ya necesitarás una especie de máquina de estados finitos para tratar con una entidad AI simple. El ejemplo típico son los enemigos que están en estado inactivo, atacando o muriendo.
Si tienes una máquina de estado finito suficientemente abstraída, puedes reutilizarla tanto para el objeto del juego como para tu IA; de repente no estás "invirtiendo" mucho esfuerzo en el estado del Juego, sino que estás reutilizando el código que usaste de todos modos.
Se produce un autoenchufe desvergonzado: he implementado una máquina de estado finito en mi biblioteca de juegos Lua, MiddleClass (concretamente, el complemento llamado MindState). Así es como haces algo con Game State .
fuente
Un enfoque diferente para esto es utilizar un concepto del mundo de la programación funcional llamado Unión Discriminada . Si bien estos se encuentran típicamente en lenguajes FP, puede emularlos usando clases .
Básicamente, una Unión Discriminada es un tipo que siempre es uno de los
n
casos, y los datos almacenados pueden variar con cada caso.Por ejemplo:
Aquí, nuestro
GameState
tipo puede serMenu
oPlaying
. Si esMenu
así, contendrá unMenuState
objeto. Si esPlaying
así, contendrá unSimulationState
objeto.Para actualizar, haríamos
match
en el estado y llamaremos a una función diferente en consecuencia:Y de manera similar para renderizar:
Una ventaja de este enfoque es que puede manejar las cosas a través de los estados (como los recursos) con mayor facilidad sin globales o pasando objetos de "servicio".
fuente