quinta-feira, 6 de agosto de 2009

Tutorial - Nosso Primeiro Jogo 2D - Extra


Este será o nosso último tutorial da série de desenvolvimento do nosso primeiro jogo 2D. Esse tutorial foi baseado nos vídeos Beginners Guide to 2D Games encontrado no site creators.xna.com.

Nesta última parte iremos surpreender os jogadores do nosso simples jogo com explosões bem legais a cada destruição.

Salvando as Novas Imagens e Adicionando ao Projeto

Começaremos esta parte do nosso tutorial, adicionando ao nosso projeto as imagens que usaremos para a explosão e a fumaça de nossas explosões. Para isso vamos salvar as imagens abaixo com seus seguintes nomes em nosso PC clicando com o botão direito do mouse.

explosion:

smoke:
Agora, no Visual C# Express Edition, no Solution Explorer, vamos clicar com o botão direito do mouse na pasta Sprites que está dentro de Content. Agora iremos adicionar as novas imagens assim como fizemos com as outras, clicando em Add->Existing Item e selecionando as novas imagens no local onde as salvamos.


Criando o Sistema de Particulas

Para fazer as explosões dos aviões inimigos no nosso jogo iremos precisar de um sistema de particulas para que fiquem mais realistas as explosões e a fumaça.

Assim ainda no solution explorer, vamos criar uma nova classe que será a responsável por cada particula de efeito no nosso jogo, clicando em Belonave->Add->New Item->Class, o nome do arquivo se chamará Particle.cs.

Essa nossa classe será uma classe pública, assim vamos mudar a declaração dela para public class Particle. E não podemos esquecer também de mudar os using para os do XNA como na figura abaixo.


Nossa partícula terá os seguintes atributos: position; velocity; acceleration; lifetime, por quanto tempo a particula ficará viva; timeSinceStart, quanto tempo já passou desde que ela foi criada; scale; rotation; rotationSpeed, a velocidade da rotação da particula; e também o isActive, que indicará se a partícula ainda está "viva".


Nossa partícula também terá dois métodos, um para inicializa-la e um para atualiza-la. O primeiro irá inicializa-la em uma posição, com uma velocidade e aceleração, um tempo em que ficará viva, sua escala e a velocidade de sua rotação. Daremos também, ainda nesse primeiro método, o tempo desde que foi iniciada a particula como 0.0 já que esse método é o que inicializa nossa particula. Se estivermos atentos iremos perceber que ainda falta inicializarmos a rotação, mas isso faremos em outro momento mais a frente.


Agora trataremos da parte de atualização da nossa particula. O que faremos basicamente é manter os atributos dela atualizados a cada intervalo de tempo.

Agora que temos nosso modelo de particula, podemos criar o nosso sistema de particulas, que será responsável por gerenciar todas as particulas do nosso jogo. Assim como fizemos para criar o Particle.cs, vamos fazer o mesmo para criar o ParticleSystem.cs.

Mas nessa nossa nova classe, não só trocaremos os using, e tornaremos ela pública, como também a tornaremos abstrata e faremos ela herdar da classe DrawableGameComponent. Isso significa que ela irá proporcionar as funcionalidades básicas para criarmos um efeito de partículas. Outras subclasses irão extender os efeitos dessa classe de uma maneira mais customizada.


Ela terá acesso a diversos atributos de outras classes como do objeto ao qual daremos o efeito de explosão e fumaça. Teremos também um gerador de números randomicos para dar mais realidade ao nosso efeito.


Outras constantes também serão necessárias pois serão usadas nos sistemas de particulas mas especializados que criaremos a seguir. Continuaremos na linha onde paramos anteriormente.



Agora poderemos passar para o construtor da nossa classe. No construtor receberemos o nosso Game, o numero de particulas que esperamos ver na tela a cada momento e o nome da nossa textura.

Nossa classe terá também a implementação das funções Initialize, LoadContent, Update e Draw. Mas antes de começarmos a implementá-las, temos que implementar diversos métodos auxiliares para nosso sistema de particulas, ainda continuando abaixo de onde paramos antes.
Agora abaixo das implementações que acabamos de fazer, vamos implementar os métodos Initialize:

LoadContent:



Update:

e Draw:

E temos também que lembrar que deixamos para setar o atributo rotation da classe Particle, o que faremos agora:

Sistemas de Particulas Customizados

Agora que já temos a base do nosso sistema de particulas, podemos começar a trabalhar nos nossos sistemas especializados em explosões e fumaça. Como fizemos para adicionar o Particle.cs e o ParticleSystem.cs, vamos adicionar também mais dois arquivos ao nosso projeto, o ExplosionParticleSystem.cs e o SmokeParticleSystem.cs.

Faremos também as mesmas alterações dos using que fizemos nos outros arquivos e tornaremos estas classes também públicas e as faremos herdar do nosso recém finalizado ParticleSystem.

Devido ao grande trabalho que tivemos implementando o nosso ParticleSystem, nessas nossas classes especializadas, só precisaremos implementar três funções: a InitializeConstants(), InitializeParticle() e o construtor delas.

Começaremos pela classe ExplosionParticleSystem:

Seu construtor:
InitializeConstants:

InitializeParticle:
Agora na classe SmokeParticleSystem:

Seu construtor:
InitializeConstants:

Agora, para finalizarmos, devemos ir a nossa classe Game.cs e fazer as seguintes alterações:

Mais algumas variáveis:


Construtor:
UpdateCannonMissiles:

Ahh... ainda em Game.cs não podemos esquecer de um último detalhe:


Se não nos esquecemos de nenhum detalhe, podemos rodar nosso jogo e veremos explosões e fumaças realistas ao derrubarmos cada aeronave inimiga.

Resumo

Esta foi a ultima parte do nosso tutorial de como criar um jogo 2D com o XNa Game Studio. Nela conseguimos criar um sistema de particulas e simular explosões e fumaça no nosso jogo... Poderiamos expandir esse sistema para abordar outras formas de particulas como um brilho mágico, neblina, sei lá, depende da sua imaginação.

Espero que as coisas fiquem bem claras e qualquer dúvida não exitem em entrar em contato comigo, via comentários, via e-mail, etc.

Sei que ficou bastante "cuspido" esta ultima parte, mas é resultado da minha falta de tempo, por isso estou bem aberto para responder a duvidas sejam quais forem.

Espero que tenha ajudado e que a maioria tenha gostado.

Em breve colocarei uma enquete aqui para saber qual será a temática do próximo tutorial.

Abraços a todos.

14 comentários:

Anônimo disse...

Oi Leo. Primeiro, parabéns pelo seu blog. Muito bom. Mas com relação a este último post, estou tendo problemas com o SpriteBatch e o SpriteEffects. O Visual Studio não compila de jeito nenhum. Eu acho que vc esqueceu também o método SpriteEffects, já que tem o SpriteBatch. Estou louco pra ver o efeito da explosão.

Leonardo Nascimento (leocamello) disse...

Estive dando uma olhada no meu código e encontrei diversos lugares em que uso o SpriteEffects. Todos como SpriteEffects.None:

- Game.cs: método Draw, onde desenhamos os mísseis, onde desenhamos o canhão e onde desenhamos os aviões inimigos;
- ParticleSystem.cs: método Draw, onde fazemos o game.SpriteBatch.Draw(...)

Um dos possíveis motivos de erro do spriteBatch pode ser na declaração das variáveis em Game.cs.
Fazemos a seguinte declaração:

"GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;"

Abaixo dessa declaração de spriteBatch temos que fazer um get público para conseguirmos acessar o spriteBatch a partir do ParticleSystem.cs.
Assim temos que adicionar o seguinte trecho no Game.cs:

"SpriteBatch spriteBatch;
public SpriteBatch SpriteBatch
{
get{ return spriteBatch; }
}

Acho que isso resolve seu problema.

Abraços

Ricardo Martins disse...

Viva Leo!

Gostei muito do teu jogo! Sou português e estou a gostar de "brincar" com XNA!! Mas estou com um problema, já fiz todos os passos e mesmo assim tenho um erro de compilação: "Microsoft.Xna.Framework.Game' does not contain a definition for 'SpriteBatch' and no extension method 'SpriteBatch' accepting a first argument of type 'Microsoft.Xna.Framework.Game' could be found (are you missing a using directive or an assembly reference?)" Isto acontece mesmo depois de ter feito o get público ao método SpriteBatch na classe Game. Só não consigo ver as explosões!!!

Podes ajudar?
Obrigado
Ricardo.

Jordão disse...

Olá. Parabéns pelo blog, mas tambem estou com o problema acima, acho que esta faltando o metodo "LoadContent", tambem não consigo ver as explosões!!!

Obrigado

Unknown disse...

Olá.
Muito legal sua explicação. Obrigado por compartilhar conhecimentos.

Mas da uma olhada nas imagens, pois você colocou duas vezes a mesma imagem, consequentemente pulou uma.

E faltou a do LOADCONTENT.

Ai o jogo não fica completado.

Abraços.

Anônimo disse...

Ola, já faz algum tempo que o tutorial foi feito, mas se alguem tem a parte do LoadContent() e pudesse postar eu ficaria muito grato. Desde ja agradeço.

Anônimo disse...

pessoal jah mandei um e-mail pro camello e ele acobou de corrigir as imagens erradas dessa parte do tuto,agora jah podemos ver as explosoes tah td certo.

vlw Camello por ter corrigido

Unknown disse...

Cara, fiz até essa parte dando tudo certinho, chega aqui eu empaco, revisei todo o código duas vezes, e nada. Esta tudo igual ao seu.
Eu só não deixei de notar, desculpa se eu estiver falando bobagem, mas você não usou os png's da explosão e da fumaça, não vi referência a eles? isso está certo?
Até mais e vlw!

Leonardo Nascimento (leocamello) disse...

Lucas, no Construtor(img_71.jpg) fazemos referencia as imagens, dê uma conferida. Abraços

LayBoy disse...

ola Leo, Gostei muito do seu tutorial e muito Legal... olha podes so me esclarecer uma coisinha é que fiz tudo e não me dá nenhum erro mas não consigo ver o efeito explosivo.

Abraços!!!

Anônimo disse...

Olá, primeiramente parabens pelo blog
estou aprendendo muito aqui.
gostaria de pedir, que se possivel, disponibilize o projeto para download

estou tendo problemas com o
protected virtual void InitializeParticle(Particulas p, Vector2 onde)
{
}

aqui esta alegando "Inconsistent accessibility", oque sera que errei?
vou tentar olhar novamente ... mas se tiver o codigo fonte ficaria mais facil de me localizar
pois devo ter copiado algo errado
obrigado

morangus2 disse...

nessa base:

public override void Draw(GameTime gameTime)
{
game.SpriteBatch
base.Draw(gameTime);
}

ele acha o game mas não o SpriteBatch depois do ponto...
Obs.:Uso o XNA 4.0

Parbens pelo tutorial, apesar de estar perdidos em alguns comandos, achei simplesmente genial =D;

Anônimo disse...

Boa tarde Leo, tudo bem? Primeiramente devo agradecer pelos tutoriais que você tem criado, eles são fáceis e simples de entender. Me ajudaram muito em um trabalho da faculdade que estou fazendo e se possível gostaria de uma ajuda sua.
Como eu posso finalizar o jogo???
Por exemplo: Tenho um procedimento dentro do UPDATE que fica verificando se a minha variável life_Jogador é igual a zero. Quando for gostaria paralisar a posição atual do jogo e mostrar a mensagem de Game Over na tela. Poderia me orientar em como fazer isso???
Grato pela atenção

Anônimo disse...

ow eu nao entendi nada, faz videos,e eu to querendo criar um jogo de rpg, faz videos encinando :D