Vi a seguinte pergunta: prever a posição do inimigo para que um objeto lidere seu alvo . Minha situação é um pouco diferente.
Meu alvo se move e o atirador se move. Além disso, a velocidade do atirador é adicionada às velocidades das balas, ou seja, as balas disparadas ao deslizar para a direita terão uma velocidade maior na direção da direita.
O que estou tentando fazer é conseguir que o inimigo seja capaz de determinar onde ele precisa atirar para atingir o jogador. Usando a solução SO vinculada, a menos que o jogador e o inimigo estejam imóveis, a diferença de velocidade causará um erro. Como posso evitar isso?
Aqui está a solução apresentada na resposta de estouro de pilha. Tudo se resume a resolver uma equação quadrática da forma:
a * sqr(x) + b * x + c == 0
Note que com sqr
eu quero dizer quadrado, ao contrário de raiz quadrada. Use os seguintes valores:
a := sqr(target.velocityX) + sqr(target.velocityY) - sqr(projectile_speed)
b := 2 * (target.velocityX * (target.startX - cannon.X)
+ target.velocityY * (target.startY - cannon.Y))
c := sqr(target.startX - cannon.X) + sqr(target.startY - cannon.Y)
Agora podemos analisar o discriminante para determinar se temos uma solução possível.
disc := sqr(b) - 4 * a * c
Se o discriminante for menor que 0, esqueça de atingir seu alvo - seu projétil nunca poderá chegar lá a tempo. Caso contrário, observe duas soluções candidatas:
t1 := (-b + sqrt(disc)) / (2 * a)
t2 := (-b - sqrt(disc)) / (2 * a)
Note que se o disco == 0 então t1 e t2 são iguais.
sq()
vez desqr()
? Isso torna muito confuso ler.Respostas:
Ok, vamos colocar um pouco de sanidade nisso. Receio que você não esteja facilitando nada, seu código não é compilado, é inconsistente com relação aos nomes de variáveis (
playerVelocityX
ficaplayerXvelocity
após algumas linhas? O que éxVelocity
?) E é muito detalhado. É basicamente impossível depurar para que você não faça um esforço considerável.Então, aqui estão as coisas para corrigir:
Velocidade da bala
A velocidade da bala deve ser
30
, ponto final. Não há necessidade dos cálculos que você está fazendo: a mudança do quadro de referência está precisamente lá para evitar a complexidade. Você só adiciona a velocidade do inimigo depois de encontrar uma solução quando volta ao quadro de referência principal.Validade da solução
Você não está verificando se a
time
solução é positiva.Inúmeros erros de codificação
Você está testando
time1
etime2
sempre usandotime1
nos resultados.Você faz o
playerXvelocity - yVelocity
que é inconsistente.Você está fazendo em
/ 2 * a
vez de/ (2.f * a)
. Este é o pior erro e é por isso que tudo está dando errado.Você calcula
shootx
eshooty
como a posição final da bala, enquanto o que você está procurando é a velocidade da bala.Código fixo
fonte
playerX += playerVelocityX*t0;
playerY += playerVelocityY*t0;
float bulletX = ((cos(heading * DEGREE2RAD)*bulletSpeed + enemyVelocityX) * t0) + enemyX;
float bulletY = ((sin(heading * DEGREE2RAD) * bulletSpeed + enemyVelocityY) * t0) + enemyY;
A saída é P = (84.8069,93.0386) E = (88.3793.105.132)bulletSpeed
neste momento. Substituacos(heading * DEGREE2RAD) * bulletSpeed
porshootx
. O mesmo parashooty
. O motivo é que a velocidade do inimigo é adicionada à velocidade da bala, sua velocidade não é mais exatamentebulletSpeed
. Na verdade, você não precisa daheading
variável, apenas ajuda na depuração.Ter um atirador em movimento é idêntico a ter um atirador parado. Subtraia simplesmente o vetor de movimento dos atiradores do vetor de movimento dos alvos.
Calcule o vetor de tiro / ângulo inicial e adicione o vetor de movimento dos alvos ao marcador normalmente.
fonte
Aqui está um exemplo em que eu projetei e implementei uma solução para o problema da segmentação preditiva usando um algoritmo recursivo: http://www.newarteest.com/flash/targeting.html (eu tinha um atirador estacionário, mas a mesma abordagem funcionaria para um atirador em movimento)
Vou ter que experimentar algumas das outras soluções apresentadas, porque parece mais eficiente calculá-lo em uma única etapa, mas a solução que surgiu foi estimar a posição de destino e alimentar o resultado de volta no algoritmo para criar um novo estimativa mais precisa, repetindo várias vezes.
Para a primeira estimativa, eu "atiro" na posição atual do alvo e depois uso a trigonometria para determinar onde o alvo estará quando o tiro atingir a posição disparada. Então, na próxima iteração, eu "disparo" nessa nova posição e determino onde o alvo estará neste momento. Após cerca de 4 repetições, chego a um pixel de precisão.
fonte
Como você está trabalhando apenas com física 2D (sem velocidade Z), esse problema pode ser bastante simplificado. A maneira mais fácil de fazer isso é parar de pensar nos movimentos de origem e destino em relação às coordenadas do mundo e apenas pensar no destino em movimento em relação à fonte (e manter a fonte estacionária).
Normalmente, a velocidade de uma bala seria muito maior que a velocidade do atirador, portanto, geralmente é assumido que a bala é independente, mas há ocasiões em que isso não é verdade, como disparar de um helicóptero ou avião de combate.
Então precisamos calcular a velocidade da bala:
O problema que você está enfrentando é que o alvo se move quando a bala os atinge.
e resolva o TargetPosition == BulletPosition porque o marcador atingirá o alvo. Agora você tem três incógnitas e apenas duas equações. Podemos remover 't' usando a derivada de primeira ordem:
Agora, para atingir o alvo, você desejaria
dV/dt == -TargetInitialPosition * k
. A constante deve ser a mesma nas coordenadas X e Y e é o número de segundos que o marcador levará para atingir o alvo.torná-los iguais:
ou para expandir as variáveis:
Então a álgebra fornece sua equação final:
A próxima parte é confusa e você decide como deseja implementá-la no seu código, mas apenas substituímos isso e normalizamos o vetor.
Você acaba com uma equação com apenas um desconhecido (source.directionX) e pode resolvê-lo com directionX e substituí-lo novamente para obter directionY.
Eu não testei nenhum desses códigos e sinta-se à vontade para apontar quaisquer erros matemáticos que cometi, mas a teoria deve ser sólida :).
Boa sorte.
fonte
Este é apenas um problema de geometria 3D.
Primeiro você precisa da posição relativa e da velocidade relativa do atirador e do alvo:
Então você precisa resolver a equação:
Para
t
ex
.Isto faz:
A última dessas equações é uma equação quadrática simples, que você deve resolver. Para cada resultado positivo, você insere o resultado na equação:
Isso deve fornecer todos os vetores de fogo possíveis, onde
t
é o tempo que o tiro levará.Observe que se
FireSpeed
for maior que a magnitude deVel
haverá apenas uma solução, mas seFireSpeed
for menor, poderá haver duas soluções ou nenhuma, ou, em casos especiais, apenas uma única solução dupla.Edit: Melhor fazer a matemática corretamente ou esta resposta não será muito boa.
fonte