Como lidar com a detecção de colisões para que objetos rápidos não passem através das paredes?

14

Estou criando um jogo de tiro em 2D lateral e estou tendo alguns problemas com a detecção de colisão para as balas. Tudo, incluindo os marcadores, são objetos com seus próprios polígonos / métodos de atualização.

O problema é que os marcadores passam rápido e, a 60 quadros por segundo (no que o jogo é executado), uma bala costuma pular através de uma parede - já que se move mais do que a largura da parede durante o intervalo de atualização - e continue feliz, pois os polígonos nunca se sobrepõem.

O que é que eu posso fazer sobre isto? A única coisa que consegui sugerir é desenhar uma linha da posição antiga para a nova posição e fazer a detecção de colisão, mas o desenho de linha para detecção de colisão é recomendado pela documentação do slick2d. Como posso resolver isso?

Mala
fonte
Não é uma resposta completa, portanto, um comentário. Eu nunca recomendaria desenhar graficamente uma linha, mas matematicamente você pode fazer isso, é apenas uma simples interseção no plano de raios para ver se a colisão ocorreu. Você pode então fazer uma detecção de etapa fixa menor para obter o momento exato (e todas as informações que o acompanham) quando a colisão ocorreu sem ter que executar a uma taxa constantemente mais alta, conforme sugerido nas respostas. Faça uma verificação menos dispendiosa e depois gaste o tempo obtendo a resposta mais precisa que você precisar.
James

Respostas:

9

As abordagens padrão são (escolha uma):

  1. Aumente a largura do seu limite E / OU reduza a velocidade máxima da sua bala para que ele nunca possa pular através de uma parede em uma única atualização (é necessário um pouco de Pitágoras para descobrir as distâncias máximas / larguras mínimas dos limites);
  2. Realize a detecção contínua de colisões (CCD), geralmente através de radiodifusão para detectar colisões com superfícies lineares (2) ou planas (3D) à frente do objeto em movimento. Isso é mais caro, mas é uma solução mais completa. A transmissão de raios em linhas 2D é bastante básica, mas neste caso é necessário definir todos os seus limites como polígonos de borda reta.

Nesse caso, você pode modelar suas balas como raios - se isso se encaixa na aparência do seu jogo, como no left4kdead . Dessa forma, você não precisa aproximar as balas como raios, porque elas já são raios. Do ponto de vista da aparência, isso pode parecer decente se você desenhar a linha com um ponto mais brilhante no final da bala ou apenas desenhar a linha como um gradiente de claro (final da bala) a escuro (final da cauda), dando uma aparência de movimento.

Concordo que, na maioria das circunstâncias, o uso de gráficos para detecção de colisão é um pouco equivocado, no entanto, a detecção de colisão com pixel perfeito é exatamente isso e é uma técnica aceita. Acho que tudo depende do que você deseja alcançar e com que rapidez. Se você não precisa de um jogo muito rápido com muitos corpos + ação, vá em frente. Caso contrário, é melhor usar uma das abordagens descritas acima.

Engenheiro
fonte
Obrigado pela ótima resposta - idealmente, eu gostaria que fosse rápido com muitos corpos em movimento. A razão pela qual estou tratando as balas como objetos físicos é para que sejam afetadas pela gravidade como todo o resto (então diminua um pouco, dependendo da velocidade da bala, etc.). Esta não é uma boa maneira de fazer isso? Este é o meu primeiro jogo, então ainda estou procurando as melhores práticas. Eu também poderia usar uma equação parabólica, mas eu não sei como eu iria configurar os coeficientes relativos à velocidade / objectivo ângulo da bala
Mala
3
Parece muitos detalhes para balas. Na vida real, quando você dispara uma bala, é improvável que encontre essa lesma devido à força do ricochete, imprevisibilidade do ângulo do richoch, etc. Ou então, apenas entra no corpo e fica lá (árvore, pessoa). Gostaria que eles desaparecessem ou ricochetassem e depois desaparecessem pouco depois. Concentre-se em sua jogabilidade principal, não se preocupe muito com esses pequenos detalhes. O realismo é mais focado nas coisas que importam.
Engenheiro de
Sim, suponho que eu possa usar apenas linhas retas para balas e talvez encontrar uma maneira de fazê-las curvar um pouco mais tarde, se parecer importante.
Mala
2
Se a velocidade das balas não for muito alta (ou seja, não tão rápida que você não possa vê-las viajar pela tela), basta aplicar a gravidade à velocidade delas enquanto modela sua detecção de colisão usando raios simples. O usuário não notará mais que o marcador está se movendo como uma série de linhas retas, além de perceber como todos os seus outros objetos também estão fazendo o mesmo. Para trilhas de bala, o cálculo e o desenho de uma trilha curva (spline) não são difíceis e aumentam a ilusão de uma curva suave na trajetória da bala.
Sean Middleditch
3

Se você deseja que suas balas se comportem como objetos físicos realistas (por exemplo, suas balas são mais parecidas com flechas ou pedras de uma catapulta do que com tiros), então você também pode tentar aumentar a frequência de suas atualizações físicas.

Portanto, enquanto seu jogo pode rodar com 60 quadros por segundo, sua simulação física pode ser executada a 120 atualizações por segundo (aqui está o onipresente artigo sobre correção de timestep, que explica uma boa configuração física que pode ser executada em velocidade diferente da do loop de renderização).

Obviamente, aumentar o intervalo de atualização no mecanismo de física colocará uma carga maior na CPU. Portanto, essa abordagem só é sensata se seus projéteis não estiverem se movendo muito rapidamente (o que eu estava assumindo, pois você é capaz de dizer que seus projéteis estão se movendo em arco).

bummzack
fonte
Obrigado! Estou efetivamente fazer isso (assim como a utilização de projéteis em forma de linha) e estou esperando ele permanece viável como o jogo fica mais complicado
Mala