Estou planejando um jogo de aventura e não consigo descobrir qual é a maneira correta de implementar o comportamento de um nível, dependendo do estado da progressão da história.
Meu jogo para um jogador apresenta um mundo imenso, onde o jogador precisa interagir com pessoas de uma cidade em vários pontos do jogo. No entanto, dependendo da progressão da história, coisas diferentes seriam apresentadas ao jogador, por exemplo, o Líder da Guilda mudará os locais da praça da cidade para vários locais da cidade; As portas só se destrancaram em determinados momentos do dia após o término de uma rotina específica; Diferentes eventos de tela cortada / gatilho acontecem somente depois que um determinado marco é atingido.
Pensei ingenuamente em usar uma instrução switch {} inicialmente para decidir o que o NPC deveria dizer ou em que ele poderia ser encontrado e tornar os objetivos da missão interativos somente após verificar a condição de uma variável global game_state. Mas percebi que encontraria rapidamente vários estados de jogo e casos de troca para mudar o comportamento de um objeto. Essa declaração de switch também seria extremamente difícil de depurar, e acho que também pode ser difícil de usar em um editor de níveis.
Então pensei que, em vez de ter um único objeto com vários estados, talvez devesse ter várias instâncias do mesmo objeto, com um único estado. Dessa forma, se eu usar algo como um editor de níveis, eu posso colocar uma instância do NPC em todos os locais diferentes em que ele poderia aparecer, e também uma instância para cada estado de conversa que ele tiver. Mas isso significa que haverá muitos objetos de jogo invisíveis e inativos flutuando pelo nível, o que pode ser um problema de memória ou simplesmente difícil de ver em um editor de níveis, não sei.
Ou simplesmente, crie um nível idêntico, mas separado, para cada estado do jogo. Essa é a maneira mais limpa e sem erros de fazer as coisas, mas parece um trabalho manual maciço, garantindo que cada versão do nível seja realmente idêntica uma à outra.
Todos os meus métodos parecem tão ineficientes, para recapitular minha pergunta, existe uma maneira melhor ou padronizada de implementar o comportamento de um nível, dependendo do estado da progressão da história?
PS: Ainda não tenho um editor de níveis - pensando em usar algo como o JME SDK ou criar o meu.
fonte
As escolhas que eu consideraria são fazer com que os objetos individuais respondam a diferentes gamestates ou atendam níveis diferentes em diferentes gamestates. A escolha entre os dois dependeria exatamente do que estou tentando fazer no jogo (quais são os diferentes estados? Como o jogo fará a transição entre estados? Etc.)
De qualquer forma, no entanto, eu não faria isso codificando os estados no código do jogo. Em vez de uma declaração de comutação massiva em objetos NPC, eu usaria os comportamentos NPC carregados em uma matriz associativa a partir de um arquivo de dados e depois usaria essa matriz associativa para executar comportamentos diferentes para os estados associados, algo como:
fonte
Que tal usar um padrão de observador para procurar mudanças de marcos? Se uma mudança acontecer, alguma classe reconhecerá isso e manipulará, por exemplo, uma mudança que deve ser feita em um npc.
Em vez do padrão de design de estado mencionado, eu usaria um padrão de estratégia.
Se um npc tem n maneiras de interagir com o personagem e m posições onde ele poderia estar, há um máximo de (m * n) +1 de classe que você precisa criar. Usando o padrão de estratégia, você terminaria com as classes n + m + 1, mas essas estratégias também poderiam ser usadas por outros npcs.
Portanto, pode haver uma classe lidando com os marcos e classes que observam essa classe e lidam com npc ou inimigos ou o que quer que deva ser alterado. Se os observadores forem atualizados, eles decidirão se precisam mudar algo para as instâncias que governam. A classe NPC por exemplo, no construtor, informa o NPC-Manager quando ele precisa ser atualizado e o que precisa ser atualizado ...
fonte
Todas as abordagens fornecidas são válidas. Depende da situação em que você está, a qualquer momento. Muitas aventuras ou MMOs usam uma combinação desses.
Por exemplo, se um evento crucial altera uma grande parte do nível (por exemplo, um cobrador de dívidas limpa seu apartamento e todos são presos), geralmente é mais fácil substituir a sala inteira por uma segunda que é parecida.
OTOH, se os personagens andam pelo mapa e fazem coisas diferentes em lugares diferentes, geralmente você tem um único ator que gira através de diferentes objetos de comportamento (por exemplo, siga em frente / sem conversas versus fique aqui / conversando sobre a morte de Mitch), que pode incluir "oculto" se o seu objetivo tiver sido cumprido.
Dito isto, geralmente ter duplicatas de um objeto que você cria manualmente não deve causar problemas. Quantos objetos você pode criar? Se você pode criar mais objetos do que o seu jogo pode passar, observe a propriedade "oculta" e pule, seu mecanismo está muito lento. Então eu não me preocuparia muito com isso. Muitos jogos online realmente fazem isso. Certos personagens ou itens estão sempre lá, mas não são exibidos para personagens que não têm a missão correspondente.
Você pode até combinar as abordagens: Tenha duas portas em seu prédio. Um leva ao apartamento "antes do cobrador de dívidas", outro ao apartamento depois. Quando você entra no corredor, apenas o que se aplica à sua progressão na história é realmente mostrado. Dessa forma, você pode apenas ter um mecanismo genérico para "o item está visível no momento atual da história" e uma porta com um único destino. Como alternativa, você pode criar portas mais complicadas que podem ter comportamentos que podem ser trocados, e uma delas é "vá para o apartamento completo", a outra "vá para o apartamento vazio". Isso pode parecer absurdo se realmente apenas o destino da porta mudar, mas se sua aparência mudar também (por exemplo, uma grande fechadura na frente da porta que você primeiro tenha que abrir),
fonte