Envie Artigos e Concorra a Prêmios
 
Artigos
Article List
Tutorial de XNA - Parte IV
Continuação do tutorial de XNA para iniciantes, aborda desenho de imagens com áreas transparentes e colisão por pixel.
Enviado por   em 2/1/2008 13:36:05

Até agora, nós descobrimos como é a estrutura de um jogo no XNA, como movimentamos os nossos desenhos, como recebemos as teclas pressionadas no teclado e como funciona um método de colisão. Porém, o método de colisão das “caixas delimitadoras” não é dos melhores, por causa das falhas que ele provoca quando as imagens não preenchem todo o espaço retangular, assim, vamos tratar de um outro método de colisão, a colisão por pixel.

Para o melhor entendimento deste material é necessário que o leitor tenha conhecimentos prévios de C#, de orientação a objetos e que tenha lido as outras 3 partes desse tutorial.
 
 

 

Mas, antes que alguém grite: “Espere ai!! O que é um pixel?? Como assim bitmap??”, eu farei uma pequena explanação sobre os tipos de imagens e suas peculiaridades, assim o leitor vai entender melhor o método de colisão por pixels e a teoria por traz dele.

 

Atualmente dois tipos de imagens são usados com mais freqüência nas aplicações, as imagens de bitmap e as imagens vetoriais. No parágrafos abaixo, falarei sobre as duas, mas, só utilizaremos um tipo nesse tutorial, os bitmaps.

 

O que são imagens de bitmap?

 

Pense em uma tabela enorme, com umas 200 linhas e 200 colunas, agora em cada quadrinho da tabela você coloca um ponto com uma cor diferente, dependendo da disposição das cores dentro da sua tabela, você pode até formar desenhos, essa é a idéia dos bitmaps.

 

Um bitmap é basicamente uma matriz de pontos coloridos onde cada ponto da matriz é chamado de pixel. Podemos perceber isso se aumentarmos o zoom na visualização de uma foto, você perceberá os “quadrados” que formam a imagem, inclusive verá que as curvas ficam “serrilhadas”, já que também são formadas por pontos. Veja o exemplo na foto abaixo:

 

  

 

Esse tipo de imagem é usado em diversas aplicações, como o Paint[1], por permitir a criação de efeitos mais realistas, porém, mais pesados. Um dos problemas que acontece com mais freqüência quando se trabalha com esse tipo de imagem, ocorre quando o usuário tenta redimensionar a imagem, principalmente quando ele tenta aumentá-la.

 

Como as imagens de bitmap são formadas por pontos, quando se diminui a imagem apenas retiramos pontos, tentando manter o padrão, com isso perdemos informação e por conseqüência perdemos qualidade na imagem, no entanto, a visualização não é tão afetada.

 

Um problema maior acontece quando tentamos aumentar uma imagem, o software vai tentar manter o padrão da imagem inserindo pontos com as cores mais próximas dos já existentes, isso causa um “serrilhamento” e o resultado na maioria das vezes não é satisfatório.

 

O que são imagens vetoriais?

 

Bom, vocês já viram os problemas encontrados nas imagens de bitmap, agora imaginem uma gráfica, onde as imagens são redimensionadas várias vezes para reproduzir a mesma imagem em vários tipos de documentos e onde geralmente se precisa do melhor resultado possível na apresentação de um trabalho. Lógico que se fossem usados somente bitmaps nesse tipo de ambiente, diversos problemas iriam surgir, por isso se usa um outro tipo de imagem, as imagens vetoriais.

 

As imagens vetoriais são formadas por equações matemáticas que formam os objetos desenhados, quando alguém tenta redimensionar uma imagem dessas, os pontos são recalculados e a imagem é refeita sem perder qualidade. Esse tipo de imagem é ideal para desenhos que são redimensionados diversas vezes, como no caso da gráfica. Um software bastante conhecido que utiliza imagens vetoriais é o Corel Draw.

 

Nos jogos 2D, em quase toda a sua totalidade, são usadas imagens de bitmap e agora que já sabemos o básico sobre os tipos de imagem já podemos falar sobre as colisões por pixel.

 

Como funciona a colisão por pixel?

 

A idéia é bem simples, se duas imagens estão colidindo, as suas áreas retangulares possuem uma interseção, uma área comum formada por suas “caixas delimitadoras” (lembre dos conceitos vistos na outra parte do tutorial sobre colisão por “bounding box”), como as imagens usadas são duas imagens de bitmap essa interseção, na verdade, é formada por duas áreas sobrepostas e essas áreas também possuem seus respectivos pixels. Veja o exemplo:

  

 

Aqui temos duas imagens, um cavaleiro desferindo um golpe e um dragão, as imagens estão sobrepostas de modo a formar uma área comum, destacada em amarelo. Se estivéssemos usando o modo de colisão por Bounding Box, o dragão já teria sido atingido e isso seria mentira, pois o cavaleiro está a uma certa distância do dragão, mas, como a área da imagem é retangular, a colisão seria positiva, ou seja, se a espada do cavaleiro não emitir nenhuma aura mágica que ataque a distância, estaríamos apelando e o pobre dragão sofreria um dano injusto. :-)

 

No nosso caso, a espada do cavaleiro desfere apenas golpes físicos e precisamos testar se ele acertou o dragão ou não, então, o método que já conhecemos não é adequado e precisamos usar colisões por pixel.

 

Vejamos mais alguns exemplos sobre colisões destacando áreas comuns em algumas imagens, é a partir dessa área que vamos descobrir se existe colisão ou não, repare que se não existir área comum, a colisão já está descartada. Considere a área branca dentro dos retângulos pontilhados como transparente. 

 

 

Repare que nos três exemplos, se estivéssemos usando o método de colisão anterior (bounding box) os três casos resultariam em uma colisão positiva. Vale ressaltar que os desenhos são muito simples.

 

Nas imagens que possuem uma área transparente algumas áreas da imagem não são desenhadas na tela. Essas áreas possuem pixels e nesses pixels as cores armazenadas possuem o valor Alpha (responsável pela transparência) com o valor 0 (zero), esse pequeno detalhe é a chave da colisão por pixel. Basta testar as cores dos pixels das duas áreas dessa intersecção, se uma das cores for transparente então não há nada desenhado ali e por tabela, não há colisão, a colisão só vai existir se os pixels presentes na interseção não forem preenchidos, em ambas as imagens, com a cor de transparência.

 

Pronto, agora já sabemos como funciona a colisão por pixels, agora, veremos como implementar esse método no seu jogo.

 

A implementação.

 

Aqui, vou comentar somente sobre os itens que não conhecemos ainda, se você não leu os outros tutoriais, talvez seja uma boa hora para procurar neles algum item que você não conhece. Depois de fazer os comentários eu vou colocar o código por partes (com mais comentários) e depois colocarei o código completo, serão poucas modificações e faremos poucas “continhas”, o mais importante é a lógica usada para resolver o problema.

 

Antes vamos cuidar de um detalhe nas imagens, até agora, todos os nossos desenhos ocupavam toda a área da imagem e nunca nos preocupamos em desenhar uma área da imagem transparente, sempre desenhávamos da mesma cor do fundo. Agora o nosso cavaleiro medieval não ocupa toda a área, inclusive esse é um dos motivos para usarmos colisão por pixel, e para desenhar uma área da imagem transparente precisaremos usar um formato de imagem que suporte transparência, um desses formatos é o PNG.

 

Nesse tipo de imagem são salvos no arquivo informações extras que vão dizer as aplicações quais áreas da imagem são transparentes.

 

Um software gratuito que você pode usar para desenhar as imagens, com suporte a arquivos no formato PNG, é o Paint.NET que pode ser baixado nesse endereço: http://baixaki.ig.com.br/download/Paint-NET.htm

 

Uma imagem com fundo branco não é o mesmo que uma imagem com o fundo transparente, veja a diferença nesse exemplo:

 

 

O fundo quadriculado na imagem representa as área transparente e essa parte da imagem não será mostrada na tela quando estivermos desenhando as nossas imagens no jogo, já as imagens com fundo branco, terão a cor branca desenhada na tela já que pixels brancos também são pixels :-)

 

Você pode encontrar um texto explicando os formatos de imagem suportados pelo XNA no blog da equipe:

http://blogs.msdn.com/xna/archive/2006/08/29/730168.aspx

 

Vamos relembrar a nossa idéia geral, achar a interseção das imagens (isso nós já sabemos fazer), descobrir quais cores estão armazenadas naquela área de interseção (ainda vamos descobrir como) e depois testar se as cores guardadas naqueles locais são transparentes ou não.

 

Manterei muita coisa do exemplo anterior, mudando só o que for necessário:

 

//texturas

Texture2D TexCavaleiro;

Texture2D TexDragao;

 

//sprites

SpriteBatch SpCavaleiro;

SpriteBatch SpDragao;

 

//vetores para as posições

Vector2 posiCavaleiro = Vector2.Zero;

Vector2 posiDragao = Vector2.Zero; //vai ficar parado

 

//objeto para guardar o resultado dos testes de colisao

bool resultado_colid = false;

 

//cor semi-transparente

Color my_color = new Color(255, 255, 255, 150); //branco com transparencia!!

 

 

Esses itens já são conhecidos, se você tem alguma dúvida na utilização desses itens consulte as outras partes do tutorial.

 

Também precisamos de lugar para guardar as cores que estão presentes nas nossas texturas, para isso vamos usar um Array do tipo Color:

 

//array com as cores das texturas

Color[] coresDrag;

Color[] coresCav;

 

No exemplo anterior, o nosso cavaleiro teria velocidade 1, ou seja, ele seria movimentado de pixel em pixel incrementando suas coordenadas de 1 em 1, nesse exemplo eu vou incluir um item que vai controlar sua velocidade, que inicialmente será 5:

 

//velocidade do cavaleiro

int velocidade = 5;

 

Agora vamos às inicializações, nosso dragão ficará sempre parado na posição 200x200:

 

//inicializa outros itens que não requerem a inicalização do dispositivo gráfico

protected override void Initialize()

{

  //dragão na posição (200,200), cuidado!!

  posiDragao.X = 200;

  posiDragao.Y = 200;

 

  base.Initialize();

}

 

Depois carregamos nossas texturas e aproveitamos para pegar as cores das texturas e armazenar nos nossos arrays de cores:

 

//método para carregar as texturas.

protected override void LoadGraphicsContent(bool loadAllContent)

{

  if (loadAllContent)

  {

      //carregando texturas

      TexCavaleiro = recursos.Load<Texture2D>(@"imagens\cavaleiro");

      TexDragao = recursos.Load<Texture2D>(@"imagens\dragao");

 

      SpCavaleiro = new SpriteBatch(config_am.GraphicsDevice);

      SpDragao = new SpriteBatch(config_am.GraphicsDevice);

 

      //determinando o tamanho do meu array

      coresCav = new Color[TexCavaleiro.Width * TexCavaleiro.Height];

      coresDrag = new Color[TexDragao.Width * TexDragao.Height];

 

      //armazenando as cores das texturas em um array

      TexCavaleiro.GetData(coresCav);

      TexDragao.GetData(coresDrag);        

  }

}

 

Repare que o array de cores é criado com o tamanho de cores que tiver na textura, por exemplo, se minha textura do cavaleiro tiver 50x50 (pixels), então o meu array de cores terá de ter um tamanho de 2500 cores, ou seja, a altura vezes a largura da imagem (50x50).

 

//determinando o tamanho do meu array

coresCav = new Color[TexCavaleiro.Width * TexCavaleiro.Height];

 

Agora que eu já sei o tamanho, preciso preencher o array de cores com as cores da textura usando o método GetData da classe Texture2D que copia as cores da textura no array.

 

      //armazenando as cores das texturas em um array

      TexCavaleiro.GetData(coresCav);

 

Um detalhe importante e um pouco óbvio é que eu só posso usar esse método depois de carregar a textura, caso contrário eu não teria o que colocar no array.

 

Depois que carregarmos as texturas e tivermos as cores delas em um array, podemos tratar do método que irá controlar a atualização do nosso “mundo”, o método UpDate, nele iremos testar a colisão e usar a nossa variável que controla a velocidade:

 

protected override void Update(GameTime gameTime)

{

  //um objeto para guardar o status do teclado

  KeyboardState teclado = Keyboard.GetState();

 

  //os retangulos que contem as coordenadas precisam ser

  //atualizados a cada loop, por isso estão aqui.

  Rectangle retanguloCav = new Rectangle((int)posiCavaleiro.X,

  (int)posiCavaleiro.Y, TexCavaleiro.Width, TexCavaleiro.Height);

  

  Rectangle retanguloDrag = new Rectangle((int)posiDragao.X,

  (int)posiDragao.Y, TexDragao.Width, TexDragao.Height);

      

  //veja se algum objeto colidiu

  resultado_colid = testar_colisao_pixel(retanguloCav, retanguloDrag,

  coresCav, coresDrag);

 

  //testando a qual tecla foi pressionada e

  //incrementando a coordenada correta

  if (teclado.IsKeyDown(Keys.Right))

  {

      posiCavaleiro.X += velocidade; //mover para a direita

  }

  else if (teclado.IsKeyDown(Keys.Left))

  {

      posiCavaleiro.X -= velocidade; //mover para a esquerda

  }

  else if (teclado.IsKeyDown(Keys.Down))

  {

      posiCavaleiro.Y += velocidade; //mover para baixo

  }

  else if (teclado.IsKeyDown(Keys.Up))

  {

      posiCavaleiro.Y -= velocidade; //mover para cima

  }

  else if (teclado.IsKeyDown(Keys.Escape))

  {

      this.Exit(); //sair da aplicação

  }

 

}

 

O método UpDate funciona da seguinte forma, primeiro precisamos checar o status do teclado, depois instanciamos dois “Retangulos”, eles irão representar as coordenadas das imagens e serão usados na nossa rotina de colisão, para criar um retângulo basta fornecer dois pontos, um com as coordenadas iniciais e outro com as coordenadas finais, no nosso caso a posição da imagem e as coordenadas de final da imagem (baseadas no tamanho dela), veja o exemplo:

 

  Rectangle retanguloCav = new Rectangle((int)posiCavaleiro.X,

  (int)posiCavaleiro.Y, TexCavaleiro.Width, TexCavaleiro.Height);

 

Esse retângulo terá o mesmo tamanho que a imagem e servirá para encontrarmos a interseção entre as duas imagens. Lembre que a cada movimentação as coordenadas mudam e é por isso que temos de criar o retângulo a medida que precisamos testar novas colisões.

 

Agora que já temos as coordenadas, podemos testar se houve colisão, mais a frente eu vou detalhar o método de colisão.

 

//veja se algum objeto colidiu

resultado_colid = testar_colisao_pixel(retanguloCav, retanguloDrag, coresCav, coresDrag);

 

Depois testamos qual a tecla que foi pressionada e realizamos a ação adequada, aqui eu testarei se a tecla pressionada foi uma das setas direcionais e incremento a posição do personagem usando a nossa variável “velocidade”, por exemplo:

 

  //testando a qual tecla foi pressionada e

  //incrementando a coordenada correta

  if (teclado.IsKeyDown(Keys.Right))

  {

      posiCavaleiro.X += velocidade; //mover para a direita

  }

 

Agora o nosso exemplo está praticamente pronto, só falta explicar o método que testa a colisão, ele receberá como argumentos, as cores das texturas e as coordenadas (através dos retângulos):

 

static bool testar_colisao_pixel(Rectangle retanguloA, Rectangle retanguloB, Color[] coresA, Color[] coresB)

  

Depois nós vamos encontrar a interseção das imagens usando as suas coordenadas:

 

//encontrando as coordenadas da interseção das imagens

int topo = Math.Max(retanguloA.Top, retanguloB.Top);

int inferior = Math.Min(retanguloA.Bottom, retanguloB.Bottom);

int esquerda = Math.Max(retanguloA.Left, retanguloB.Left);

int direita = Math.Min(retanguloA.Right, retanguloB.Right);

 

Agora, baseado nessas coordenadas da interseção, vamos percorrer os arrays de cores para testar se houve colisão, a cada loop, testamos as cores das imagens para verificar se ambas são diferentes da transparência, o que caracterizaria a colisão, como o array só tem uma dimensão, precisamos fazer umas continhas para achar a cor correspondente a área de interseção das imagens e depois testar cada cor dessa área:

 

for (int y = topo; y < inferior; y++)

 {

   //enquanto existirem colunas na interseção, continue procurando pontos

   for (int x = esquerda; x < direita; x++)

   {

    //o array de cores só tem uma dimensão, calcule as coordenadas e

    //retorne a cor daquela posição

    Color corA = coresA[(y - retanguloA.Top) * retanguloA.Width +

    (x - retanguloA.Left)];

    //ache as coordenadas para o outro objeto

    Color corB = coresB[(y - retanguloB.Top) * retanguloB.Width +

    (x - retanguloB.Left)];

 

    //agora que já achou as cores, teste se alguma delas é transparente

    //se nenhuma das cores for transparente, colidiu!

       if (corA.A != 0 && corB.A != 0)

        {

          //encontrou colisão

          return true;

        }

   }

}

 

Agora, já podemos ir para o código inteiro:

 

#region referencias

using System;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

#endregion

 

 

//executando o jogo

namespace meu_jogo

{

  class novo_jogo

  {

      static public void Main() //método principal da aplicação

      {

          jogo teste = new jogo();

          teste.Run();

      }

  }

}

 

//o código da classe jogo, herdado da classe pai "Game"

 

class jogo : Game

{

  //permite a configuração do ambiente

  GraphicsDeviceManager config_am;

  ContentManager recursos;

 

  //texturas

  Texture2D TexCavaleiro;

  Texture2D TexDragao;

 

  //sprites

  SpriteBatch SpCavaleiro;

  SpriteBatch SpDragao;

 

  //vetores para as posições

  Vector2 posiCavaleiro = Vector2.Zero;

  Vector2 posiDragao = Vector2.Zero; //vai ficar parado

 

  //array com as cores das texturas

  Color[] coresDrag;

  Color[] coresCav;

  

  //velocidade do cavaleiro

  int velocidade = 5;

 

  //objeto para guardar o resultado dos testes de colisao

  public bool resultado_colid = false;

 

  //cor semi-transparente

  Color my_color = new Color(255, 255, 255, 150);

  //branco com transparencia!!

 

  //construtor da classe

  public jogo()

  {

      config_am = new GraphicsDeviceManager(this);

      recursos = new ContentManager(Services);

 

  }

 

  //inicializa outros itens que não requerem a inicalização do

  //dispositivo gráfico

  protected override void Initialize()

  {

      //dragão na posição (200,200), cuidado!!

      posiDragao.X = 200;

      posiDragao.Y = 200;

 

      base.Initialize();

  }

 

  //método para carregar as texturas.

  protected override void LoadGraphicsContent(bool loadAllContent)

  {

      if (loadAllContent)

      {

          //carregando texturas

          TexCavaleiro = recursos.Load<Texture2D>(@"imagens\cavaleiro");

          TexDragao = recursos.Load<Texture2D>(@"imagens\dragao");

 

          SpCavaleiro = new SpriteBatch(config_am.GraphicsDevice);

          SpDragao = new SpriteBatch(config_am.GraphicsDevice);

 

          //determinando o tamanho do meu array

          coresCav = new Color[TexCavaleiro.Width * TexCavaleiro.Height];

          coresDrag = new Color[TexDragao.Width * TexDragao.Height];

 

          //armazenando as cores das texturas em um array

          TexCavaleiro.GetData(coresCav);

          TexDragao.GetData(coresDrag);        

      }

  }

 

  protected override void Update(GameTime gameTime)

  {

      //um objeto para guardar o status do teclado

      KeyboardState teclado = Keyboard.GetState();

 

      //os retangulos que contem as coordenadas precisam ser

      //atualizados a cada loop, por isso estão aqui.

      Rectangle retanguloCav = new Rectangle((int)posiCavaleiro.X,

     (int)posiCavaleiro.Y, TexCavaleiro.Width, TexCavaleiro.Height);

    

      Rectangle retanguloDrag = new Rectangle((int)posiDragao.X,

     (int)posiDragao.Y, TexDragao.Width, TexDragao.Height);

      

      //veja se algum objeto colidiu

      resultado_colid = testar_colisao_pixel(retanguloCav, retanguloDrag,

      coresCav, coresDrag);

      

      //testando a qual tecla foi pressionada e

      //incrementando a coordenada correta

      if (teclado.IsKeyDown(Keys.Right))

      {

          posiCavaleiro.X += velocidade; //mover para a direita

      }

      else if (teclado.IsKeyDown(Keys.Left))

      {

          posiCavaleiro.X -= velocidade; //mover para a esquerda

      }

      else if (teclado.IsKeyDown(Keys.Down))

      {

          posiCavaleiro.Y += velocidade; //mover para baixo

      }

      else if (teclado.IsKeyDown(Keys.Up))

      {

          posiCavaleiro.Y -= velocidade; //mover para cima

      }

      else if (teclado.IsKeyDown(Keys.Escape))

      {

          this.Exit(); //sair da aplicação

      }

 

  }

 

  protected override void Draw(GameTime gameTime)

  {

      config_am.GraphicsDevice.Clear(Color.Black);

 

      

      //desenhe o retangulo azul em uma posicão fixa e sempre

      //com a mesma cor.

      SpDragao.Begin();

      SpDragao.Draw(TexDragao, posiDragao, Color.White);

      SpDragao.End();

 

      if (resultado_colid) //se colidiu, desenhe com transparencia

      {

          SpCavaleiro.Begin();

          SpCavaleiro.Draw(TexCavaleiro, posiCavaleiro, my_color);

          SpCavaleiro.End();

      }

      else //em caso contrário desenhe normal

      {

          SpCavaleiro.Begin();

          SpCavaleiro.Draw(TexCavaleiro, posiCavaleiro, Color.White);

          SpCavaleiro.End();

      }

 

  }

  

  //testa a colisao por pixel entre dois objetos

  //recebe como argumentos dois retangulos que formam a interseção

  //das imagens e os arrays de cores das imagens

  static bool testar_colisao_pixel(Rectangle retanguloA,

  Rectangle retanguloB, Color[] coresA, Color[] coresB)

  {

      //encontrando as coordenadas da interseção das imagens

      int topo = Math.Max(retanguloA.Top, retanguloB.Top);

      int inferior = Math.Min(retanguloA.Bottom, retanguloB.Bottom);

      int esquerda = Math.Max(retanguloA.Left, retanguloB.Left);

      int direita = Math.Min(retanguloA.Right, retanguloB.Right);

 

      //agora resta achar as cores de cada ponto da interseção,

      //dentro dos arrays das texturas.

      //enquanto não chegar a coordenada y final da interseção, encontre

      //uma cor para testar.

      for (int y = topo; y < inferior; y++)

      {

          //enquanto existirem colunas na interseção,

          //continue procurando pontos

          for (int x = esquerda; x < direita; x++)

          {

              //o array de cores só tem uma dimensão, calcule as

              //coordenadas e retorne a cor

              //daquela posição

              Color corA = coresA[(y - retanguloA.Top) * retanguloA.Width +

              (x - retanguloA.Left)];

              //ache as coordenadas para o outro objeto

              Color corB = coresB[(y - retanguloB.Top) * retanguloB.Width +

              (x - retanguloB.Left)];

 

              //agora que já achou as cores, teste se alguma delas é

              //transparente

              //se nenhuma das cores for transparente, colidiu!

              if (corA.A != 0 && corB.A != 0)

              {

                  //encontrou colisão

                  return true;

              }

          }

      }

      return false; //não colidiram.

            

  }

  

}

 

Esse código é bem básico, mas, já deve servir como base para um jogo simples, mostra como desenhar uma imagem com uma área transparente e ainda exemplifica a colisão por pixels. Também usei boa parte do código do exemplo anterior, possibilitando uma revisão dos conceitos e ainda aproveitei para falar sobre os tipos de imagens (vetoriais e de bitmap), espero que tenha sido útil e até a próxima parte deste tutorial.

 



[1] Software para desenho de imagens de bitmap simples, que vem com o Microsoft Windows.

 

 

 


Sobre o Autor

???
Não Definido
Não Definido
Ocorreu um erro.
Ocorreu um erro.


Clique para avaliar:

Comentários
" Realmente luciano, em um jogo real, é sempre bom colocar "testes dentro de testes" com o intuito de checar se existe necessidade de executar um teste que exige mais processamento :-)

abraço.
"
Enviado por jferreira em 30/4/2008 18:56:39:
 
" opa josé ferreira blz? parabéns pelo artigo! Sem duvida, esse tipo de colisão chama atenção e impressiona os amantes de 2D!

Pra quem for utilizar esse tipo de colisao em "um jogo real", eu acho interessante que antes de utilizar o teste de colisao por pixel - seria interessante utilizar antes, um teste de colisão "mais rapido" e que não comprometesse o desempenho do jogo; ao inves de utilizar logo de cara a "colisão por pixel", escolha, por exemplo, a colisão com BoundingBox ou BoundingSphere - essa escolha é relativa, e depende das circuntâncias. Dai então, se houver colisão, ai sim, utilize o teste de colisão por pixel.
"
Enviado por lucianoJose em 30/4/2008 18:29:01:
 
" Obrigado jalf, caso alguém note alguma incorreção, por favor avise :-)

"
Enviado por jferreira em 2/1/2008 15:11:00:
 
" massa!"
Enviado por Jose Antonio Farias em 2/1/2008 14:26:00:
 

Adicione seu Comentário
juegos gratis
PrêmiosMinimizar

Envie um artigo para o Sharpgames, colabore com a comunidade e fique famoso! Clique aqui e saiba mais.

Logos do XBox 360, XNA e Games For Windows
Copyright 2006-2012 por SharpgamesPolítica de Privacidade  |  Termos de Uso