• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Kyu

[Java/JSP] Detecção de colisões entre sprites

3 mensagens neste tópico

Existem três abordagens, com as suas vantagens e desvantagens inerentes, para a solução deste problema, que parecendo simples... rapidamente se torna bastante bicudo.

1. Detecção de colisões por intersecção de rectângulos

Uma imagem ocupa sempre um espaço rectangular, independentemente das suas áreas transparentes. Esta abordagem simplesmente verifica se os rectângulos das duas sprites se intersectam.. não tendo em conta a sua área transparente. Isto leva a que colisões sejam detectadas mesmo quando apenas áreas transparentes das sprites intervenientes estejam a colidir.

É a abordagem mais fácil e rápida das três, e também a mais ineficaz.

Implementação:

1) criar uma instância da classe java.awt.Rectangle com a mesma posição e dimensões que a sprite

2) mover essa instância de Rectangle à medida que a sprite é movida

3) sempre que a sprite é movida verificar se o seu Rectangle se intersecta com todos os outros Rectangle das outras sprites através do método da classe Rectangle: public boolean intersects(Rectangle r)

2. Detecção de colisões por comparação de pixels

Basicamente aplica-se a primeira abordagem para detecção de possíveis colisões. Quando é detectada uma possível colisão verifica-se se é de facto uma verdadeira colisão através de comparação pixel a pixel da informação das imagens na área intersectada. Se houver algum pixel em que ambas as imagens tenham informação não transparente é porque a colisão é real, e deve por isso ser tratada.

É a abordagem mais eficaz, no sentido que detecta colisões apenas quando elas realmente acontecem, mas também a mais lenta, visto que necessita de muito processamento.

Implementação:

1) repetir os passos da primeira abordagem

2) obter o rectângulo de intersecção entre as duas instâncias de Rectangle das duas sprites através do método da classe Rectangle: public Rectangle intersection(Rectangle r)

3) obter a informação binária das duas sprites nessa intersecção através dos métodos da classe java.awt.image.PixelGrabber: public boolean grabPixels() e public synchronized Object getPixels()

4) comparar pixel a pixel as cores dos dois arrays, se houverem dois pixels na mesma posição ambos com cores não transparentes é porque a colisão é real

3. Detecção de colisões por rectângulo encolhido

Esta abordagem é bastante semelhante à primeira em implementação, mas tem resultados visuais largamente superiores. Em vez de criarmos um rectângulo com as mesmas dimensões que a sprite, criamos apenas um à volta da área colidível. Isto faz com que em termos de velocidade seja praticamente igual à primeira abordagem, e em termos visuais não muito inferior à segunda.

Implementação:

1) criar uma instância da classe java.awt.Rectangle com as dimensões da área colidível da sprite

2) mover essa instância de Rectangle à medida que a sprite é movida

3) sempre que a sprite é movida verificar se o seu Rectangle se intersecta com todos os outros Rectangle das outras sprites através do método da classe Rectangle: public boolean intersects(Rectangle r)

Esta abordagem é um intermédio entre as duas já mencionadas. É mais rápida que a segunda abordagem, mas menos precisa, e mais lenta que a primeira abordagem, mas mais precisa.

A título de nota pessoal, recomendo vivamente a terceira abordagem. A primeira é simplesmente má, e não é assim tão mais rápida ou complicada que a terceira para ser usada. A segunda embora exacta, torna-se demasiado lenta para ser usada em jogos.. ou outras aplicações. Tentei optimizá-la ao máximo e ainda assim não consegui atingir uma velocidade que fosse aceitável. Se alguém conseguir por favor ajude-me a melhorar este tutorial e a mim mesmo, postando aqui a implementação. A terceira abordagem é simplesmente óptima, e até à data ainda não me deparei com problemas que sentisse ter de utilizar uma detecção de colisões mais exacta que esta.

Estou aberto a quaisquer dúvidas relacionadas com o tópico, sugestões, críticas, ameaças de morte, declarações de amor, etc.

[Artigo na Wiki]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vou fazer uma declaração de amor xD

Epá gostei, simples, directo e eficaz. Pelo meio enunciaste as classes e metodos necessários sem espinhas. Bom tutorial

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora