Estou escrevendo um jogo XNA de cima para baixo em 2D. Desde o meu primeiro, estou tentando escrever as coisas da física e da colisão para aprender.
Sempre que meu personagem sprite de jogador tenta se mover para uma posição em que seus limites se cruzam com a borda de uma parede, descubro um ângulo de rebatimento (ângulo de incidência = ângulo de reflexão) e faço o jogador saltar da parede e evitar a colisão .
Estou tendo problemas para descobrir como lidar com a situação do meu sprite se cruzando com duas arestas da parede simultaneamente, por exemplo, quando atinge um canto.
Atualmente, meu código me diz que duas arestas da parede foram cruzadas, mas não em qual aresta ele teria atingido primeiro e, portanto, em que aresta ricochetear.
Qual é o teste matemático para escolher qual borda rebater? É fácil ver quando olhamos para ele, mas estou lutando para descobrir o teste de matemática para ele.
Respostas:
Se você calcular o quão longe no
Wall
oPlayer Sprite
mudou, você provavelmente pode baseá-lo no delta do x e y coordenadas dos cantos que estão se cruzam. Espero que faça sentido, não consigo pensar em uma maneira melhor de expressar isso.Então, por exemplo, se você olhar para o seu diagrama. Pegue o
x
valor do canto superior esquerdo doPlayer Sprite
(após a movimentação) e subtraia ox
valor do canto inferior direito doWall
. Faça o mesmo para osy
valores e depois veja qual é maior. A chave é que, se um é maior que o outro, oPlayer Sprite
provavelmente se cruza nesse lado.Aqui está um exemplo de imagem (esta é uma subseção da sua imagem com minhas próprias linhas adicionadas):
Agora, você vê aqui que a linha azul é maior que a linha verde. Nesse caso, a linha azul também está do lado em que
Player Sprite
se espera que ela salte.Se os dois valores forem iguais, eles acertam na esquina.
Agora, há um pequeno problema em fazê-lo dessa maneira. Se o
Player Sprite
veículo estiver viajando muito rápido ou a colisão estiver muito próxima da esquina, é possível que elePlayer Sprite
avance mais naWall
direção errada. Nesse caso, você provavelmente terá que verificar a velocidade do objeto em movimento. (Veja a resposta de Nathan Reed .)Nota: Acho que estou essencialmente tentando descrever a detecção de colisão SAT mencionada pelo @Blau, mas passei muito tempo escrevendo isso, então vou publicá-la de qualquer maneira. Espero que ajude você.
fonte
O deslocamento mínimo nem sempre fornece a resposta certa para qual borda foi atingida primeiro. Considere este caso:
Isso acontece quando a velocidade é alta o suficiente para que o bloco se mova bastante longe durante um quadro. Para detectar corretamente qual aresta foi atingida primeiro, você precisará configurar uma equação linear para resolver o tempo de colisão com cada aresta. Nesse caso, descrito no diagrama do OP, as equações relevantes são:
(Isso pressupõe um sistema de coordenadas X-direita e Y-up.) Em geral, você teria que usar os sinais dos componentes X e Y de player.velocity para determinar qual par de arestas precisa ser testado. De qualquer forma, depois de calcular os tempos de colisão, a mais antiga das duas é a colisão que você precisa lidar.
fonte
Você precisa da detecção de colisão SAT
Basicamente, você precisa procurar o vetor de deslocamento mínimo que é subtraído a um dos objetos, para que eles não se cruzem.
Na sua imagem, o deslocamento mínimo é o segmento laranja.
fonte
Respondeu a uma pergunta semelhante aqui
Você pode considerar verificar posições anteriores -
Por exemplo: se seu lado esquerdo estava anteriormente à direita do lado direito e você está colidindo, ocorreu uma colisão com a mão direita.
Se você fizer isso, resolva as colisões do eixo y, verifique se está colidindo com alguma coisa e, em seguida, resolva as colisões do eixo x.
fonte