segunda-feira, 21 de abril de 2008

Colisão

Queria fazer um post sobre como organizar os objetos dentro do código mas eu ainda estou bem perdido nisso :)
Assim sendo, vou falar um pouco de colisão.
Falando bem por alto, algoritmos de colisão tratam de detectar quando objetos colidem (dããã), ou seja, quando um objeto encosta ou penetra outro objeto.
Para a nossa alegria, o XNA facilita a nossa vida enormemente pois na versão 2.0 passou a disponibilizar métodos para tal. Ele ja faz colisão entre sólidos (cubo, esfera...) e não-sólidos(planos, retas...), entre tipos diferentes como esferas e planos... tudo isso com um só método. Com a chamada objeto.Intersect(objetoAlvo) e pronto.
Até ai ótimo mas tudo isso não serve de nada sem o principal. O mais importante da colisão não é a detecção em si, mas a reação dos objetos que colidem.
Um exemplo para ilustrar e para facilitar, vamos trabalhar em 2D:
Um objeto Bola cai perpendicularmente em direção a um objeto Caixa. Em cada um desses objetos, eu crio um atributo _boudingBox do tipo Rectangle que irá guardar a representação geometria desse objeto. Note que o Rectangle não da para usar no teste de colisão com uma das classes que o XNA disponibiliza para tal mas vai ser suficiente para o exemplo já que seu uso é quase idêntico.
Dai, já assumimos que essa bola está acelerando sob ação da gravidade. Logo, pode-se dizer que o Update() dessa bola é:
public void Update() {
...
this.aceleracao.Y = 10f; //aceleração da gravidade
this.velocidade.Y += this.aceleração.Y; //incrementa a velocidade com a aceleração

this.Y += this.velocidade.Y; //muda a posição da bola de acordo com a velocidade
...
}

Pronto, nossa bola está caindo. Agora vamos testar, no Update de quem controla os objetos, se a bola colide com a caixa:
public void Update() {
...
if (obejtoBola._boudingBox.
Intersect(objetoCaixa._boudingBox))
{
//a bola colide com a caixa
}
...
}

Simples, não? Agora você ja sabe que eles colidem, mas e dai?
Daqui em diante temos que implementar a reação que a bola terá ao colidir com a caixa. Para isso, vamos adicionar algumas linhas no Update() da bola.
public void Update() {
...
this.aceleracao.Y = 10f; //aceleração da gravidade
this.velocidade.Y += this.aceleração.Y; //incrementa a velocidade com a aceleração

if (this.estaColidindo)
{
this.velocidade.Y = -
this.velocidade.Y; //inverte a velocidade vertial, ou seja, joga a bola de volta para cima
}

this.Y += this.velocidade.Y; //muda a posição da bola de acordo com a velocidade
...
}

Pronto. Agora toda vez que a bola bater na caixar ela vai para cima de volta. Assim, reproduzimos o "quique" da bola.

Depois dou uma explicada melhor em colisão. Seguem alguns links para quem quiser saber mais:
http://www.harveycartel.org/metanet/tutorials/tutorialA.html Muito bom, tem vários exemplos e alguns applets mostrando a reação de alguns objetos a colisão
http://www.cs.unc.edu/~geom/collide/ Alguns textos, vídeos e exemplos bem interessantes

Nenhum comentário: