Close Menu
    Facebook X (Twitter) Instagram
    Select Game
    • Home, Notícias, Posts Recentes
      • GameHall
        • Análises
        • Curiosidades
        • Guias, Dicas, Segredos
      • Termos de Serviço e Política de privacidade
    • Games e Cosplays
      • Roblox: Códigos, Eventos, Notícias
      • Fortnite
      • World of Warcraft
      • Honkai Star Rail
      • Genshin Impact
      • Elden Ring
      • Listas de Troféus
      • Listas de Conquistas
      • Cosplays
      • One Piece
      • Animes
    • Stories, Looks
      • Web Stories
      • Celebridades, Looks, Reality Shows
    • Pop Top Gaming
    Facebook X (Twitter) Instagram
    Select Game
    Início » Gamedev » Tutorial: XNA Invasores – Parte 5

    Tutorial: XNA Invasores – Parte 5

    Diego Barboza23/04/200810 Mins Read

    Na 5º parte do nosso tutorial vamos ver o funcionamento dos Game Components do XNA, uma adição simples mas que ajuda muito na reutilização de código.
    Antes de começar pra valer, vamos ver uma coisinha que ficou faltando na última parte mas é muito importante: a taxa de quadros por segundo do jogo. O XNA tem duas formas de lidar com a velocidade do jogo, temos uma taxa fixa ou variável.
    Por padrão, o jogo sempre trabalha com uma taxa fixa de 60 quadros por segundo, ou qualquer outro valor definido através da propriedade TargetElapsedTime. Isto é muito interessante quando se faz jogos pro XBOX 360, já que como o hardware é padrão, temos a garantia de que o jogo irá se comportar da mesma forma em todos os videogames.
    No caso dos computadores isto é um grande problema, uma vez que existem inúmeras configurações diferentes e dificilmente o jogo irá se comportar igualmente em duas máquinas distintas. Então, ao invés de fixar o número de quadros por segundo, podemos deixar essa taxa variável e fazer todos os cálculos dependentes do tempo através do parâmetro gameTime que os métodos Update e Draw recebem (veremos isto à frente). Para deixar a taxa variável, apenas adicione a seguinte linha no construtor de JogoInvasores:

    IsFixedTimeStep = false;

    Agora vamos criar a classe mais primitiva do nosso modelo de classes que será herdada por diversas outras classes. Estamos falando, é claro, da classe Entidade. Como veremos, Entidade é um Game Component, mas o que é um Game Component? Você deve estar se perguntando.
    Lembram quando a gente definiu nosso jogo, que herdava da classe Game e com isso vários métodos eram chamados automaticamente? Pois então, os Game Components funcionam da mesma forma. Nós vamos definir um Game Component e adicioná-lo ao jogo, depois disso o próprio jogo se encarrega de cuidar dele e chamar seus métodos.
    Existem dois tipos de Game Components no XNA: o GameComponent, que é um componente comum que NÃO executa operações de desenho e o DrawableGameComponent que possui um método Draw e pode ser desenhado. No nosso caso, iremos usar um DrawableGameComponent.
    Chega de enrolar e vamos criar então a classe Entidade. Com o botão direito sobre o nome do projeto, escolha Add -> New Item. O Visual C# nos dá um modelo chamado GameComponent que já traz a implementação de alguns métodos desta classe, mas como teríamos que fazer muitas alterações neste arquivo (especialmente por não haver um modelo de DrawableGameComponent), escolha Code File no diálogo que se abriu e dê a ele o nome de Entidade.cs. Futuramente, quando for dito para criar um novo arquivo em branco, este é processo a ser feito.
    No novo arquivo criado, vamos fazer referência ao Namespace Microsoft.Xna.Framework que é onde estão definidas várias classes usadas neste arquivo. Aproveitando, crie o Namespace Tutorial_XNAInvasores neste arquivo também (pra quem não se lembra, é neste Namespace que estamos criando nosso jogo).

    using Microsoft.Xna.Framework;
    namespace Tutorial_XNAInvasores
    {
    }

    Dentro do Namespace Tutorial_XNAInvasores, vamos criar a classe Entidade (declarada como abstrata, já que uma Entidade não pode ser instanciada). Como já foi dito, esta classe herda de DrawableGameComponent e com isso possui vários métodos que podem ser sobrescritos. Porém, Entidade também será herdada por várias outras classes do nosso modelo e estas classes terão suas próprias implementações dos métodos de DrawableGameComponent, portanto aqui faremos apenas a parte da herança e deixaremos para sobrescrever os métodos mais tarde.

    public abstract class Entidade : DrawableGameComponent
    {
    }

    Com isto já temos a definição da classe, hora então de definir seus atributos. No modelo, definimos que esta classe teria apenas dois atributos: suas coordenadas X e Y, como dois valores do tipo float. Ao invés de deixarmos estes valores como duas variáveis separadas, vamos usar a classe Vector2 do XNA que define um vetor 2D, que contém uma coordenada X e uma coordenada Y como precisamos, com a vantagem de que muitos métodos do XNA trabalham com instâncias de Vector2, ao invés de valores X e Y separados.
    Para que as coordenas da Entidade possam ser acessadas externamente, seguindo os conceitos de orientação a objetos, o atributo não pode ser público. Precisamos portanto criar métodos de acesso. No C#, temos a facilidade de poder usar propriedades que encapsulam métodos de leitura (get) e escrita (set) em um só. Funciona da mesma forma que seria feito em Java, por exemplo, mas ao invés de termos getValor() e setValor(), temos uma propriedade única que já resolve isso pra gente.
    Vamos nomear então o vetor com as coordenadas de XY de coord, deixando ele como protegido para que possa ser acessado livremente pelas classes que o herdam:

    protected Vector2 coord;

    Na seqüência, criamos a propriedade de acesso ao atributo coord. O método definido por get será chamado sempre que quisermos ler o valor do atributo. Em set, definimos o que será executado ao se escrever um valor em coord.

    public Vector2 Coord
    {
        get { return coord; }
        set { coord = value; }
    }

    Todo GameComponent no XNA tem uma referência para o jogo que o instanciou. Esta referência deve ser passada no seu construtor. No nosso caso, além de passar a referência ao jogo para o construtor, também vamos armazenar esta referência num atributo para que mais à frente possamos acessar algumas propriedades do jogo que serão importantes para as Entidades. Para isso, crie o atributo jogo nesta classe.

    protected JogoInvasores jogo;

    Pra finalizar a classe Entidade, falta apenas definir seu construtor. O único parâmetro recebido aqui será uma instância de jogo. Utilizando a palavra chave base, repassamos o jogo recebido para o construtor de DrawableGameComponente. Dentro do nosso construtor, vamos armazenar esta instância no atributo jogo e definir a posição inicial da Entidade como sendo (0, 0), através da propriedade Zero de Vector2 que retorna um vetor com as coordenadas (0, 0).

    public Entidade(JogoInvasores jogo) : base(jogo)
    {
        this.jogo = jogo;
        coord = Vector2.Zero;
    }

    Seguindo em frente, podemos criar a classe Nave, que é a próxima na hierarquia, mas primeiro vamos criar dois tipos enumerados: EstadoNave (que irá definir os possíveis estados para as naves no jogo) e Direcao (que define as possíveis direções nas quais uma nave pode se movimentar).
    O processo é o mesmo da criação de uma classe, crie um arquivo vazio de nome EstadoNave.cs e adicione o seguinte código:

    namespace Tutorial_XNAInvasores
    {
        public enum EstadoNave
        {
            Ativo, Inativo, Destruido
        }
    }

    Repita os mesmos passos para a criação do arquivo Direcao.cs e cole o a seguir código nele. Veja que aqui definimos valores inteiros para cada valor do enum, isto é importante porque utilizaremos estes valores na hora de mover as naves.

    namespace Tutorial_XNAInvasores
    {
        public enum Direcao
        {
            Esquerda = -1,
            Direita = 1,
            Parado = 0
        }
    }

    Agora sim podemos criar nossa nave. Uma nave em si também é uma classe abstrata, visto que não estaremos criando instancias desta classe, mas sim de suas derivações (NaveJogador, NaveInvasor e NaveBonus). Esta classe irá trazer alguns atributos comuns aos diversos tipos de nave, e também irá implementar o método Draw herdado de DrawableGameComponent (através da herança da classe Entidade), uma vez que todas as naves se desenham da mesma forma. Porém, o método Update ainda não será implementado aqui, já que cada tipo de nave terá um comportamento diferente do outro.
    Começamos de novo com a adição dos Namespaces, que desta vez são dois. Além de Microsoft.Xna.Framework, precisamos adicionar Microsoft.Xna.Framework.Graphics pois estaremos trabalhando com a classe Texture2D deste Namespace.

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    Vamos criar a classe Nave e fazê-la herdar da classe Entidade. Lembre-se que Nave também é uma classe abstrata.

    namespace Tutorial_XNAInvasores
    {
        public abstract class Nave : Entidade
        {
        }
    }

    Teremos quatro atributos nesta classe: estado (define o estado da nave), velocidade (a velocidade de movimento dela), direcao (a direção atual da nave) e imagem (uma textura que representa a nave na tela).

    protected EstadoNave estado;
    protected float velocidade;
    protected Direcao direcao;
    protected Texture2D imagem;

    Inicialmente, o estado de todas as naves será o mesmo: EstadoNave.Ativo. A imagem e as coordendas iniciais (herdada de Entidade) serão definidas pelo jogo no momento da criação da Nave, e os outros atributos serão definidos em cada tipo de Nave mais tarde. O construtor fica assim:

    public Nave(JogoInvasores jogo, Texture2D imagem, Vector2 coord)
        : base(jogo)
    {
        this.imagem = imagem;
        this.coord = coord;
        estado = EstadoNave.Ativo;
    }

    Dos atributos criados, o único que precisa ser visto externamente é direcao. Para isso, vamos criar uma propriedade Direcao. Como precisamos apenas ler a direção da Nave, vamos criar apenas com o método get, sem o método set.
    Obs.: Não tem nenhum problema o tipo de retorno ter o mesmo nome da propriedade porque em tempo de compilação o C# cria um método de nome get_Direcao que é chamado quando usamos esta propriedade, portanto não há conflito de nomes.

    public Direcao Direcao
    {
        get { return direcao; }
    }

    Além da direção, precisaremos também obter uma caixa ao redor da Nave para calcular sua colisão com outros objetos. Para fazer isto, criamos um método que calcula esta caixa com base nas coordenadas atuais e nas dimensões da imagem da Nave. Isto é feito criando uma instancia da classe Reclangle (provida pelo XNA), com as coordenadas XY da Nave (que precisam ser convertidas para int, já que o C# não faz conversões implícitas) e a largura e altura da imagem, obtida através das propriedades Width e Height da classe Texture2D.

    public Rectangle ObterRetangulo()
    {
        return new Rectangle((int)coord.X, (int)coord.Y, imagem.Width,
            imagem.Height);
    }

    Para terminar, falta apenas implementar o método Draw, que é responsável por desenhar as naves. Mas antes disso, precisamos adicionar uma propriedade em JogoInvasores para que seja possível acessar seu SpriteBatch e assim efetuar desenhos na tela. Adicione o seguinte código em JogoInvasores:

    public SpriteBatch SpriteBatch
    {
        get { return spriteBatch; }
    }

    Voltando a mexer com a classe Nave, criamos o método Draw. Este é um método herdado de DrawableGameComponent que recebe como parâmetro uma instancia de GameTime, caso seja necessário basear os desenhos em alguma contagem de tempo.
    O que fazemos aqui é simples: primeiro verificamos se a imagem não é nula (apenas para garantir que o programa não vai dar erro caso a imagem não tenha sido carregada com sucesso) e depois efetuamos o desenho em si. Todas as operações de desenho 2D no XNA iniciam com SpriteBatch.Begin() e finalizam com SpriteBatch.End(). Tudo o que será desenhado vai entre estes dois métodos.
    No caso da Nave, a única chamada necessária é para o método SpriteBatch.Draw(), que recebe como parâmetros a imagem a ser desenhada (o Texture2D recebido no construtor), as coordenadas em que a imagem deve aparecer (um Vector2) e uma cor que pode alterar a coloração da imagem. Para desenhar a imagem sem nenhum efeito, usamos Color.White.

    public override void Draw(GameTime gameTime)
    {
        if (imagem != null)
        {
            jogo.SpriteBatch.Begin();
            jogo.SpriteBatch.Draw(imagem, coord, Color.White);
            jogo.SpriteBatch.End();
        }
        base.Draw(gameTime);
    }

    Com isto terminamos mais uma parte do tutorial. Hoje vimos vários conceitos importantes do XNA, mas o executável gerado pelo projeto vai trazer o mesmo resultado da última parte, já que nenhuma instância de classe foi criada e nenhuma alteração mais significativa no jogo foi feita.
    O projeto do jogo, com comentários no código, pode ser baixado aqui.
    Até a próxima.

    Share. Facebook Twitter Pinterest LinkedIn Tumblr WhatsApp

    Posts Relacionados

    Roblox Luta de Anime tem novos códigos de novembro de 2025 (Anime Fight Codes, AF Codes)

    Blue Lock Rivals tem novos códigos lançados hoje (08/11) e update com o rework de Oliver Aiku (Roblox Bloqueio Azul Rivais, BLR Codes, 08 de novembro de 2025)

    Roblox Rogue Piece ganha novos códigos com o update de Jujutsu Kaisen (Yuta e Gojo, Peça Rogue, Codes de novembro de 2025)

    Roblox Dragon Soul: Códigos de itens grátis de novembro de 2025 (New Codes Alma do Dragão, Anime MMO)

    Roblox Basquete Zero tem novo código com o update Estilo Prateado, Mítico (Basketball Zero Codes, BBZ Codes, update de 08 de novembro de 2025)

    Roblox Lendas do Voleibol tem novos códigos com o update TSO e maestria de Taichou (Volleyball Legends Codes, VBL Codes, Haikyuu Legends, 08 de novembro 2025)

    Publicidade
    Posts recentes
    • Roblox Luta de Anime tem novos códigos de novembro de 2025 (Anime Fight Codes, AF Codes)
    • Blue Lock Rivals tem novos códigos lançados hoje (08/11) e update com o rework de Oliver Aiku (Roblox Bloqueio Azul Rivais, BLR Codes, 08 de novembro de 2025)
    • Roblox Rogue Piece ganha novos códigos com o update de Jujutsu Kaisen (Yuta e Gojo, Peça Rogue, Codes de novembro de 2025)
    • Roblox Dragon Soul: Códigos de itens grátis de novembro de 2025 (New Codes Alma do Dragão, Anime MMO)
    • Roblox Basquete Zero tem novo código com o update Estilo Prateado, Mítico (Basketball Zero Codes, BBZ Codes, update de 08 de novembro de 2025)
    • Roblox Lendas do Voleibol tem novos códigos com o update TSO e maestria de Taichou (Volleyball Legends Codes, VBL Codes, Haikyuu Legends, 08 de novembro 2025)
    • Belo cosplay da Tamamo no Mae, de Fate Grand Order, da Gica
    • Roblox Azure Latch ganha novos códigos em novembro 2025 (New Codes, Fechadura Azul, inspirado em Blue Lock, AL Codes)
    Publicidade
    RSS Select 2.0
    • Battlefield: RedSec pode ser o modo de battle royale de Battlefield 6!
    • Mais jogados no Steam em 26/10: Battlefield 6, PUBG, Marvel Rivals e mais
    • Belo cosplay da Lux Academia de Batalha, de League of Legends
    • Halo ganhará remake e sairá também para PS5
    • Veja este belo cosplay da Lux Academia de Batalha, de League of Legends
    RSS Pop Top
    • Steal a Brainrot on Roblox will have a secret event today, Friday, October 31st? And what to expect from the next official announcement? Times for upcoming events and more
    • See the time and details for Saturday’s Steal a Brainrot Event, from Roblox (October 25)
    • Roblox Anime Eternal has new codes at the beginning of October 2025 (update 18)
    • Kazuha, from Le SSerafim: Instagram update in this week
    • New Roblox event Steal a Brainrot! See the time and more details for this Saturday’s event
    • Termos de Serviço e Política de privacidade
    • Sobre
    • Contato
    © 2025 Select Game - Todos os Direitos Reservados. Imagens e embeds tem foco em divulgação!

    Type above and press Enter to search. Press Esc to cancel.

    Usamos cookies para garantir que você tenha a melhor experiência.