Pular para o conteúdo
Início » Programação » Tutorial: XNA Invasores – Parte 2

Tutorial: XNA Invasores – Parte 2

Logo do XNAAntes de começar a programação, geralmente um jogo passa por uma grande fase de planejamento e projeto. Não é difícil imaginar o motivo disto, afinal mesmo que um jogo casual não envolva centenas de profissionais nem custe milhões pra ser produzido, ele ainda é um software complexo e o rumo pode ser facilmente perdido se não houver um documento mostrando o rumo a ser seguido.
Este tutorial não visa detalhar este planejamento, meu objetivo maior é ensinar a programar um jogo, porém pelo menos uma visão geral do que será feito deve ser estruturada para que a gente não se perca no processo.
Obviamente, quando se faz um novo tipo de jogo a necessidade de análise (para estipular requisitos como jogabilidade, objetivos, personagens…) é bem maior, por isso mesmo eu decidi começar com um clone de um jogo bem conhecido. Uma vez que a maioria das pessoas conhece o Space Invaders, podemos apenas observar seu funcionamento e criar um modelo baseado no que vemos.

Para começar, vamos olhar a tela principal do jogo (imagem acima) e tentar identificar o fluxo do jogo e os principais objetos envolvidos.
No Space Invaders, nós controlamos uma nave que pode se mover horizontalmente e atirar para cima. Temos também as naves inimigas que se movem horizontalmente e, ao atingir um dos cantos da tela, desce um pouco em direção ao jogador. Essas naves também têm a capacidade de atirar para baixo. Entre o jogador e os inimigos temos quatro escudos que vão sendo destruídos conforme são atingidos por tiros. O jogo acaba quando todos os inimigos são destruídos (condição de vitória) ou quando as vidas do jogador acabam ou as naves inimigas atingem um limite inferior na tela (condições de derrota).
Pronto, o parágrafo acima sintetiza, ainda que de forma incompleta, o funcionamento principal do jogo. Baseado nesta descrição, já podemos identificar algumas entidades que atuam no jogo, que serão transformadas em classes. Além das entidades facilmente identificáveis (nave do jogador, nave inimiga, escudo, tiro), temos uma série de outras classes necessárias para o jogo. Eu identifiquei várias classes e as descrevo a seguir, mas em outra análise, outras pessoas podem achar a necessidade de criar outras classes ou mesmo excluir algumas do meu modelo.

O Diagrama de Classes acima mostra as classes que serão implementadas no jogo. Eu incluí apenas os atributos mais importantes e não listei nada dependente de tecnologia, de forma que o modelo pode ser facilmente usado sem o XNA. Também decidi não listar os métodos para deixar o modelo mais simples, mas vamos adicioná-los conforme o jogo for sendo desenvolvido.
Agora vamos ver qual a função de cada classe do modelo:

  • Entidade: como vários objetos no jogo têm como característica comum o fato de ocuparem um lugar no espaço, esta classe abstrata foi criada para servir como ponto de partida para estas entidades, diminuído a repetição de código.
    Obs.: veremos na hora da implementação que a Entidade tem algumas características adicionais, como uma referência para o jogo que a criou, e que ela herda da classe DrawableGameComponent do XNA Framework, o que é uma justificativa adicional para sua existência.
  • Nave: mais uma classe abstrata. Neste caso, teremos vários tipos de nave no jogo que terão características em comum, portanto a criação desta classe abstrata também é bem natural.
  • NaveInvasor: representa as naves inimigas que se movem e atiram no jogador.
  • NaveBonus: é aquela nave que passa pelo topo da tela e oferece um bônus cumulativo na pontuação se for atingida. Para cada nave atingida, o valor da próxima nave será maior. O atributo estático contador é responsável por manter um registro de quantas já foram destruídas.
  • NaveJogador: a nave controlada pelo jogador. Perceba que ela é responsável pelo controle de vidas e pontos.
  • ControladorDeNaves: o jogo terá várias fileiras de naves que deverão ser controladas. Ao invés de jogar este controle dentro do laço principal do jogo, uma classe foi criada para gerenciá-las, o que deixará o código mais organizado. Como apenas uma nave inimiga poderá atirar por vez, a controlador de naves é que deverá controlar a criação e destruição do tiro, ao invés de deixar que está tarefa seja executada diretamente pela classe NaveInvasor. Esta decisão irá minimizar em muito os testes que serão feitos na hora de verificar se uma nave atirou e a colisão desse tiro com os outros objetos.
  • Tiro: simplesmente representa um tiro que foi disparado por uma nave.
  • Escudo: um escudo é na verdade um conjunto de células (veja a seguir). Esta classe basicamente irá gerenciar as células (assim como o ControladorDeNaves), ao invés de deixá-las sendo acessadas diretamente, por motivos de organização.
  • CelulaEscudo: representa cada uma das células usadas para compor um escudo. A célula tem um tipo variável de acordo com a sua posição (veja, por exemplo, que a célula superior esquerda é diferente da célula superior direita) e uma energia que representa o quanto ela foi danificada pelos tiros.
  • JogoInvasores: a lógica central do jogo é controlada por esta classe. É esta classe que será responsável pela criação e destruição dos principais elementos do jogo, bem como a exibição de menus e mensagens de derrota ou vitória ao jogador.

Muito bem, agora já temos um modelo de classes sobre o qual trabalhar. Na próxima parte veremos um Diagrama de Atividades que irá descrever o fluxo principal do jogo (o algoritmo que deverá ser seguido para o jogo funcionar) e enfim poderemos partir para a implementação. Até lá.
P.S.: Qualquer dúvida ou sugestão sobre o conteúdo do tutorial, não deixem de falar nos comentários. Se alguma coisa não ficou muito clara (como a parte de UML), perguntem que eu explico com mais detalhes.

Relacionados e Publicidade