Estou desenvolvendo um jogo espacial 2D para dispositivos móveis, mas ele se torna muito complexo e minha solução é bastante confusa e produz muitos segmentos de código repetidos.
Eu tenho uma classe mundial em que eu tenho listas multible de diferentes objetos como:
List<Enemy> enemys;
List<Projectile> projectiles;
List<Collectable> collectables;
List<Asteroid> asteroids;
List<Effect> effects;
..
Cada lista é atualizada pela classe mundial. mas isso não é tudo. Cada inimigo tem uma lista de mecanismos e lista de lançadores de armas que são atualizados pelo inimigo. Agora, cada mecanismo adiciona alguns efeitos de fogo à lista mundial de 'efeitos', e cada lançador de armas adiciona projéteis à lista mundial de 'projéteis'. Todas essas classes têm parâmetros diferentes, então eu preciso de uma atualização extra E da função de renderização extra para cada classe.
Pelo menos eles são todos filhos de 'GameObject', que fornece itens básicos como vetores de posição, velocidade e aceleração, polígonos delimitadores e funções como applyForce e uma máquina de estados finitos
Existe uma maneira melhor ou mais comum de fazer isso? como uma classe abrangente que contém todos os parâmetros e métodos possíveis para todos os objetos diferentes. (acho que isso produziria um código ainda mais confuso)
fonte
Respostas:
Sim, isso é chamado de arquitetura baseada em componentes . Dê uma olhada aqui para mais detalhes.
Isso permitiria apenas uma lista de entidades em sua classe mundial:
É um exemplo de composição sobre herança .
fonte
Dentro dos limites da sua pergunta original, uma opção seria dividir as listas em Ações, em vez de Tipos como o que você possui. Por exemplo, você teria o
List<HasAI>
e um paraList<Collidable>
e quando você cria um novo objeto, ele se adiciona a qualquer lista de ações de que precisa, quando o objeto é destruído, ele se remove dessas listas. Um objeto pode estar em várias listas.A segunda etapa dessa opção é refatorar suas classes de uma hierarquia para uma que use interfaces, portanto seu tipo HasAI é uma classe que implementa a interface IBrains como exemplo. Correspondência de que
List<HasAI>
apenas os objetos precisam ter a interface IBrains.Isso deve ajudar a limpar parte da complexidade.
fonte
Eu acho que o que você precisa fazer é abstrair a renderização em suas próprias classes, acho que uma para o jogador e outra para o inimigo (ou talvez apenas uma para o jogador, e depois criar uma instância para o jogador e o inimigo - não 100% de certeza do seu design de jogo.)
Você pode usar um padrão de visitante para deixar o renderizador percorrer os vários objetos e decidir o que desenhar, que pode ser menos complexo.
fonte
Usar uma classe base e confiar no polimorfismo é uma ideia muito boa. Mas existem algumas abordagens alternativas. Há dois artigos de Noel Llopis que valem a pena ser lidos. Ultimamente, tenho estudado o Design Orientado a Dados e acho que ele tem algum mérito.
Os artigos estão aqui e aqui . Isso pode simplificar seu código um pouco mais do que o polimorfismo. Mas, como qualquer coisa YMMV, dê uma olhada e veja se ele se encaixa no que você está tentando alcançar. O polimorfismo usa herança e o DOD usa agregação, ambos têm prós e contras, portanto escolha seu veneno.
fonte
Você pode utilizar OOP e, principalmente, polimorfismo.
Basicamente, você precisa criar uma classe base, da qual todas as entidades do jogo herdam. Essa classe base, o mais abstrata possível, conterá itens como a função Criação, Atualização e Talvez uma função Destruir.
Então você obtém todos os seus outros objetos de jogo dessa classe. Você provavelmente também precisará adicionar algum tipo de reflexão ao seu código se o seu idioma não o suportar, para fazer coisas mais avançadas, mas é evitável se você souber estruturar sua herança corretamente.
fonte