Pular para o conteúdo
Início » Gamedev » Tutorial: XNA Invasores – Parte 4

Tutorial: XNA Invasores – Parte 4

Google News

Logo do XNAHoje vamos começar a implementar o jogo usando o XNA, mas primeiro vamos ver algumas particularidades que diferem o desenvolvimento com XNA do desenvolvimento com outras bibliotecas.
Uma grande diferença do XNA em relação ao que estamos acostumados com outras bibliotecas (como o Allegro ou SDL) é seu modelo de aplicação. Normalmente, quando criamos um jogo ou qualquer outra aplicação que tenha repetição, devemos criar um laço principal onde a lógica central será executada repetidamente até que uma determinada situação ocorra e o programa seja encerrado.
Em C, teríamos algo do tipo:

int main()
{
    // Função para carregar recursos usados no jogo
    CarregarRecursos();
    // Função para iniciar as entidades do jogo
    IniciarEntidades();
    // Laço principal
    while(!fimDeJogo)
    {
        AtualizaEntidades();
        DesenhaEntidades();
    }
}

No código acima os recursos do jogo são carregados e as entidades instanciadas. Após isso, entramos num laço que irá se repetir até que a variável fimDeJogo seja verdadeira.
No XNA, não usamos diretamente este formato. O laço principal é abstraído na classe Game, que será herdada por uma classe no nosso jogo. Esta classe de interface traz um conjunto de métodos que devem ser implementados para definir as ações do jogo, mas eles são chamados internamente e nós não precisamos nos preocupar com estas chamadas.
Basicamente o funcionamento é similar a um ambiente de programação visual, como o Visual C# (com Windows Forms) ou o Delphi. Nestes ambientes, nós escolhemos os eventos de cada componente e programamos o comportamento desejado quando este evento ocorrer. Desta forma, podemos, por exemplo, exibir uma mensagem para o usuário quando ele der um duplo clique em um determinado botão. Mas não é necessário verificar se o botão foi clicado ou não, sempre que for clicado, o método definido para o evento de clique duplo será chamado automaticamente.
Todo jogo no XNA herda da classe Game e deve implementar seus métodos virtuais. Para executar um jogo, criamos uma instância desta classe que herda da classe Game e chamamos seu método Run. Após isto, todos os outros métodos definidos em Game serão chamados automaticamente na ordem correta. A seguir, vemos quais são estes métodos e qual sua ordem de chamada.

Modelo de aplicação do XNA

  • Construtor: o construtor é chamado ao instanciar a classe jogo e antes do método Run. Aqui podemos configurar algumas propriedades do jogo, com as dimensões da tela. O construtor não é parte integrante do modelo de aplicação do XNA, ele é parte da linguagem C# (e da programação orientada a objetos, obviamente).
  • Run: Inicializa o jogo, executa o laço principal e processa eventos. Este método não será sobrecarregado, precisamos apenas chamá-lo. Fazendo isto, os métodos seguintes serão chamados automaticamente.
  • Initialize: Inicializa um componente. Este método é usado para inicializar recursos não-gráficos de um componente.
  • LoadContent: Aqui são carregados todos os recursos do jogo, como imagens, fontes e sons.
  • Update: Agora entramos no laço principal do jogo. Em Update será definido a lógica central do jogo.
  • Draw: A outra parte do laço principal do jogo. Aqui todos os recursos gráficos são desenhados.
  • UnloadContent: chamado quando o jogo é encerrado. Normalmente não precisamos fazer nada aqui, já que o próprio Framework se encarrega de destruir tudo que foi carregado usando o ContentManager (veremos isso futuramente). Caso algo tenha sido carregado manualmente em LoadContent, este é o lugar de descarregá-lo.

Visto isso, vamos finalmente começar a trabalhar com o XNA. A instalação do XNA Game Studio é muito simples. Primeiramente instale o Visual Studio ou o Visual C# Express 2005 e o Service Pack 1 para a versão escolhida. Depois disso, é necessário apenas instalar o XNA Game Studio 2.0 e já temos tudo que é necessário para trabalhar com o XNA.
Com tudo instalado, crie um novo projeto no Visual C# (File -> New Project -> XNA Game Studio 2.0 -> Windows Game (2.0)). Eu chamei meu projeto de Tutorial_XNAInvasores, mas você pode dar o nome que desejar.
Ao usar este modelo, o Visual Studio nos dá um projeto preparado para trabalhar com o XNA, já com todas as referências definidas (as DLLs que tem que ser adicionadas ao projeto), um arquivo Game1.cs que é onde vamos implementar nosso jogo e o arquivo Program.cs que contém a função Main do projeto.
Abrindo o arquivo Game1.cs, vemos que uma classe Game1 que herda da classe Game foi definida automaticamente. Mude o nome da classe de Game1 para JogoInvasores, apenas pra ter um nome mais significativo. Ao re-nomear a classe, você terá a opção de re-nomear automaticamente todas as referências a ela. Para fazer isto, pressione Shift+Alt+F10 ou clique no sublinhado vermelho que aparece no nome e escolha a opção Rename ‘Game1’ to ‘JogoInvasores’. Aproveite e mude também o nome do arquivo em que a classe está de Game1.cs para JogoInvasores.cs (no Solution Explorer, clique com o botão direito em Game1.cs e escolha Rename).
Vamos esquecer esta classe por uns instantes e dar uma olhada no arquivo Program.cs. É neste arquivo que temos a função Main do programa, que como você já deve saber, é o ponto de início de qualquer programa. Neste caso temos o seguinte:

using System;
namespace Tutorial_XNAInvasores
{
    static class Program
    {
        ///
        /// The main entry point for the application.
        ///
        static void Main(string[] args)
        {
            using (JogoInvasores game = new JogoInvasores())
            {
                game.Run();
            }
        }
    }
}

Esta parte não é realmente importante para fazer jogos com o XNA, uma vez que o modelo usado na criação do projeto sempre irá criar este arquivo. Porém, é sempre bom entender o que está sendo feito e o código é bem pequeno, então o veremos rapidamente.

using (JogoInvasores game = new JogoInvasores())
{
    game.Run();
}

Esta é a parte que nos interessa. Basicamente, uma nova instância da classe JogoInvasores será criada e seu construtor será chamado. Feito isso, o método Run irá chamar uma cadeia de métodos do XNA (como visto acima) e finalmente entraremos no laço principal do jogo.
Viu como essa parte era pequena? Já acabou. Agora vamos voltar a olhar a classe principal do jogo. Aqui temos dois atributos e duas operações já definidas no construtor, vamos ver então o que cada uma delas faz.

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public JogoInvasores()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
}

Primeiramente, o objeto graphics é uma referência para o gerenciador dispositivo gráfico do XNA. Com ele nós podemos configurar as dimensões da tela e várias outras propriedades, além de ser este objeto que nos permitirá limpar a tela antes de desenhar qualquer coisa nela. Na linha seguinte vem o spriteBatch, que é usado para desenhar imagens e texto na tela.
A seguir temos o construtor do jogo. Nele, o objeto graphics é instanciado, com o parâmetro this que é uma instância da classe Game (ou de uma classe que herde de Game) requerido pela classe GraphicsDeviceManager.
A linha seguinte define o diretório raiz do ContentManager (usado para carregar o conteúdo do jogo, como imagens e sons). O diretório raiz padrão é o mesmo do executável do jogo, mas aqui definimos a pasta Content como raiz. Por exemplo: sem mudar a pasta raiz, poderíamos carregar uma imagem com o caminho “Content\Imagens\imagem”, sendo que a pasta Content deve estar na mesma pasta do executável. Mudando a raiz, o código passaria para “Imagens\imagem”.
Vamos aproveitar o construtor para configurar alguns detalhes do jogo, como as dimensões da tela e o título da janela.
Para alterar o tamanho da tela, basta alterar as propriedades PreferredBackBufferWidth e PreferredBackBufferHeight do objeto graphics criado acima. Estas propriedades definem o tamanho preferido para o buffer criado pelo XNA para desenhar as imagens. Podemos definir então duas constantes com o tamanho desejado e depois atribuir estes valores às propriedades.
Crie as constantes em qualquer lugar fora do construtor.

public const int LARGURA = 640;
public const int ALTURA = 480;

Depois é só atribuir os valores dentro do construtor.

graphics.PreferredBackBufferWidth = LARGURA;
graphics.PreferredBackBufferHeight = ALTURA;

Por padrão, um jogo do XNA começa sua execução em modo janela, mas isto pode ser alterado. Caso queira que o jogo inicie em tela cheia, adicione o seguinte código:

graphics.IsFullScreen = true;

A alteração do título da janela é feita através da propriedade Window da classe Game – esta propriedade retorna uma referência para a janela na qual o jogo está rodando. A partir desta referência, podemos alterar algumas propriedades da janela, como a capacidade de redimensioná-la e seu título. O título é alterado da seguinte forma:

Window.Title = "XNA Invasores - GamedevBR";

Ok, executando o programa agora (aperte F5), vemos uma janela com o tamanho que escolhemos, e se estiver em modo janela, também poderemos ver o título definido na barra de título. Por hora o jogo não faz mais nada, mas na próxima parte as coisas vão começar a ficar mais interessantes. Até lá.

Projeto em execução

O projeto com o que foi feito até agora pode ser baixado aqui.

3 comentários em “Tutorial: XNA Invasores – Parte 4”

  1. Thiago Moreira

    Maravilha, profissional de ponta e da pra ser professor, ja pode ministrar aulas em colega…
    Parabéns

Não é possível comentar.