Imagine um tiroteio muito simples, algo que todos sabemos:
Você é o jogador (verde). Seu movimento é restrito ao X
eixo. Nosso inimigo (ou inimigos) está no topo da tela, seu movimento também é restrito ao X
eixo. O jogador dispara balas (amarelas) contra o inimigo.
Eu gostaria de implementar uma IA para o inimigo que deve ser realmente boa em evitar as balas dos jogadores. Minha primeira idéia foi dividir a tela em seções discretas e atribuir pesos a elas:
Existem dois pesos: O "peso da bala" (cinza) é o perigo imposto por uma bala. Quanto mais próxima a bala estiver do inimigo, maior o "peso da bala" ( 0..1
onde 1 é o maior perigo). As faixas sem uma bala têm um peso igual a 0. O segundo peso é o "peso à distância" (verde-limão). Para cada faixa eu adiciono 0.2
custo de movimentação (esse valor é meio arbitrário agora e pode ser ajustado).
Simplesmente adiciono os pesos (branco) e vou para a pista com o menor peso (vermelho). Mas essa abordagem tem uma falha óbvia, porque ela pode facilmente errar os mínimos locais, pois o lugar ideal para ir seria simplesmente entre duas balas de entrada (como indicado pela seta branca).
Então, aqui está o que estou procurando:
- Deve encontrar um caminho para a tempestade de balas, mesmo quando não há lugar que não imponha a ameaça de uma bala.
- O inimigo pode desviar de maneira confiável das balas escolhendo uma solução ótima (ou quase ótima).
- O algoritmo deve ser capaz de levar em consideração a velocidade de movimento da bala (como eles podem se mover com velocidades diferentes).
- Maneiras de ajustar o algoritmo para que diferentes níveis de dificuldade possam ser aplicados (mudos para inimigos super inteligentes).
- O algoritmo deve permitir objetivos diferentes, pois o inimigo não apenas deseja fugir das balas, mas também deve ser capaz de atirar no jogador. Isso significa que as posições em que o inimigo pode disparar contra o jogador devem ser preferidas quando se desviar de balas.
Então, como você lidaria com isso? Ao contrário de outros jogos desse gênero, eu gostaria de ter apenas alguns inimigos, mas muito "habilidosos", em vez de muitos inimigos estúpidos.
fonte
Respostas:
Eu acho que sua idéia básica é sólida, mas não é analógica. Você precisa de um campo de valor analógico que atravessa a tela. Portanto, gradiente de difusão 1D, a partir do qual você pode derivar um valor em um ponto exato nessa linha, em tempo real. Gradientes de difusão são baratos e podem ser usados por vários inimigos de uma só vez, pois descrevem o ambiente, e não a visão da entidade (um pouco como a iluminação de radiosidade) - provavelmente por que você optou pela abordagem adotada em sua pergunta . Esse gradiente deve ser relativamente suave, de modo a evocar o movimento orgânico do inimigo, e obviamente é atualizado como o seu gamestate. Talvez média móvel ?
O gradiente deve combinar:
Para desviar, precisamos encontrar uma solução com precisão sempre que houver uma solução . É o caso sempre que existe uma lacuna pequena o suficiente para o inimigo se esquivar. Ou seja, você só pode fazer o que pode; portanto, a abordagem de gradiente não funcionará pior do que qualquer outra abordagem nesse sentido, eu diria.
O gradiente de difusão deve empurrar o inimigo em direção às ótimas locais (sendo os picos no gráfico) com menos imperatividade de se mover, quanto mais perto estivermos de um mínimo local, portanto, um efeito de retorno decrescente ao se esquivar. Isso abre a porta para uma tomada de decisão mais inteligente sobre quando o inimigo tem uma boa abertura para disparar.
Se a necessidade de disparar for maior que a necessidade de se mover, faça-o; seu código também pode determinar isso em quanto diferença. Você pode implementá-lo como parte do gráfico base. Nesse caso, a posição do jogador reduz os valores circundantes no gráfico (supondo que os inimigos gravitem até o ponto mais baixo), que combina toda a tomada de decisão em um gráfico ou você pode manter o " gráfico desejo de acionar "separado do gráfico principal" desejo de esquivar ", que oferecerá um controle mais direto.
IRL, eu não me incomodaria em desviar de um projétil até que esteja a uma distância que eu sei que, na minha velocidade máxima de esquiva, está começando a se tornar difícil de evitar. Experiência em primeira mão ao jogar pedras como um rapaz. Uma bala na x distância percorrida na velocidade y tem a mesma classificação de perigo que uma bala na 2x distância percorrida em 2y. Portanto, isso precisa ser levado em consideração corretamente.
As maneiras de ajustar o algoritmo para a dificuldade do inimigo incluem
Novamente, você pode implementar todos os fatores em um gráfico (menos controle e menos útil para vários inimigos) ou em vários gráficos que você olha juntos para obter os resultados (mais modular, provavelmente funciona melhor para vários inimigos). É difícil ser mais específico, pois existem várias orientações para você seguir essa abordagem.
fonte
Isso pode ser encarado como um problema de correção. Em vez de pensar em como o bandido evita as balas, a imagem das balas é estática e o bandido deve viajar através delas até a parte inferior da tela.
E = inimigo
B = marcador
P = jogador
* = opções de caminho para a parte inferior da tela
Depois que o bandido traça um caminho bem-sucedido, ele só precisa dar o próximo passo a cada vez. Provavelmente já existem alguns bons algoritmos para encontrar caminhos como esse. Se o bandido se mover na mesma velocidade que as balas, pode ser um exemplo de algoritmo;
Comece no baddy e marque as posições seguras em espaços vazios à esquerda abaixo, diretamente abaixo e abaixo à direita. Em seguida, considere cada espaço seguro que você acabou de criar e repita. Se a qualquer momento você achar que não há espaços seguros abaixo, marque o espaço como não seguro e volte.
fonte