Como posso implementar uma detecção de colisão 2D rápida e precisa?

11

Estou bem ciente de como detectar se dois ou mais objetos 2D colidem, mas estou interessado em como decidir se deve verificar se há uma colisão. Em projetos anteriores, eu tinha todos os objetos comparados com outros objetos (eu sei, O (n ^ 2) nível de estupidez) e isso criou uma jogabilidade menos do que fluida.

Vários fóruns elogiam a grandeza de Quadtrees, B-Trees e qualquer outro tipo de árvore ou estrutura que você possa imaginar.

Qual é a estrutura mais eficiente para determinar se uma colisão deve ser verificada?

Mike Cluck
fonte
1
Uma coisa que você pode querer considerar é apenas verificar colisões quanto a objetos que foram movidos e os únicos objetos próximos a você. Meu sistema atual funciona bem (centenas de milhares de objetos) - e é isso que estou fazendo.
Ultifinitus 07/10/11
Acho que gamedev.stackexchange.com/questions/14369/… poderia ajudá-lo muito. foi originalmente criado para e algoritmo para processamento paralelo, mas acho que o mesmo algoritmo também pode melhorar aplicativos de thread único.
Ali1S232
1
@ultifinitus Isso é essencialmente o que estou perguntando. Como determino quais objetos estão próximos sem iterar em todos os objetos e verificar sua posição?
quer
Mike, você pode me enviar um e-mail com algum código específico que eu usei, é em c ++ - ou posso fornecer a estrutura básica, embora possa ficar bastante ambígua e complicada por causa disso.
Ultifinitus
1
Não é uma duplicata, porque eu estava perguntando que tipo de estrutura é mais adequada para determinar se devemos nos incomodar em verificar uma colisão. Essa outra pergunta foi feita sobre colisões transparentes versus não transparentes. Para não mencionar, essa pergunta foi feita cerca de um ano antes da pergunta a que você se vinculou.
Mike Cluck

Respostas:

12

Para um jogo 2D, a menos que os objetos 2D tenham uma distribuição muito pesada em um lado do mapa, uma grade uniforme é quase sempre o caminho a percorrer. A complexidade da memória é direta (proporcional às dimensões do seu mapa) e com uma distribuição razoável, possui O (1) tempo de pesquisa e uma média de log (numberOfObjects / (linhas * colunas)) ^ 2 testes de interseção feito por célula. Você pode decidir verificar apenas as células que tiveram um objeto movido nelas, o que torna a geometria estática muito mais eficiente. É fácil modificar uma grade uniforme em tempo real (muito menos trabalhoso do que em soluções baseadas em árvores) e é mais simples de implementar. A única vez em que eu diria para não usá-lo em um jogo 2D é quando os requisitos de memória de uma grade uniforme se tornam muito grandes (diga um sim espacial onde os níveis são escassos, mas enormes).

Darcy Rayner
fonte
Como essa solução lida com objetos que fazem fronteira com 2 ou 4 células da grade?
precisa saber é o seguinte
1
Qualquer célula em que o objeto se sobrepõe, é considerada como estando, portanto, um objeto pode estar em várias células. A maioria das estruturas de dados espaciais lidará com a questão de sobreposições de maneira semelhante.
Darcy Rayner
Uau, isso é muito inteligente. +1 Saúde, cara.
precisa saber é
1

Se o seu mundo tem uma dimensão muito "longa" (chamada X), em comparação com outras, você pode manter os objetos em uma lista ordenada que pode ser reorganizada à medida que se movem e, em seguida, a detecção de colisão significa apenas verificar objetos que sobreposição no eixo X.

Outra possibilidade é manter listas de objetos ativos / passivos e não se incomodar com os objetos passivos (que não estão se movendo).

Se todos eles são objetos de tamanho médio que são visíveis para o jogador na tela, tudo vs tudo provavelmente não é tão ruim.

Fora isso, estou com Darcy, uma grade uniforme é boa.

MarkR
fonte