Flow Fields PhaserJS

Flow Fields é um termo utilizado para descrever um campo de vetores. Este campo de vetores pode ser utilizado para várias aplicações, desde edição de fotos e vídeos até video games, que é o nosso caso aqui. Neste artigo vou te mostrar como funciona este conceito em um jogo de RTS.

Movimentação em Grupo

Bom, há bastante tempo eu venho buscando a melhor forma de movimentar as minhas unidades em grupos. Passei alguns meses estudando Flocking Simulation de Craig Reynolds, este algoritmo serve para simular o movimento coordenado de multidões, se você já leu o meu artigo sobre a criação do meu jogo de RTS, você já me ouviu falar sobre ele. Acontece que Flocking Simulation é um processo muito caro para a CPU, na época eu não tinha muita ideia de como implementar isso no meu jogo e acabei abortando o processo.

Acontece que eu não abandonei o assunto por completo, a movimentação atual do meu jogo não me agrada em nada, até mesmo porque o tempo de resposta para mudança de direção é muito lento. A unidade faz um moon walker sempre que eu mando ela mudar de direção. Isso acontece porque eu não uso velocity para mudar ele de direção e sim Tweens.

Moonwalker

Resolvi estudar novamente o assunto e me deparei com um vídeo que me deixou super-animado para tentar novamente. É um vídeo de um jogo chamado Planetary Annihilation, mostrando como a sua movimentação seria implementada. Este conceito é o mesmo que foi utilizado pelo jogo Supreme Commander 2, e também será pelo Age of Empires 4, Mas o que todos estes jogos tem em comum? O mesmo engenheiro de Software, Elijah Emerson, o carinha de óculos do vídeo do Planetary Annihilation. Atualmente Elijah trabalha para a Microsoft.

Qual a vantagem de Flow Fields?

A grande vantagem de utilizar flow fields, é que um grupo de unidades pode compartilhar o mesmo flow field. Isso reduz os custos dos algoritmos de Path Finding drasticamente quando utilizados corretamente. Nós vamos explorar o conceito base por trás de flow fields.

Como gerar o Flow Field?

Pra gerar este campo de vetores é preciso ter um ponto de objetivo, ou um alvo para levar as unidades e à partir deste alvo criamos este campo. O algoritmo utilizado para isso é conhecido como Wavefront/Grassfire/Brushfire. Sim, ele tem uma porção de nomes e este foi um dos meus desafios, pesquisar algo que eu não sabia o que era nem como se chamava.

Em síntese, zeramos a posição alvo e começamos a adicionar 1 às posições vizinhas.

flow fields
Mapa de custos
let neighbour_tile = current_tile + 1;
Atualizando Mapa de Custos

Eu utilizei uma versão modificada do algoritmo de Dijkstra, que é a base do A*. A diferença é que eu não paro quando encontro o objetivo, mas continuo até terminar de ler o Grid.

Gerando o Flow Field

Para gerar o flow field precisamos verificar o valor de cada grid que calculamos anteriormente, vamos chamá-lo de custo. Da mesma forma que anteriormente, vamos verificar os valores vizinhos e gerar um vetor à partir destes valores.

vector.x = left_cost - right_cost;
vector.y = up_cost - down_cost;
flow fields
Campo de vetores – Flow Field

Por fim, basta colocar as unidades no grid e fazer com que elas apliquem o vetor à aceleração da partícula.

Flow Field

Conclusão

Gerar flow fields só é benéfico quando existem muitas unidades que precisam partilhar de um caminho semelhante, não é recomendável utilizar esta técnica para poucas unidades. Para mim o processo foi bem divertido, porém demorado, devido às informações dispersas. Ainda não implementei o algoritmo no meu jogo pois ainda faltam alguns passos de otimização. Porém eu queria compartilhar o conceito e a jornada que tive até aqui. Fique ligado pra não perder o novo Dev Log que vem por ai, este promete.

Referências

Emerson, Elijah. “Crowd Pathfinding and Steering Using Flow Field Tiles.” Game AI Pro: Collected Wisdom of Game AI Professionals. Boca Raton: CRC, 2014. 307-23. Print.

https://gamedevelopment.tutsplus.com/tutorials/understanding-goal-based-vector-field-pathfinding–gamedev-9007

Leave a comment

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Copyright © – Jonatan Pietroski