Seguindo a minha pergunta anterior sobre como encontrar a inclinação de um terreno de bitmap 2D, agora preciso saber a melhor maneira de encontrar o ponto no terreno 2D que o míssil atingiu. Obviamente, posso ver se algum pixel sob o míssil cruza o terreno, mas digo que ele se moveu bastante fundo no terreno.
Qual é a melhor maneira de voltar atrás e descobrir onde ela colidiu inicialmente? Eu poderia voltar X pixels de cada vez para a posição anterior do míssil, mas qual seria um bom valor para X? E existe uma maneira mais inteligente? Talvez movendo metade da distância, então um quarto, etc?
Respostas:
Para testes de colisão, você não deve fazer testes estáticos de tick-by-tick, deve fazer testes de rastreio / varredura.
Há uma lista exaustiva de várias fórmulas para diferentes tipos de primitivas aqui: http://www.realtimerendering.com/intersections.html
Isso é claro, supondo que você possa dividir seu terreno em algum tipo de conjunto de primitivas com as quais você possa testar (ou seja, segmentos de linha). Existem várias maneiras de fazer isso.
Veja também esta pergunta (apenas ligeiramente relacionada): Qual é um bom algoritmo para detectar colisões entre esferas móveis?
fonte
A pesquisa binária não ajudará se você tiver pequenos pedaços de cenário e projéteis em movimento rápido - você pode sentir falta deles.
Acho que sua melhor opção é varrer uma linha pela frente do projétil ao longo do caminho, pixel por vez. Você pode fazer uma verificação delimitadora primeiro em todo o volume para evitar fazer isso a cada passo.
fonte
Como é improvável que o míssil mova uma quantidade enorme de pixels por quadro (não seria bom na tela), não vejo razão para não apenas verificar todos os pixels no caminho. O algoritmo de linha Bressenham é seu amigo, e certifique-se de que você também tenha uma cópia local do seu bitmap, pois geralmente não deseja acessar a memória de vídeo para cada pixel. Isso pressupõe que seu terreno de bitmap seja totalmente aleatório (conforme o terreno de worms destrutíveis). Se seu mundo é baseado em blocos, você pode pular todos os blocos que você sabe que estão vazios para começar, mas, como mencionado anteriormente, a menos que você tenha uma quantidade enorme de mísseis para verificar, não consegui pensar em uma plataforma que precisaria lenta demais para testar pixel por pixel, e você não precisará ter seu mundo definido em primitivas (um clone de worms tornaria isso complicado)
fonte
Além das outras respostas, há algumas coisas que você pode fazer para acelerar isso, se quiser fazer uma pequena contabilidade, no que diz respeito à "coleta" de vários pixels em blocos de "estado semelhante conhecido". Por exemplo, você pode armazenar a altura da parte mais alta do terreno, para ter como certo que o míssil não atingirá nada enquanto estiver acima disso. Você também pode armazenar a altura do menor espaço "aéreo", para saber que, se o míssil chegar a essa altitude, ele deve ter atingido alguma coisa (embora isso possa ser melhor usado como verificação de sanidade). Indo além disso, você pode armazenar retângulos que representam áreas que são todo o terreno e outros retângulos que são todos do ar, mas que podem ser mais trabalhosos do que valor.
Por fim, o melhor método provavelmente será "armazenar a altura de cada coluna do terreno" e depois apenas calcular a altura do míssil a cada passo do caminho. Não posso falar com jogos mais modernos, mas acredito que, quando você fez uma "caverna" em Scorched Earth, o terreno acima dessa caverna caiu direto, sem deixar saliências. Se você quiser saliências, o trabalho será um pouco maior, mas será uma extensão dessa ideia básica. (Dica: comece a ideia básica trabalhando primeiro!)
Como seu terreno é presumivelmente completamente arbitrário, não há atalhos. Mesmo que você tenha forçado seu terreno a ser um spline ou algo assim, isso ficará aborrecido quando você começar a destruí-lo e os testes de interseção de spline de linha forem iterativos e não perfeitos ou exaustivos e sem sentido lentos para o seu tipo de problema.
fonte