namespace Colisao
{
public class TRobo
{
public bool Atirou, Visivel;
public float Angulo, Escala;
public Rectangle Area, Envolucro;
public SpriteBatch Robo;
public TDispositivo Dispositivo;
public Texture2D Textura, TexturaEnvolucro;
public Vector2 Deslocamento, Direcao, Incremento, Inicio, Olhando, Origem, Posicao;
public TRobo (TDispositivo ADispositivo)
{
Dispositivo = ADispositivo;
Angulo = 0.0f;
Area = new Rectangle (0, 0, 0, 0);
Atirou = false;
Deslocamento= new Vector2 (0, 0);
Envolucro = new Rectangle (0, 0, 0, 0);
Escala = 1.0f;
Incremento = new Vector2 (10, 10);
Inicio = new Vector2 (0, 0);
Olhando = new Vector2 (0, 0);
Origem = new Vector2 (0, 0);
Posicao = new Vector2 (0, 0);
Robo = new SpriteBatch (Dispositivo.GDM.GraphicsDevice);
Visivel = true;
}
public virtual void AtualizarEnvolucro (bool AAjusta)
{
double A, Diametro, L;
A = Textura.Height*Escala;
L = Textura.Width*Escala;
Envolucro.X = Convert.ToInt32 ((Origem.X == 0) ? Posicao.X : Posicao.X - (L/2));
Envolucro.Y = Convert.ToInt32 ((Origem.Y == 0) ? Posicao.Y : Posicao.Y - (A/2));
Envolucro.Width = Convert.ToInt32 (L);
Envolucro.Height= Convert.ToInt32 (A);
if (AAjusta) {
Diametro = Math.Sqrt (Envolucro.Width*Envolucro.Width + Envolucro.Height*Envolucro.Height);
Envolucro.X = Convert.ToInt32 (Envolucro.X + (Envolucro.Width-Diametro)/2);
Envolucro.Y = Convert.ToInt32 (Envolucro.Y + (Envolucro.Height-Diametro)/2);
Envolucro.Width = Convert.ToInt32 (Diametro);
Envolucro.Height= Convert.ToInt32 (Diametro);
}
}
public virtual void CarregarTextura (string AArquivo)
{
Textura = Dispositivo.G.Content.Load<Texture2D> (AArquivo);
TexturaEnvolucro= Dispositivo.G.Content.Load<Texture2D> (@"objeto\retangulo");
}
public virtual void Mostrar (float AProfundidade)
{
AtualizarEnvolucro (true);
if (Visivel) {
Robo.Begin (SpriteBlendMode.Additive);
Robo.Draw (Textura, Posicao, null, Color.White, Angulo, Origem, Escala, SpriteEffects.None, AProfundidade);
Robo.End ();
}
}
public virtual void MostrarEnvolucro ()
{
Robo.Begin (SpriteBlendMode.Additive);
Robo.Draw (TexturaEnvolucro, Envolucro, Color.Blue);
Robo.End ();
}
}
public class TVeiculo
{
public double Decorrido= 0.0f, Tempo= 0.0f;
public TPrincipal Principal;
public TRobo Tiro, Veiculo;
}
public class TNave: TVeiculo
{
public TNave (TPrincipal APrincipal)
{
Principal= APrincipal;
Tiro = new TRobo (APrincipal.Dispositivo);
Veiculo = new TRobo (APrincipal.Dispositivo);
}
public void CarregarTexturas (string ANave, string ATiro)
{
Veiculo.CarregarTextura (ANave);
Tiro.CarregarTextura (ATiro);
Veiculo.Area.Width = Veiculo.Dispositivo.VP.Width-Veiculo.Textura.Width;
Veiculo.Area.Height= Veiculo.Dispositivo.VP.Height-Veiculo.Textura.Height;
Veiculo.Area.Y = Veiculo.Dispositivo.VP.Height/2;
Veiculo.Posicao.X = (Veiculo.Dispositivo.VP.Width-Veiculo.Textura.Width)/2;
Veiculo.Posicao.Y = Veiculo.Area.Height;
Veiculo.Olhando.X = Veiculo.Posicao.X;
Veiculo.Olhando.Y = 0;
}
public virtual void Atirar ()
{
if (!Veiculo.Atirou) {
Veiculo.Atirou= true;
Tiro.Posicao.X= Veiculo.Posicao.X + (Veiculo.Textura.Width-Tiro.Textura.Width)/2;
Tiro.Posicao.Y= Veiculo.Posicao.Y - Tiro.Textura.Height;
}
}
public virtual void MostrarTiro ()
{
if (Veiculo.Atirou)
if (Tiro.Posicao.Y <= 0)
Veiculo.Atirou= false;
else {
// Como o envólucro não é uma circunferência, faz-se um ajuste pra abrigar a área de rotação (retângulo externo à circunferência de rotação)
Principal.UFO.Veiculo.AtualizarEnvolucro (true);
Tiro.AtualizarEnvolucro (false);
if ((Principal.UFO.Veiculo.Escala > 0.0f) && Tiro.Envolucro.Intersects (Principal.UFO.Veiculo.Envolucro)) { // Detecção de colisão 2D
Principal.DispararAoColidir_NaveTiro_Com_UFO ();
Veiculo.Atirou= false;
}
else {
Tiro.Mostrar (1.0f);
Tiro.Posicao.Y-= Tiro.Incremento.Y;
}
}
}
}
public class TUFO: TVeiculo
{
protected const float cIntervalo = 1800.0f;
protected const float cEscalaMax = 0.5f; // 50%
protected const float cEscalaIncrementoTaxa= cEscalaMax/40;
public float EscalaIncremento;
public Random Aleatorio;
public Vector2 Alvo;
public TUFO (TPrincipal APrincipal)
{
Principal = APrincipal;
Aleatorio = new Random ();
Alvo = new Vector2 (0, 0);
Tiro = new TRobo (APrincipal.Dispositivo);
Veiculo = new TRobo (APrincipal.Dispositivo);
Decorrido = -cIntervalo;
EscalaIncremento= 0.1f;
Veiculo.Escala = 0.0f;
}
public void CarregarTexturas (string ANave, string ATiro)
{
Veiculo.CarregarTextura (ANave);
Tiro.CarregarTextura (ATiro);
Veiculo.Area.X = Convert.ToInt32 (Veiculo.Textura.Width*cEscalaMax);
Veiculo.Area.Y = Convert.ToInt32 (Veiculo.Textura.Height*cEscalaMax);
Veiculo.Area.Width = Veiculo.Dispositivo.VP.Width - Convert.ToInt32 (Veiculo.Textura.Width*cEscalaMax);
Veiculo.Area.Height= Principal.Nave.Veiculo.Area.Y - Convert.ToInt32 (Veiculo.Textura.Height*cEscalaMax);
Veiculo.Origem.X = Veiculo.Textura.Width/2;
Veiculo.Origem.Y = Veiculo.Textura.Height/2;
Veiculo.Olhando.X = Veiculo.Posicao.X;
Veiculo.Olhando.Y = Veiculo.Dispositivo.VP.Height;
}
public virtual void Atirar ()
{
if (Veiculo.Visivel && !Veiculo.Atirou) {
Veiculo.Atirou = true;
Tiro.Deslocamento= Vector2.Zero;
Tiro.Inicio.X = Veiculo.Posicao.X - Tiro.Textura.Width/2;
Tiro.Inicio.Y = Veiculo.Posicao.Y - Tiro.Textura.Height/2;
Tiro.Posicao = Tiro.Inicio;
Tiro.Direcao = Alvo-Tiro.Inicio;
Tiro.Direcao.Normalize ();
}
}
public void Mostrar ()
{
if (Veiculo.Escala > 0.0f) {
if (Veiculo.Escala >= cEscalaMax) { // Atira e muda o sinal pra diminuir
Atirar ();
EscalaIncremento= -cEscalaIncrementoTaxa;
}
Veiculo.Mostrar (0.0f);
Veiculo.Escala+= EscalaIncremento;
}
else if (Tempo - Decorrido >= cIntervalo) { // Mostra o oponente a cada cIntervalo milisegundos
Decorrido = Tempo;
EscalaIncremento = cEscalaIncrementoTaxa;
Veiculo.Escala = 0.1f;
Veiculo.Posicao.X= Aleatorio.Next (Veiculo.Area.X, Veiculo.Area.Width);
Veiculo.Posicao.Y= Aleatorio.Next (Veiculo.Area.Y, Veiculo.Area.Height);
Veiculo.Olhando.X= Veiculo.Posicao.X;
Alvo.X = Principal.Nave.Veiculo.Posicao.X + Principal.Nave.Veiculo.Textura.Width/2;
Alvo.Y = Principal.Nave.Veiculo.Posicao.Y;
Veiculo.Angulo = OlharPara (Veiculo.Posicao, Veiculo.Olhando, Alvo);
Veiculo.Visivel = true;
Veiculo.Mostrar (0.0f);
}
}
public virtual void MostrarTiro ()
{
if (Veiculo.Atirou)
if (Tiro.Posicao.Y > Tiro.Dispositivo.VP.Height)
Veiculo.Atirou= false;
else {
Tiro.Posicao = Tiro.Inicio + Tiro.Direcao*Tiro.Deslocamento;
Tiro.Deslocamento+= Tiro.Incremento;
Principal.Nave.Veiculo.AtualizarEnvolucro (false);
Tiro.AtualizarEnvolucro (false);
if (Tiro.Envolucro.Intersects (Principal.Nave.Veiculo.Envolucro)) { // Detecção de colisão 2D
Principal.DispararAoColidir_UFOTiro_Com_Nave ();
Veiculo.Atirou= false;
}
else
Tiro.Mostrar (1.0f);
}
}
protected virtual float OlharPara (Vector2 APosicao, Vector2 APosicaoOlhando, Vector2 APosicaoDesejada)
{
Vector2 Direcao, Origem;
Origem = APosicaoOlhando-APosicao;
Direcao= APosicaoDesejada-APosicao;
// Ângulo entre vetores
return (float) (Math.Atan2 (Direcao.Y, Direcao.X) - Math.Atan2 (Origem.Y, Origem.X));
}
}
public class TPrincipal: TPrincipal_Base
{
protected bool MostraEnvolucro= false;
protected override void Disparar_AoInicializar ()
{
Nave = new TNave (this);
AcertosNave= 0;
AcertosUFO = 0;
UFO = new TUFO (this);
}
protected override void Disparar_AoDesenhar ()
{
Navegar ();
if (MostraEnvolucro) {
UFO.Veiculo.AtualizarEnvolucro (true);
UFO.Veiculo.MostrarEnvolucro ();
}
Nave.Veiculo.Mostrar (0.0f);
UFO.Mostrar ();
UFO.MostrarTiro ();
Nave.MostrarTiro ();
MostrarTitulo ();
}
public virtual void DispararAoColidir_NaveTiro_Com_UFO ()
{
AcertosNave++;
UFO.Veiculo.Visivel= false;
}
public virtual void DispararAoColidir_UFOTiro_Com_Nave ()
{
AcertosUFO++;
}
protected virtual void MostrarTitulo ()
{
TituloTexto= "PLACAR (Nave: " + AcertosNave + "; UFO: " + AcertosUFO + ")";
Titulo.Begin ();
Titulo.DrawString (TituloFonte, TituloTexto, TituloPosicao, Color.LightGreen);
Titulo.End ();
}
protected virtual void Navegar ()
{
if (Dispositivo.KS.IsKeyDown (Keys.Enter))
MostraEnvolucro= true;
else if (MostraEnvolucro && Dispositivo.KS.IsKeyDown (Keys.Escape))
MostraEnvolucro= false;
if (Dispositivo.KS.IsKeyDown (Keys.Up) && (Nave.Veiculo.Posicao.Y-Nave.Veiculo.Incremento.Y >= Nave.Veiculo.Area.Y))
Nave.Veiculo.Posicao.Y-= Nave.Veiculo.Incremento.Y;
if (Dispositivo.KS.IsKeyDown (Keys.Down) && (Nave.Veiculo.Posicao.Y+Nave.Veiculo.Incremento.Y <= Nave.Veiculo.Area.Height))
Nave.Veiculo.Posicao.Y+= Nave.Veiculo.Incremento.Y;
if (Dispositivo.KS.IsKeyDown (Keys.Left) && (Nave.Veiculo.Posicao.X >= Nave.Veiculo.Area.X))
Nave.Veiculo.Posicao.X-= Nave.Veiculo.Incremento.X;
if (Dispositivo.KS.IsKeyDown (Keys.Right) && (Nave.Veiculo.Posicao.X <= Nave.Veiculo.Area.Width))
Nave.Veiculo.Posicao.X+= Nave.Veiculo.Incremento.X;
if (Dispositivo.KS.IsKeyDown (Keys.Space))
Nave.Atirar ();
}
}
}
|