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 7

    Tutorial: XNA Invasores – Parte 7

    Diego Barboza11/05/20086 Mins Read

    Logo do XNADe volta com o tutorial XNA Invasores e é hora de adicionar um pouco de ação ao jogo. Hoje vamos dar poder de fogo à nossa nave.
    Iniciamos com a criação da classe Tiro que irá representar os tiros disparados pelo Jogador (e futuramente pelas naves inimigas). Como sempre, criamos uma nova classe (Add -> Class…) e damos a ela o nome de Tiro. Como esta classe também é um Drawable Game Component, fazemos com que ela herde de Entidade (assim com foi feito com a classe Nave).

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    namespace Tutorial_XNAInvasores
    {
        class Tiro : Entidade
        {
        }
    }

    Tiro tem, além dos atributos herdados de Entidade, uma velocidade e um flag “destruir” que indica se o Tiro deve ser destruído pelo Jogo. Além disso temos uma referência para a textura que será usada para desenhar o Tiro.

    private float velocidade;
    private bool destruir;
    private Texture2D imagem;

    O construtor do Tiro é bem simples. Basicamente recebemos suas coordenadas e velocidade, além da imagem previamente carregada e a referência para o Jogo (como já vinha sendo feito com outras classes). Por fim, é necessário apenas definir que o Tiro ainda não deve ser destruído, mudando seu flag “destruir” para false.

    public Tiro(JogoInvasores jogo, Texture2D imagem, Vector2 coord,
        float velocidade) : base(jogo)
    {
          this.imagem = imagem;
          this.coord = coord;
          this.velocidade = velocidade;
          destruir = false;
    }

    No método Update o Tiro será atualizado. Aqui, sua coordenada é alterada somando a velocidade (multiplicada pelo deltaTempo) à sua coordenada Y atual. Desta forma, caso a velocidade seja negativa, o Tiro se move para cima e se a velocidade for positiva, o tiro vai para baixo.
    Como não faz sentido manter um Tiro na memória se ele tiver saído da tela e não puder mais interferir no Jogo, verificamos suas coordenadas para ver se ele está abaixo ou acima da tela. Quando não estiver mais aparecendo, alteramos seu flag “destruir” para true e a classe que criou o Tiro deverá se encarregar de destruí-lo.

    public override void Update(GameTime gameTime)
    {
        coord += new Vector2(0, velocidade * jogo.DeltaTempo);
        if (imagem != null)
        {
            if (coord.Y + imagem.Height < 0
                || coord.Y > JogoInvasores.ALTURA)
            {
                destruir = true;
            }
        }
        base.Update(gameTime);
    }

    O método de desenho segue a mesma lógica do que foi feito com Nave: verificamos se a imagem não é nula, preparamos o SpriteBatch para desenho, desenhamos a textura com as coordenadas do Tiro e finalizamos o SpriteBatch.

    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);
    }

    Para terminar a classe, criamos uma propriedade de acesso ao atributo “destruir” e um método que retorna um retângulo com as coordenadas e as dimensões do Tiro para cálculo de colisão.

    public bool Destruir
    {
        get { return destruir; }
        set { destruir = value; }
    }
    public Rectangle ObterRetangulo()
    {
        return new Rectangle((int)coord.X, (int)coord.Y,
            imagem.Width, imagem.Height);
    }

    Terminada esta etapa, podemos adicionar a seguinte textura ao projeto (da mesma forma que foi feito anteriormente com a textura da nave do jogador). Adicione esta imagem ao projeto ou use uma outra imagem que desejar.
    Para carregar a textura no Jogo, podemos usar um recurso interessante dos Game Components que é a possibilidade de um Game Component gerenciar seus próprios recursos. Quando criamos a classe NaveJogador, sua textura foi carregada em JogoInvasores, mas isto também poderia ter sido feito diretamente em NaveJogador. Agora vamos usar este recurso para carregar a textura do Tiro.
    Em NaveJogador, sobrecarregamos o método LoadContent (definido por DrawableGameComponent) e carregamos a textura do Tiro nele. Antes, porém, precisamos definir um atributo nesta mesma classe para armazenar a textura carregada.

    private Texture2D imagemTiro;
    protected override void LoadContent()
    {
        imagemTiro = jogo.Content.Load< Texture2D >("imagemTiroJogador");
        base.LoadContent();
    }

    Agora precisamos criar um atributo para conter o Tiro disparado pelo Jogador. No modelo que estamos usando, o Jogador será capaz de disparar apenas um Tiro por vez, então uma variável simples já é suficiente. Caso queira que ele possa disparar mais Tiros, será necessário criar um vetor. Aproveitamos para adicionar uma propriedade de acesso a este atributo.

    private Tiro tiro;
    public Tiro Tiro
    {
        get { return tiro; }
    }

    Os Tiros serão disparados quando o Jogador pressionar a barra de espaço e nenhum outro Tiro do Jogador estiver na tela (mantendo o limite de um Tiro por vez). Esta verificação é feita no método Update de NaveJogador.
    Neste método primeiramente precisamos verificar se a barra de espaço foi pressionada (estadoTeclado.IsKeyDown(Keys.Space)). Uma vez que esta tecla tenha sido apertada, precisamos ver se o Jogador pode atirar (usando o flag podeAtirar). Durante o jogo, este flag estará com valor “false” sempre que um tiro disparado pelo Jogador estiver na tela.
    Podendo atirar, vamos criar uma nova instância de Tiro logo acima da nave do jogador (com velocidade negativa para que ela se mova para cima) e definir o flag “podeAtirar” como false.

    public override void Update(GameTime gameTime)
    {
        // Código das partes anteriores
        if (estadoTeclado.IsKeyDown(Keys.Space))
        {
            if (podeAtirar)
            {
                podeAtirar = false;
                tiro = new Tiro(jogo, imagemTiro,
                    new Vector2(coord.X + imagem.Width / 2, coord.Y), -300.0f);
            }
        }
        base.Update(gameTime);
    }

    Para finalizar o método Update, é necessário atualizar o Tiro. Lembre-se que o Tiro é um DrawableGameComponent, mas ele não foi adicionado ao Jogo usando o método Components.Add. Isto não foi feito pois nós vamos manipulá-lo diretamente, chamando seus métodos Update e Draw.
    Ainda em Update de NaveJogador, verificamos se o Tiro não é nulo e chamamos seu método Update. Após isso, verificamos seu flag “destruir” e o destruímos caso o valor seja true. Por fim, caso o Tiro seja nulo, o flag “podeAtirar” passa a ter valor true, ou seja, na próxima iteração o Jogador será capaz de atirar novamente.

    if (tiro != null)
    {
        tiro.Update(gameTime);
        if (tiro.Destruir)
        {
            tiro = null;
        }
    }
    else
    {
        podeAtirar = true;
    }

    Como eu já disse, temos que chamar o método Draw do Tiro manualmente, então vamos fazer isto no Draw de NaveJogador. Aqui é bem simples, basta verificar se o Tiro não é nulo e desenhá-lo a seguir.

    public override void Draw(GameTime gameTime)
    {
        if (tiro != null)
        {
            tiro.Draw(gameTime);
        }
        base.Draw(gameTime);
    }

    E assim chegamos ao fim de mais uma parte do tutorial. Para testar os Tiros, basta pressionar a barra de espaço com o Jogo rodando (repare que você só será capaz de disparar um novo Tiro quando o anterior tiver saído da tela).
    O projeto completo pode ser baixado aqui.

    Jogo

    Share. Facebook Twitter Pinterest LinkedIn Tumblr WhatsApp

    Posts Relacionados

    GTA 6 é adiado para 19 de novembro de 2026

    Progressão de Hearthstone: Primeiras Ranqueadas e recompensas da nova expansão

    Hearthstone: Veja novos decks do meta de Através dos Percursos Temporais

    Deck de Hearthstone – Lynessa Paladin (Paladino), do meta de Através dos Percursos Temporais (+impressões)

    Deck de Hearthstone – Aggro Demon Hunter (Caçador de Demônios), do meta Através dos Percursos Temporais

    Deck de Hearthstone – Mago Elemental Baratinho (Meta de Através dos Percursos Temporais)

    Publicidade
    Posts recentes
    • GTA 6 é adiado para 19 de novembro de 2026
    • Progressão de Hearthstone: Primeiras Ranqueadas e recompensas da nova expansão
    • Hearthstone: Veja novos decks do meta de Através dos Percursos Temporais
    • Deck de Hearthstone – Lynessa Paladin (Paladino), do meta de Através dos Percursos Temporais (+impressões)
    • Deck de Hearthstone – Aggro Demon Hunter (Caçador de Demônios), do meta Através dos Percursos Temporais
    • Deck de Hearthstone – Mago Elemental Baratinho (Meta de Através dos Percursos Temporais)
    • Deck de Hearthstone – Cavaleiro da Morte Deathrattle (Sangue/Profano, Último Suspiro)
    • Deck de Hearthstone – Quest Warlock (Bruxo Missão), do Meta de Através dos Percursos Temporais
    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

    Notícias de Genshin Impact, Honkai Star Rail, Zenless Zone Zero

    • Honkai Star Rail Cyrene Wallpaper Art Full HD 002
      Versão 3.7 de Honkai Star Rail está disponível; veja as principais novidades
    • Honkai Star Rail - Hyacine Wallpaper Full HD
      A temporada atual do “Pura Ficção” em Honkai Star Rail (3.6)
    • Honkai Star Rail Cyrene - Imagem da live da 3.7
      Honkai Star Rail: Códigos da live da 3.7, junto com outros codes de outubro de 2025
    • Genshin Impact - Nefer capa 24-10
      Genshin Impact – As novidades da nova versão Luna II, com Nefer, o modo de jogo Miliastra, e mais
    • Constance - A Dália - Honkai Star Rail capa 01
      A Dália em Honkai Star Rail! Constance é revelada oficialmente e ganha primeira imagem oficial
    • Honkai Star Rail Cyrene capa wallpaper 20-10-2025
      Honkai Star Rail ganha data da live da 3.7; Cyrene jogável pode ser destaque da transmissão
    • 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.

    Nós utilizamos cookies para garantir que você tenha a melhor experiência em nosso site. Se você continua a usar este site, assumimos que você está satisfeito.