O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

Bases para IA [PT1]: Movimentando NPC's via Sensor de distância(Eventos)

Iniciado por Zugzwang, 11/04/2014 às 21:34

Bases para IA: Movimentando NPC's via Sensor de distância(Eventos)
Resumo. Usamos variáveis para analisar distâncias entre Evento e Jogador (ou Evento etc.), e as empregamos em Condições para alcançar determinados efeitos.
Engine testada: RPG Maker VX Ace (conceitos funcionam em outras versões)
Apenas para estudo! Será atualizado posteriormente.


Clique aqui

Protótipo desenvolvido apresentado: Toque-me se for capaz! Silverhair quer distância. Ele se manterá a 1 tile de você. Adicionais. Movimentos específicos nas bordas e quinas (funcional). Magia que o afasta dele (esboço de um sistema). Conversa de acordo com distância (mal-configurada). Maskman o persegue se Silverhair aproximar-se dele. Configuração de rota ainda não implementada. (Perigo!: Erros de português nos comentários. Códigos não utilizados. Etc.)
Teclas: A: Mudar configurações. S: Conversar.

Tutorial. Conceitos+sistema experimental (mantenha 1 tile de distância!)
Proposta: O Evento escolhido é capaz de enxergar a posição do Jogador, calcular distância em relação a si mesmo e a direção da qual ele vem.
Aplicações: O Evento aciona os efeitos desejados de acordo com os critérios imputados. P. ex., afasta-se do Jogador caso ele queira quebrar a distância mínima (ABSystem), ou enxerga dentro de seu campo de visão (mini-games de vigias) etc.
Considerações: As configurações serão relativamente complexas. Se isso for um problema, use apenas em determinadas situações. Conceitos apresentados aqui podem ser empregados por scripters, o que facilitaria sistemas mais elaborados.
Conceito: Comparemos as coordenadas do Evento no Mapa com o do Jogador, gerando como saída uma diferença (subtração). Mais especificamente, serão comparadas as coordenadas X e Y destes elementos (XE-XJ; YE-YJ). As coordenadas do Evento será nosso ponto de referência (0, 0), visto que esta seria a diferença entre ele e ele mesmo (ou do Jogador em cima dele). Como no Plano Cartesiano, sabemos a posição do Jogador nos "quadrantes" de acordo com os valores de saída. Note: Devido às posições reais das coordenadas do Mapa iniciarem no canto superior esquerdo, perceba, os valores do eixo X são invertidos.




Para facilitar: Não precisa fazer contas. Selecione a posição do Evento. Se o Jogador estiver junto dela, o resultado das Coordenadas Comparadas será = (0,0). Para cada tile à direita, o resultado de X Comparado será o negativo X=-1 (p. ex., três tiles, X-3). À esquerda, será o positivo X=+1 por tile. Acima, será Y=+1 por tile. E abaixo, Y=-1 por tile. "Ande" com o teclado. Faça a conta por cada direção que você apertou. (Se três para direita, X-3).
Configurando o básico. Você pode fazer isso na Aba Eventos comuns. Será mais fácil visualizar e editar o código depois. Ele precisa estar em Processo Paralelo. Lembre-se de acionar seu switch depois. Eu chamarei o meu de Boss Silverhair. Nota: o número das variáveis é meramente ilustrativo. P. ex. [005:Jogador X].

#Analisando Coordenadas do Jogador. Gravando nas variáveis#
@>Controle de Variáveis: [005:Jogador X] = Jogador e Mapa X
@>Controle de Variáveis: [006:Jogador Y] = Jogador e Mapa Y


Guardamos as Coordenadas do Jogador nas respectivas variáveis. Precisamos fazer o mesmo com o Evento desejado. Crie seu Evento no mapa e volte para cá. Ajuste estas variáveis para captar as Coordenadas do Evento (no meu caso, Silverhair).

#Analisando Coordenadas do Boss. Gravando nas variáveis. Boss estabelecido: Evento [Silverhair]#


@>Controle de Variáveis: [007:Boss X] = [Silverhair] e Mapa X
@>Controle de Variáveis: [008:Boss Y] = [Silverhair] e Mapa Y


Qual é nosso objetivo? Comparar as variáveis. Basicamente, queremos as contas Evento X- Jogador X e Evento Y-Jogador Y. O ideal seria colocar o valor de saída da subtração Evento(X/Y)-Jogador(X/Y) numa terceira variável de nome qualquer (como Boss(X/Y)-Jogador(X/Y)). Teremos de configurar a conta manualmente, já que trabalhamos com as limitações dos Eventos da Engine, criando dois controles de variáveis para simular esta conta.

#Comparando valores das Coordenadas do Boss- Coordenadas doJogador#
#Gravando resultado na váriavel BossX(Y)-JogadorX(Y)#
(Subtração entre eles)
#Resultados são positivos ou negativos#


@>Controle de Variáveis: [009:BossX-JogadorX] = Variável [0007:Boss X]
@>Controle de Variáveis: [009:BossX-JogadorX] -= Variável [0005:Jogador X]
@>Controle de Variáveis: [010:BossY-JogadorY] = Variável [0008:Boss Y]
@>Controle de Variáveis: [010:BossY-JogadorY] -= Variável [0006:Jogador Y]


Basicamente é isso. Tchau! Brincadeira. O esquema de comparações está montado. Daqui para frente, vai da sua imaginação. Não acredita? Vamos tentar produzir alguma coisa. A partir de agora, as coisas ganhar um caráter experimental. CUIDADO!: Esteja preparado para lidar com bugs e erros de códigos. Siga a lógica, refaça os movimentos e não desista de criar o efeito desejado. DICA: Comente. Comente seus códigos. Você irá revisá-los freqüentemente. Na melhor das hipóteses; na pior serão dezenas de vezes revisadas. Também facilitará na hora de modificações e acréscimos no seu Sistema.

#TEORIA BÁSICA DA COMPARAÇÃO:
Saída das subtrações [009:BossX-JogadorX] e [010:BossY-JogadorY]#
Referência: Boss (0,0)
Acima do Boss: Valor positivo.
Abaixo do Boss: Valor negativo.
Direita do Boss: Valor negativo.
Esquerda do Boss: Valor positivo.


Com base nisso, iremos criar o seguinte: O Evento(Silverhair) procurará manter sempre 1 tile de distância do herói, desviando-se dele. Primeiro configuramos os movimentos no Evento: Velocidade Normal. Freq. Maior possível.

#AJUSTES: VELOCIDADE: Normal#
#FREQ.: Maior possível.# MARQUE IGNORAR SE IMPOSSÍVEL  E DESMARQUE  ESPERAR PARA ALCANÇAR FREQ. DO JOGADOR#


Criando os movimentos Direita e Esquerda.
#CRIANDOS MOVIMENTOS: DIREITA E ESQUERDA#

Para configurarmos os movimentos horizontais, a primeira providência é:
@>Condição: Variável  [010:BossY-JogadorY] == 0

#Esta Condição analisa se Jogador e Boss estão na #
#mesma LINHA(Y=0)#

Hã? É que, se o resultado é igual a zero, Evento e Jogador estão na mesma linha! Acompanhe com a imagem da teoria.

Agora vemos descobrir em qual coluna o Jogador está.
      @>Condição: Variável  [09:BossX-JogadorX] == -1
Se o resultado é negativo, o Jogador está à direita. No caso, 1 tile à direita é a condição requerida para os efeitos criados.
#LEMBRE-SE: Se o Jogador está à direita, valor é#
#negativo.


Enxergamos, portanto, quando o Jogador vem da direita para esquerda em direção ao Evento. Para manter distância, configuramos o movimento:
             @>Definir Rota de Movimento: [Silvhair] (Passar)
                                                                     : $>Mover a Esquerda

Marque Passar e desmarque Esperar.

Pronto! #Esquiva para Esquerda para manter distância estipulada.# Ficou assim:
@>Condição: Variável  [010:BossY-JogadorY] == 0
      @>Condição: Variável  [09:BossX-JogadorX] == -1

            @>Definir Rota de Movimento: [Silvhair] (Passar)
                                                                     : $>Mover a Esquerda


Agora vamos para a outra hipótese.
Dentro da @>Condição: Variável  [010:BossY-JogadorY] == 0, e fora da condição acima, crie:
@>Condição: Variável  [09:BossX-JogadorX] == 1
Se o resultado é positivo, o Jogador está à esquerda. No caso, 1 tile à esquerda.
#LEMBRE-SE: Se o Jogador está à esquerda, valor é positivo.


Enxergamos, aqui, quando o Jogador vem da esquerda para direita em direção ao Evento. Manteremos distância com o movimento:
             @>Definir Rota de Movimento: [Silvhair] (Passar)
                                                                     : $>Mover a Direita


Ok! #Esquiva para Direita para manter distância estipulada.# Estamos assim:
@>Condição: Variável  [010:BossY-JogadorY] == 0
      @>Condição: Variável  [09:BossX-JogadorX] == -1

            @>Definir Rota de Movimento: [Silvhair] (Passar)
                  :                                                                  : $>Mover a Esquerda

            @>
        :    Fim da Condição
      @>Condição: Variável  [09:BossX-JogadorX] == 1
            @>Definir Rota de Movimento: [Silvhair] (Passar)
                  :                                                                  : $>Mover a Direita

            @>
        :    Fim da Condição
      @>
: Fim da condição

Boiada. Mais fácil que tirar chupeta de slime, não?

Configuraremos os movimentos verticais.
#CRIANDOS MOVIMENTOS: CIMA E BAIXO#
Essa eu passo para vocês. Pegue a imagem dos conceitos. Use as lições aprendidas acima e configure os movimentos verticais. Abaixo segue o resultado. Os comentários esclarecerão eventuais dúvidas.
DICA: Comece por um raciocínio igual ao dos casos anteriores, mas nesse contexto. Primeiro: Se o resultado de BossX-JogadorX é igual a zero, Evento e Jogador estão na mesma coluna. Novamente, acompanhe com a imagem da teoria. A partir daí, configure as hipóteses e os movimentos adeqüados.

@>Condição: Variável  [09:BossX-JogadorX] == 0
#Esta Condição analisa se Jogador e Boss estão na #
#mesma Coluna(X=0)#

      @>Condição: Variável  [010:BossY-JogadorY] == -1
#LEMBRE-SE: Se o Jogador está abaixo, valor é#
#negativo.

            @>Definir Rota de Movimento: [Silvhair] (Passar)
                  :                                                                  : $>Mover a Acima

            @>
#Esquiva para Cima para manter distância estipulada.#
        :    Fim da Condição
      @>Condição: Variável  [010BossY-JogadorY] == 1
#LEMBRE-SE: Se o Jogador está acima, valor é#
#positivo.

            @>Definir Rota de Movimento: [Silvhair] (Passar)
                  :                                                                  : $>Mover Abaixo

            @>
#Esquiva para Baixo para manter distância estipulada.#
        :    Fim da Condição
      @>
: Fim da condição


Para refletir. Seu evento é encurralado nas bordas? Reparou no que acontece se você colocar seu mapa com Loop de Ambos os lados? No caso, no que não acontece. E mais: Como usar distâncias >1 ou <-1 (como campo de visão --lembre-se que 0 é seu ponto de referência para analisar direções)?

Até o próximo episódio.
For all to be accomplished, for me to feel less lonely, all that remained to hope was that on the day of my execution there should be a huge crowd of spectators and that they should greet me with howls of execration.

Spoiler
[close]