Como levar em consideração a gravidade ao mover a IA


9

Estou fazendo um jogo 2D. Atualmente, existe um helicóptero voando, controlado pelo jogador. É controlado usando as teclas de seta: CIMA, ESQUERDA e DIREITA.

É a velocidade ao longo do eixo y dy, e a velocidade ao longo do eixo x é dx.

É física é a seguinte:

Sempre que UP não é pressionado , dyacelera em constante aceleração, indefinidamente em direção a baixo. (Gravidade). dxpermanece no seu valor atual.

Quando UP é pressionado , dyacelera em constante aceleração, independentemente do que é atualmente, até 4 (para cima, até atingir a velocidade 4). dxpermanece no seu valor atual.

Quando ESQUERDA é pressionado , dxacelera em constante aceleração, de qualquer que seja o momento, até -4 .

Quando RIGHT é pressionado , o dx acelera em constante aceleração, de qualquer que seja o momento, até 4 .

(Quando ESQUERDA ou DIREITA são pressionadas e UP não é pressionada simultaneamente, como eu disse: dycada vez mais se torna cada vez menor, porque a gravidade está afetando o helicóptero)

Tudo isso faz o helicóptero seguir arcos no ar, em vez de linhas retas.

Isso cria física que parece bastante realista.

Minha pergunta é:

O helicóptero oponente, uma IA, deve se mover usando o mesmo sistema de física.

Digamos que a IA queira ir de onde está atualmente, para apontar B.

insira a descrição da imagem aqui

Se não houvesse gravidade nem aceleração gradual no jogo, seria fácil. Eu simplesmente desenharia um vetor da posição da IA ​​para o ponto B e faria a AI segui-lo.

Mas como existe gravidade e aceleração gradual, a IA nunca pode se mover em linha reta (quase). qual seria a melhor maneira de fazer a IA ir para o ponto B, com a maior eficiência possível de tempo?

Como posso levar em consideração a gravidade ao mover a IA para um destino específico?

(Se for mais fácil explicar, considere o ponto B no mesmo nível no eixo y da IA ​​e não na diagonal).

obrigado


Você pode desativar a física na IA enquanto está em movimento? Nesse caso, você pode desativá-lo enquanto ele está se movendo em direção ao ponto e ativá-lo quando o atingir.
Zhafur 31/01

@Zhafur Isso fará com que o movimento da IA ​​pareça irreal ou pelo menos diferente de como o movimento do jogador parece. Quero que o movimento da IA ​​pareça o movimento do jogador.
precisa saber é o seguinte

Respostas:


4

tl; dr:

TimeToStop.x = CurrentSpeed.x / Accelaration.x;

if (TimeToStop.x * CurrentSpeed.x >= 1.99 * DistanceFromTarget.x)
    slow_down_x(); // CurrentSpeed += Acc.x * direction;
else
    speed_up_towards_target_x(); // CurrentSpeed += Acc.x * direction;

O mesmo com y. Lembre-se de limitar a velocidade, para que fique entre zero e a velocidade máxima. Se o inimigo tiver uma velocidade muito lenta em algum momento e tentar parar, poderá começar a se mover na direção oposta. Não permita. Pare se estiver diminuindo a velocidade e a velocidade estiver abaixo de 1 * Acc.

Versão longa: Se não houver obstáculos, o movimento no eixo y é completamente irrelevante para (e não afeta) o movimento no eixo x. Portanto, a pergunta que você descreve pode ser dividida em duas perguntas separadas.

  1. Movendo-se para lá no eixo x
  2. E indo para lá no eixo y.

CS.x& CS.ysão a nossa velocidade atual nos eixos x e y.

TS.x& TS.yÉ o tempo que levaria para que você parasse apenas na vertical ou na horizontal, considerando sua velocidade atual no eixo relevante.

D.x& D.ysão a distância em cada eixo.

tl; dr: você continua a acelerar (se possível [a menos que tenha atingido a velocidade máxima]) no eixo x até chegar a um ponto onde a seguinte condição é verdadeira:

if (TS.x * CS.x >= 1.99 * D.x) hit_the_breaks_on_x();

O mesmo com y.


2

Uma abordagem que usei para um problema semelhante foi primeiro desenhar um vetor no alvo e depois compará-lo com a direção da velocidade atual.

Portanto, pegue o ângulo assinado entre o vetor de velocidade e o vetor de destino e aplique um impulso em relação ao tamanho do vetor.

Portanto, se o ângulo a entre o vetor de velocidade vermelho e o vetor de alvo verde for negativo, aplique um impulso positivo; caso contrário, não aplique nenhum impulso e deixe a gravidade resolvê-lo.insira a descrição da imagem aqui

Observe que você terá que tratar os quatro quadrantes onde o alvo pode ser diferente (como se o alvo estivesse no canto superior esquerdo, um ângulo positivo exigiria a aplicação de impulso).

Além disso, certifique-se de aplicar a quantidade de empuxo em relação ao desvio da velocidade alvo.

Tecnicamente, isso não está levando em consideração a gravidade, está compensando o estado atual e significa que o helicóptero da IA ​​pode não voar em linha reta com o alvo, mas oscilará um pouco. Isso pode ou não funcionar para o seu jogo.


11
Obrigado. Várias perguntas sobre isso: 1- "... aplique um impulso em relação ao tamanho do vetor " . Você quis dizer "tamanho do ângulo " ? 2- Por 'ângulo assinado', você quer dizer positivo ou negativo - correto? Nesse caso, um ângulo é positivo se estiver acima da linha marrom e negativo se estiver abaixo da linha marrom. Direita? 3- Se bem entendi, o que você quer dizer é: Todo quadro, obtenha o ângulo entre o vetor de velocidade atual e o vetor atual no alvo. Em seguida, adicione / subtraia de dx e dy de acordo. Isso está correto?
precisa saber é o seguinte

@ user3150201 Sim na questão do ângulo. Sim na pergunta assinada / não assinada, atan2 pode fornecer o ângulo assinado entre dois vetores. Parece que você entendeu meu ponto de vista, desculpas se eu não estivesse clara.
bornander

1

Você pode simplesmente recalcular o movimento a cada X quadro. Supondo que você não coloque muitos quadros no meio, mas o suficiente para não afetar o desempenho, a gravidade de um helicóptero não deve ser forte o suficiente para realmente ver a trajetória mudando. Além disso, acho que um jogador poderia se mover da mesma maneira, adaptando-se à gravidade enquanto se movia e não planejando.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.