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?
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?
Respostas:
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.
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 a
para 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.
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)
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.