Como devo modelar um jogo baseado em economia no código?

10

Eu gostaria de criar um jogo de economia baseado em uma civilização antiga. Não tenho certeza de como projetá-lo. Se eu estivesse trabalhando em um jogo menor, como uma cópia de "Space Invaders", não teria problema em estruturá-lo assim:

  • Classe de controle principal
  • Classe Gráfica
  • Classe de Jogador
  • Classe inimiga

Não entendo como faria isso em projetos maiores, como o meu jogo econômico. Crio uma classe de país que contém várias cidades? As cidades contêm muita classe de construção, a maioria contém classes de pessoas? Eu faço uma classe de localização de caminhos que o jogador pode acessar para se locomover?

Matthew G.
fonte
3
Você pode querer usar alguma forma de um sistema de componentes de entidades (aqui está a referência canônica ) - sem que as entidades se desenhem (especialmente se você tiver muitas delas).
ThorinII
9
Você ficaria terrivelmente surpreso com o quão horríveis, desorganizados e hackeados a maioria dos jogos "grandes" é. Eles são construídos em torno de prazos e marcos. Basta escrever um jogo e qualquer estrutura que caia fora do que você precisa escrever será tão boa quanto não melhor do que a maioria dos jogos AAA por aí.
Sean Middleditch 30/10
Mesmo se você não usar o ECS completo, ainda assim é bom não duplicar o código, deixe o controlador iterar as entidades e chamar o renderizador, ou até mesmo deixar o renderizador digitalizar. Fazer uma pequena atualização de código em 100 locais é uma dor.
MickLH
1
Pular de Space Invaders para um jogo complexo, como você descreveu, é um pouco drástico, na minha opinião. Existem mais etapas de aprendizado entre esses dois jogos, antes de você entrar em um projeto de grande jogo. Considere criar uma plataforma side-scroller 2D e aumentar gradualmente a complexidade dos seus jogos. Passar da primeira para a quinta marcha pode levar até 120 km / h, mas não com a mesma eficiência (tempo / esforço) que seria se você passasse de nível por nível.
Emir Lima
2
Parece que você tem duas perguntas aqui, e não sei dizer o que é mais importante para você. O primeiro é sobre como evitar passar muitas referências a objetos, e o segundo é sobre como você deve abordar o mapeamento das entidades lógicas no seu jogo em classes de código. Essas perguntas têm respostas distintas, e acho que você deve postar perguntas distintas para elas. Vou editar sua parte "evitando passar referências". Sinta-se à vontade para republicá-lo (e também considere pesquisar neste site por tópicos sobre "evitar singletons e globais", pois as respostas são muito semelhantes).

Respostas:

5

Crio uma classe de país que contém várias cidades?

Certo.

As cidades contêm muita classe de construção, a maioria contém classes de pessoas?

Certo.

Eu faço uma classe de localização de caminhos que o jogador pode acessar para se locomover?

Certo.

Tudo o que você sugeriu acima parece razoável. Pode não ser o melhor caminho para você a longo prazo, mas tudo bem. Obviamente, faz sentido para você saber, uma vez que foi o modelo organizacional que lhe veio pela primeira vez. É importante que você pegue isso e inicie uma implementação a partir dele. Isso o ajudará a começar, superando essa "paralisia de design" inicial que muitas vezes aflige os desenvolvedores no início de uma tarefa e (se houver algum defeito), ensinando uma ou duas coisas sobre os prós e os contras dessa abordagem específica ao design.

Você naturalmente pegou os conceitos em sua cabeça e os agrupou em código de acordo com algumas regras simples:

  • Esse conceito difere significativamente no comportamento ou nos dados de outros objetos que eu já tenho? (Países e pessoas compartilham muito pouco, se houver, dados ou comportamentos significativos, portanto devem ser representados por tipos distintos no jogo).
  • Será que preciso manipular esse conceito no código de maneira significativa (se o seu jogo lida com pessoas individuais, você pode precisar dessa Personclasse, mas se o jogo se importar apenas com elas de forma agregada, como nas versões anteriores do SimCity, você talvez não seja necessário esse tipo, nem instâncias desse tipo para criar um mapeamento 1: 1 da população de uma cidade int populationCount.
  • Este conceito requer estado ? Nesse caso, deve ser encapsulado de alguma forma que me permita armazenar esse estado (uma classe) em vez de um monte de funções livres. (Uma implementação de pathfinding não possui um objeto do mundo real análogo, mas exige o acompanhamento de dados, como quais nós no mapa já foi considerado, e isso é melhor realizado através de uma classe do que armazenado em um monte globais ocultos e funções autônomas).

Embora simples, responder a essas perguntas pode beneficiar muito você ao tentar decidir se e como transformar um conceito mental em código-fonte. Você também pode ler os princípios do SOLID do design orientado a objetos .

Observe que a sugestão de um sistema de entidade / componente feita nos comentários também é uma abordagem válida, embora eu a evite aqui, a menos que você redimensione seu projeto para ser menor (simplesmente porque assumir dois novos e grandes desafios em um projeto pode ser muito assustador e pode diluir o benefício educacional que você receberia por se concentrar apenas em um). Em um modelo orientado a componentes, o "tipo" nas perguntas acima se torna mais implícito: não o tipo concreto no código, mas o tipo implícito definido pela coleção de componentes que formam uma entidade. Os mesmos princípios orientadores podem ser aplicados.


fonte
1

O que você descreveu (uma classe para cada tipo principal de objeto de jogo lógico) faz todo sentido para um jogo simples. Se esta é a primeira vez que você escreve um jogo desse tipo, sugiro fazê-lo dessa maneira.

Apenas algumas dicas:

  • Um jogador é realmente diferente de um inimigo ? É provável que muitas das funcionalidades sejam as mesmas, portanto, essas devem normalmente ser da mesma classe ou estendidas da mesma classe base. Considere uma classe base AbstractPlayer com duas subclasses HumanPlayer e AIPlayer - todas as funcionalidades comuns podem ser encontradas no AbstractPlayer .
  • Prefira configurar objetos com composição em vez de herança. Não faça suas hierarquias de herança muito profundas. Se você começar a chamar uma classe ForgeWithSteelAnvil , deverá ficar preocupado: Uma Forja pode ser uma subclasse de Construção , mas o tipo de bigorna usada deve ser um objeto contido na construção.
  • Da mesma forma, prefira propriedades que permitem configurar objetos em vez de adicionar centenas de classes de objetos ligeiramente diferentes.

Em jogos mais complexos, existem técnicas mais avançadas que você pode usar, mas sugiro não usá-las até que você esteja muito confortável com a abordagem básica de POO (ou seja, tenha feito alguns jogos concluídos com êxito). Abordagens mais avançadas podem incluir:

  • Modelos de objetos baseados em protótipos - use uma classe única para todos os objetos do jogo e modele todos os seus objetos por meio de propriedades / atributos e composição. Muito mais flexível / dinâmico que o OOP padrão, mas mais difícil de gerenciar (em particular, o compilador não ajudará muito se você fizer algo estúpido). Usei isso com bom efeito no meu joguinho Roguelike Tyrant ( https://github.com/mikera/tyrant )
  • Sistemas de componentes de entidade - bom se você tiver muitos comportamentos complexos que deseja misturar e combinar em muitos tipos diferentes de objetos de jogo. Muito poderoso, mas difícil de acertar.
Mikera
fonte
0

Existem alguns métodos que você pode usar para abordar a organização de suas entidades e conjuntos de dados. Prefiro escrever um documento de planilha e testar os dados indo e voltando para ter certeza de que estou sendo eficiente. Se você está fazendo o jogo, lembre-se de que ele precisa fazer sentido para você. Às vezes, a rota mais eficiente é ser um pouco menos eficiente no código para simplificar o projeto.

Se você quiser ter mais ajuda para estruturar seu conteúdo, encontre um código-fonte antigo do jogo que use uma estrutura ou estilo semelhante e encontre a solução. Depois, refine-o e corrija-o ao seu gosto.

Belzebu
fonte
-1, pois isso não parece abordar a organização do código e a sugestão de copiar cegamente o que algum outro jogo faz sem discutir maneiras de entender as vantagens e desvantagens de quaisquer decisões de design que o jogo tomou.