Localização de caminho na grade para objetos que ocupam mais de um bloco

7

Em um jogo baseado em grade em que estou trabalhando, quero adicionar objetos que ocupam mais de um bloco da grade. Existem algoritmos ou técnicas para encontrar caminhos para esse tipo de objeto?

miguelSantirso
fonte

Respostas:

5

Em geral, você adaptará os algoritmos de busca de caminho existentes para serem sensíveis à largura. Principalmente, isso significa adaptar A *, embora, como seu jogo seja baseado em grade, você pode achar útil o algoritmo para resolver labirintos gordos .

Para A *, a solução mais básica é simplesmente adicionar uma asserção de largura aos seus cálculos, de acordo com as regras de movimento. No entanto, isso atrapalhará o seu código de busca de caminhos e diminuirá a busca de qualquer entidade de tamanho normal.

Como alternativa, você pode considerar sua grade como uma rede de localização de caminhos baseada em nó e, para suas entidades maiores, você pode criar uma rede secundária que seja responsável pelo tamanho e usá-la para movimento e localização de caminhos. Isso tem o benefício de permitir que você personalize seu caminho para entidades maiores, para que ele se comporte conforme o esperado, mas significa criar vários mapas para cada cena e mantê-los na memória, o que pode afetar os jogos em plataformas móveis.

Se nenhum desses métodos atender às suas finalidades, você poderá procurar inspiração nos algoritmos de busca de caminhos de malha de navegação , que são inerentemente sensíveis à largura.

Keeblebrox
fonte
6

Uma opção seria calcular uma segunda grade que leva em consideração o tamanho do objeto "pintando" ele na grade, assim. Aqui está a grade original:

#########
#..b....#
#.#.....#
#.####..#
#.......#
#.......#
#..#.#..#
#a.#.#..#
#########

Queremos ver se um objeto 2x2 pode passar de apara b. Calculamos uma segunda grade em que toda vez que temos uma parede ( #), adicionamos paredes acima e à esquerda ( x), transformando cada segmento de parede em um 2x2. Agora parece:

xxxxxxxxxx
x#########
x#xxb...x#
x#x#xxx.x#
x#x####.x#
x#......x#
x#.xxxx.x#
x#.x#x#.x#
x#ax#x#xx#
x#########

Podemos então encontrar o caminho nesta grade tratando o objeto como 1x1, pois a própria grade leva em consideração seu tamanho.

maravilhoso
fonte
11
Eu não gosto dessa opção muito porque eu precisaria criar uma grade diferente para cada tamanho do objeto ...
miguelSantirso
@miguelSantirso: Não, você só precisa incluir um amplo valor disponível para cada bloco. Supondo que você tenha vários tamanhos de lado a lado e um máximo pequeno, isso pode ser um campo de bits indicando se cada tamanho pode caber em cada quadrado.
Jack Aidley
0

Você pode estender a resposta da munificent para armazenar uma única grade de suporte, que, em vez de armazenar a passabilidade para cada tamanho de objeto diferente, armazena um campo de distância registrando o número de larguras de meia telha entre esse local e a barreira mais próxima. (Ou, como alternativa, a largura do maior objeto que pode ser centralizado nesse bloco sem atingir nada)

  • Um ladrilho de parede tem uma distância de -1 (o centro desse ladrilho fica dentro da maior parte da parede).
  • Um ladrilho adjacente a uma parede em pelo menos um lado tem uma distância de 1 (metade de um ladrilho separa o centro desse ladrilho da borda da parede mais próxima)
  • Um ladrilho sem paredes adjacentes, que é adjacente a um ladrilho adjacente a uma parede, tem uma distância de 3 (uma largura de ladrilho completo para alcançar o centro do vizinho e uma metade de ladrilho de lá para a parede)

Você pode preencher essa grade inicializando o mapa em um número inteiro maior que o tamanho do mapa em espaços vazios e -1 em sites de parede. Em seguida, defina iterativamente cada bloco> 0 para o mínimo de seus vizinhos mais dois.

Agora, dentro do seu algoritmo de busca de caminhos, você substitui

if (!IsPassable(PassabilityMap[x, y])) continue;

com

if (DistanceToObstacleMap[x, y] < pathfindingAgent.size) continue;

Agora você pode lidar com a busca de caminhos para qualquer tamanho de unidade com um único mapa, e a armazenagem / verificação da passabilidade permanece comparável em custo ao caso de um bloco por bloco.

DMGregory
fonte