Página 1 de 1

[INT] [Tutorial] IA Básica de TDS (Pt. 2)

Enviado: Sex Abr 29, 2016 12:15 am
por Tutoriais & Aulas
Autor original: Gonçalves
Tutorial TDS IA Parte 2 (Chamando Reforço)

Olá. Eu sou o Gonçalves e vim aqui ensinar o pouco que eu sei sobre Inteligência Artificial de jogos Top-down shooter. Baixe o conteúdo do fim da Primeira aula aqui:

http://www.mediafire.com/?9oa9ivcjusjkiro

Tentarei deixar o mais claro possível para os leitores e estarei aceitando feedback.

Sumário

1. Atores patrulhando
2. Usando os grupos e criando aliados
3. Criando os "teammates"

Introdução

Vimos na 1ª Parte como fazer uma IA básica, agora iremos complementá-la com alguns adicionais que deixarão o jogo mais difícil e realista.

1. Atores patrulhando

Vamos agora passar o que ensinei em [Tutorial]Patrulha Top-Down para a nossa IA. Para não ter de ficar explicando tudo novamente, peço que deem uma olhada no tutorial de patrulha para saber como tudo funciona, darei breves explicações apenas por aqui. Primeiramente, adicione ao Create do atr_inimigo o seguinte código, que define as configurações da patrulha:

Código: Selecionar todos

patrulhar=true // Define se esse objeto vai patrulhar ou não.
fim_patrulha=false // Define se ele vai parar após passar por todos os pontos de patrulha ou vai voltar do início
ponto_atual=0 // Definirá por quantos pontos ele passará, deixe 0
patrulha_total=0 // Define o ponto inicial, deixe 0 caso não saiba o que está fazendo
patrulhando = patrulhar // Definir se irá começar já patrulhando
vel_patrulha = velocidade/4 // Velocidade no qual o ator vai patrulhar
Explicações no próprio código. Agora criemos o script adicionar_ponto_patrulha, com o seguinte código:

Código: Selecionar todos

patrulha_x[patrulha_total]=argument0
patrulha_y[patrulha_total]=argument1
patrulha_total+=1
E agora, adicionemos no Create do atr_inimigo o pontos de patrulha que queremos adicionar, citarei um exemplo:

Código: Selecionar todos

// Definir os pontos de patrulha (Ex. abaixo forma um quadrado)
adicionar_ponto_patrulha(x+100,y)
adicionar_ponto_patrulha(x+100,y+100)
adicionar_ponto_patrulha(x,y+100)
adicionar_ponto_patrulha(x,y)
Fará com que ele fique andando em uma espécie de quadrado. Agora substituíremos todo o Step por esse:

Código: Selecionar todos

checar_vida()

if distance_to_object(atr_jogador) < percepcao and ! collision_line(x,y,alvo.x,alvo.y,obj_caixote,0,0) {viu_alvo = true; alvo = atr_jogador; if patrulhar = true {patrulhando = false}}

if collision_line(x,y,alvo.x,alvo.y,obj_caixote,0,0) {viu_alvo = false; if patrulhar = true {patrulhando = true}}

if viu_alvo = true 
{
if distance_to_object(atr_jogador) > percepcao*0.6 {mp_potential_step(alvo.x,alvo.y,1.2+(velocidade*0.1),1)}

olhar_para(alvo.x,alvo.y)

if tempo < 12 {tempo += 1}
if tempo >= 12 {atirar()}
}

if patrulhando = true
{
    mp_potential_step(patrulha_x[ponto_atual],patrulha_y[ponto_atual],1.2+(vel_patrulha*0.1),0)

    if distance_to_point(patrulha_x[ponto_atual],patrulha_y[ponto_atual]) <=0
    {
    ponto_atual+=1
    }
    
    if ponto_atual >= patrulha_total
    {
        if fim_patrulha = true
        {
        patrulhando=false
        }
        else
        {
        ponto_atual=0
        }
    }

}
Substituímos aquele código simples por um com o sistema de patrulha, e houve uma ligeira modificação nos efeitos das primeiras condições, peço que deem uma olhada. Se quiser também, desenhe os pontos da patrulha do ator no cenário para ilustrá-la (Draw):

Código: Selecionar todos

var w;
for (w=0; w<patrulha_total; w+=1)
{
    draw_circle_color(patrulha_x[w],patrulha_y[w],5,c_lime,c_lime,1)
}
Resultado:

Imagem

Os atores irão patrulhar e, ao avistá-lo, atacarão, se parar de vê-lo (ou matar o alvo), seguirão na patrulha.

2. Usando os grupos

Vamos agora montar um sistema de grupo (com os objetos grupo contidos na engine) para fazer com que grupos de atores se enfrentem (no caso Aliados e Inimigos). Primeiro vamos definir no Create do atr_inimigo qual o seu grupo inimigo:

Código: Selecionar todos

inimigo = grupo_aliado
No Step, modificaremos a parte:

Código: Selecionar todos

if distance_to_object(atr_jogador) < percepcao and ! collision_line(x,y,alvo.x,alvo.y,obj_caixote,0,0) {viu_alvo = true; alvo = atr_jogador; if patrulhar = true {patrulhando = false}}

if collision_line(x,y,alvo.x,alvo.y,obj_caixote,0,0) {viu_alvo = false; if patrulhar = true {patrulhando = true}}

if viu_alvo = true 
{
if distance_to_object(atr_jogador) > percepcao*0.6 {mp_potential_step(alvo.x,alvo.y,1.2+(velocidade*0.1),1)}

olhar_para(alvo.x,alvo.y)

if tempo < 12 {tempo += 1}
if tempo >= 12 {atirar()}
}
Por:

Código: Selecionar todos

var prox;

prox = instance_nearest(x,y,inimigo)

if distance_to_object(prox) < percepcao and ! collision_line(x,y,prox.x,prox.y,grupo_objetos,0,0) {viu_alvo = true; alvo = prox; if patrulhar = true {patrulhando = false}}

if collision_line(x,y,alvo.x,alvo.y,obj_caixote,0,0) {viu_alvo = false; if patrulhar = true {patrulhando = true}}

if viu_alvo = true 
{
if distance_to_object(prox) > percepcao*0.6 {mp_potential_step(alvo.x,alvo.y,1.2+(velocidade*0.1),1)}

olhar_para(alvo.x,alvo.y)

if tempo < 12 {tempo += 1}
if tempo >= 12 {atirar()}
}
O que modificamos? Primeiro definir como prox o inimigo mais próximo. Depois checamos se o tal está perto e o definiremos como alvo normalmente, só substituindo os atr_jogador pelo prox. Logo qualquer ator considerado um aliado (com parent grupo_aliado) será alvejado pelo mesmo se possível. Também trocamos o obj_caixote por grupo_objetos, fazendo com que qualquer objetos no grupo impeça a visão da IA.

Agora duplicaremos o objeto atr_inimigo, dando uma sprite diferente (se quiser ponha a mesma do jogador, ou mude ao menos a letra pra 'A', você que sabe). Nele, vamos colocar como parent o grupo_aliado e colocar como inimigo (no Create) o grupo_inimigo. Espalhe-os pelo mapa.

Resultado:

Imagem

Os atores (aliados e inimigos) patrulham e se atacam.

3. Criando os "teammates"

Agora que já temos aliados por si só, vamos criar aliados (ou até mesmo inimigos) que seguem seus líderes, vamos lá. Dupliquemos o atr_aliado e coloquemos o nome atr_aliado2, no seu Create adicionaremos o seguinte:

Código: Selecionar todos

seguir_lider = true // Define se deve seguir alguém ou não
lider = atr_jogador // Definie seu líder
seguindo_lider = seguir_lider // Definir se irá começar já seguindo
seguir_dist = 60  // Definir distância pro líder
Não se esqueça de desativar a variável patrulhar, pois ele não pode seguir e patrulhar ao mesmo tempo. Se as duas tiverem valor true, ele ficará como uma louco andando pra um lado e pra outro.

Agora que definimos suas config., vamos adicionar isso ao Step:

Código: Selecionar todos

if seguindo_lider = true and seguir_lider = true and instance_exists(lider)
{
    if distance_to_object(lider) > seguir_dist {mp_potential_step(lider.x,lider.y,1.2+(velocidade*0.1),0)}
}
E vamos modificar a primeira parte do Step novamente, subs. isso:

Código: Selecionar todos

if distance_to_object(prox) < percepcao and ! collision_line(x,y,prox.x,prox.y,grupo_objetos,0,0) {viu_alvo = true; alvo = prox; if patrulhar = true {patrulhando = false}}

if collision_line(x,y,alvo.x,alvo.y,grupo_objetos,0,0) {viu_alvo = false; if patrulhar = true {patrulhando = true}}
Por isso:

Código: Selecionar todos

if distance_to_object(prox) < percepcao and ! collision_line(x,y,prox.x,prox.y,grupo_objetos,0,0) {viu_alvo = true; alvo = prox; if patrulhar = true {patrulhando = false}; if seguir_lider = true {seguindo_lider = false}}

if collision_line(x,y,alvo.x,alvo.y,grupo_objetos,0,0) {viu_alvo = false; if patrulhar = true {patrulhando = true}; if seguir_lider = true {seguindo_lider = true}}
Vai definir também ali quando ou não parar de seguir seu líder. Agora substitua todo o código de colisão com grupo_pessoas do obj_projetil por esse:

Código: Selecionar todos

if atirador.inimigo != other.inimigo
{
    other.alvo = atirador
    other.viu_alvo = true
    other.seguindo_lider = false
    other.patrulhando = false
} 

with(other) 
{
    energia -= (20+random(15)-resistencia) // Danificar o alvo
}

instance_destroy()
E ponha no Create do atr_jogador:

Código: Selecionar todos

inimigo = grupo_inimigo
Assim seus aliados não o atacaram no caso de friendly fire.

Resultado:

Imagem

O(s) teammate(s) te seguem e atacam os inimigos quando necessário.

Tudo pronto, espero que tenham entendido, qualquer problema só me avisar. O resultado final você pode baixar no link abaixo:

http://www.mediafire.com/?lcsee7bdw2z2777

Deixei como comentário as marcações na engine (percepção, linha até alvo etc.), ficando assim:

Imagem

É isso aí, fico por aqui. Provavelmente terá uma Parte 3, só preciso de tópicos pra abordar.

VALEU!