Programa da nave completo
Com alguns comentários
Game1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Espaco;
namespace Nave
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Fundo fundo1;
Fundo fundo2;
Fundo fundo3;
Espaco.Nave nave;
SpriteFont fonte;
Song som;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
//Define tela de 800x600
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
//Tela cheia!
//graphics.IsFullScreen = true;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
fundo1 = new Fundo(Content, "fundo", 2);
fundo2 = new Fundo(Content, "nebula1", 4);
fundo3 = new Fundo(Content, "nebula2", 6);
nave = new Espaco.Nave(Content, 4, GraphicsDevice.Viewport.Bounds);
fonte = Content.Load<SpriteFont>("fonte");
som = Content.Load<Song>("trilha");
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(som);
}
protected override void Update(GameTime gameTime)
{
fundo1.Atualizar();
fundo2.Atualizar();
fundo3.Atualizar();
nave.Atualizar();
KeyboardState estadoTeclado = Keyboard.GetState();
if (estadoTeclado.IsKeyDown(Keys.Left)) nave.Volta();
if (estadoTeclado.IsKeyDown(Keys.Right)) nave.Avanca();
if (estadoTeclado.IsKeyDown(Keys.Up))
nave.Sobe();
else if (estadoTeclado.IsKeyDown(Keys.Down))
nave.Desce();
else
nave.PosicaoNormal();
if(estadoTeclado.IsKeyDown(Keys.Space))
nave.PuxarGatilho();
else
nave.SoltarGatilho();
if (estadoTeclado.IsKeyDown(Keys.Escape))
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
fundo1.Desenhar(spriteBatch);
fundo2.Desenhar(spriteBatch);
nave.Desenhar(spriteBatch);
fundo3.Desenhar(spriteBatch);
var posicaoTitulo = new Vector2(7, 7 + 7 * (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds*5));
spriteBatch.DrawString(fonte, "Simulado Prof. Willians", posicaoTitulo - (Vector2.One * 3), Color.Black);
spriteBatch.DrawString(fonte, "Simulado Prof. Willians", posicaoTitulo, Color.Green);
var texto = string.Format("Posicao X:{0}, Y:{1}", nave.Posicao.X.ToString("0000"), nave.Posicao.Y.ToString("0000"));
var dimensoesTexto = fonte.MeasureString(texto);
var posicaoNaTela = new Vector2(GraphicsDevice.Viewport.Width - dimensoesTexto.X, GraphicsDevice.Viewport.Height - dimensoesTexto.Y);
spriteBatch.DrawString(fonte, texto, posicaoNaTela-(Vector2.One * 3), Color.Black);
spriteBatch.DrawString(fonte, texto, posicaoNaTela, Color.Yellow);
spriteBatch.End();
base.Draw(gameTime);
}
}
}Fundo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace Espaco
{
public class Fundo
{
#region [ Campos privados ]
private Texture2D imagem;
private int x;
#endregion
#region [ Campos públicos ]
public int Velocidade;
#endregion
#region [ Métodos públicos ]
public Fundo(ContentManager Content, string assetName, int velocidadeScroll)
{
imagem = Content.Load<Texture2D>(assetName);
Velocidade = velocidadeScroll;
}
public void Atualizar()
{
//Move fundo para esquerda da tela
x -= Velocidade;
}
public void Desenhar(SpriteBatch spriteBatch)
{
//Desenha a primeira imagem
spriteBatch.Draw(imagem, new Vector2(x, 0),Color.White);
//Calcula o x da segunda imagem em relacao a primeira
int x2 = x + imagem.Width;
//Desenha a segunda imagem
spriteBatch.Draw(imagem, new Vector2(x2, 0), Color.White);
//Verifica se a segunda imagem assumiu a posicao inicial da primeira imagem e volta a primeira imagem ao seu lugar inicial.
if (x2 <= 0) x = 0;
}
#endregion
}
}Nave.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
namespace Espaco
{
public class Nave
{
#region [ Campos públicos ]
public Vector2 Posicao;
public int Velocidade;
public int larguraNave;
public int alturaNave;
#endregion
#region [ Campos privados ]
private Texture2D imagem;
private Texture2D imagemProjetil;
private SoundEffect somDisparo;
private List<Projetil> projeteis;
private Rectangle recorte;
private int indiceXAnimacao;
private int indiceYAnimacao = 1;
private int frame = 0;
private int posicaoKeyFrame = 5;
private int direcaoAnimacao = 1;
private bool disparando = false;
private Rectangle dimensoesTela;
private float aceleracaoX;
private float aceleracaoY;
private float impulso = .3f;
private const int NUMERO_PROJETEIS = 50;
#endregion
#region [ Métodos públicos ]
public Nave(ContentManager Content, int velocidadeNave, Rectangle dTela)
{
dimensoesTela = dTela;
Velocidade = velocidadeNave;
string assetName = "naveSprite";
string assetNameProjetil = "projetil";
string assetSom = "silenciador";
imagem = Content.Load<Texture2D>(assetName);
imagemProjetil = Content.Load<Texture2D>(assetNameProjetil);
somDisparo = Content.Load<SoundEffect>(assetSom);
larguraNave = imagem.Width / 3;
alturaNave = imagem.Height / 3;
projeteis = new List<Projetil>();
for (int i = 0; i < NUMERO_PROJETEIS; i++)
{
projeteis.Add(new Projetil());
}
}
public void Sobe()
{
indiceYAnimacao = 0;
aceleracaoY -= impulso;
}
public void Desce()
{
indiceYAnimacao = 2;
aceleracaoY += impulso;
}
public void Avanca()
{
Posicao.X += Velocidade;
aceleracaoX += impulso;
}
public void Volta()
{
Posicao.X -= Velocidade;
aceleracaoX -= impulso;
}
public void PosicaoNormal()
{
indiceYAnimacao = 1;
}
public void PuxarGatilho()
{
disparando = true;
}
public void SoltarGatilho()
{
disparando = false;
}
public void Atualizar()
{
frame++;
frame = frame % posicaoKeyFrame;
//Desacelera a nave
aceleracaoX *= .96f;
aceleracaoY *= .96f;
Posicao.X += aceleracaoX;
Posicao.Y += aceleracaoY;
if (frame == 0)
{
indiceXAnimacao += direcaoAnimacao;
if (indiceXAnimacao == 0 || indiceXAnimacao == 2)
direcaoAnimacao *= -1;
}
//Define qual das naves sera recortada para o desenho
recorte = new Rectangle(larguraNave * indiceXAnimacao, alturaNave * indiceYAnimacao, larguraNave, alturaNave);
}
public void Desenhar(SpriteBatch spriteBatch)
{
//Cria a cada tiro a cada "frame" milesimos de segundo.
if (disparando && frame == 0)
{
foreach (Projetil projetil in projeteis)
{
//Reaproveita os tiros que não sao mais uteis
if(!projetil.Visivel){
projetil.Visivel = true;
//Posiciona o tiro a frente da nave
projetil.Posicao = new Vector2(
Posicao.X + larguraNave,
Posicao.Y + (alturaNave - imagemProjetil.Height)/2);
//Toca o som do tiro
somDisparo.Play();
break;
}
}
}
//Desenha cada tiro VISIVEL!
foreach (Projetil projetil in projeteis)
{
if (projetil.Visivel)
{
spriteBatch.Draw(imagemProjetil, projetil.Posicao, Color.White);
projetil.Posicao.X += Projetil.Velocidade;
if (projetil.Posicao.X > dimensoesTela.Width)
projetil.Visivel = false;
}
}
//Desenha a nave conforme variavel "recorte"
spriteBatch.Draw(imagem, Posicao, recorte, Color.White);
}
#endregion
}
}Projetil.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace Espaco
{
public class Projetil
{
public static int Velocidade = 10;
public Vector2 Posicao;
public bool Visivel;
}
}