Escolha o bloco com base nos blocos adjacentes


10

Estou trabalhando em um editor de mapas lado a lado e preciso escolher os blocos automaticamente, com base nos blocos adjacentes. Por exemplo, ao colocar um ladrilho de estrada, próximo a outro ladrilho de estrada, os dois precisam ser orientados para formar uma estrada contínua. Se houver outras estradas ao seu redor, talvez seja necessário usar ladrilhos de esquina ou interseção.

Alguém pode recomendar alguns algoritmos para fazer isso? O jogo usa um mapa de azulejos quadrados de 8 direções.


Você não pode simplesmente examinar todos os 8 blocos ao redor sempre que o usuário coloca um novo bloco e orientar o novo bloco adequadamente? Obviamente, você precisará armazenar algumas informações extras em cada bloco, como orientação e tipo.
XiaoChuan Yu

Estou examinando todas as peças circundantes, mas não sabia como lidar com todas as combinações de peças. Por exemplo, você pode escolher entre sete peças possíveis (horizontal, vertical, quatro cantos e uma cruz). Pensei em usar instruções de chave complicadas, mas isso parecia errado.
Alekop 23/05

Respostas:


18

Talvez seja assim que normalmente é feito. Você tem sua lista de ladrilhos diferentes que representam um ladrilho de estrada em todas as orientações possíveis. Da esquerda para a direita, todos os quatro cantos, de cima para baixo, qualquer que seja. Agora você indexará todos esses blocos com um byte cada. 8 bits, um para cada direção. Isso pode estar em um hashmap ou pelo nome do arquivo ... no entanto, você deseja fazer isso.

Então você tem isso:

insira a descrição da imagem aqui

O código de bytes do bloco acima é 00000000 . Então seu bloco que vai da esquerda para a direita (ou da direita para a esquerda) fica assim:

insira a descrição da imagem aqui

O código de bytes para esse bloco é 10001000 ou 136. Como outro exemplo, vamos ver uma interseção de três maneiras:

insira a descrição da imagem aqui

O código de bytes desse bloco é 10101000 .

Você provavelmente vê para onde estou indo. Você define as posições dos bits no byte que representa as conexões. Isso é muito melhor do que tentar fazer uma grande cadeia if / else que eu já vi antes. Quando estiver procurando colocar um bloco, examine os blocos ao redor e crie um byte ao longo do caminho. Defina 1 para blocos que possuem estradas (ou o que você deseja conectar) e 0 para blocos que não têm. Quando terminar, você terá o código de bytes do bloco exato de que precisa.

Observe que, ao criar os ativos, você pode reutilizá-los bastando girar e atribuir o código de bytes correto a ele.

EDIT : Imagens atualizadas para serem menos ruins. Sim, esses são melhores do que antes.


Muito agradável! Simples e eficiente. A única coisa que eu não entendo é como você está recebendo essas máscaras. Por exemplo, como você está obtendo uma máscara de bit 17 dos números 3 e 7?
Alekop 23/05

Não importa, eu vejo o que você está fazendo. Você está configurando os bits 3 e 7, mas está contando da esquerda, e não da direita.
Alekop # 23/12

Oh uau, que vergonha. Misturei meu Endianness . Isso foi um acidente, eu vou consertar isso!
MichaelHouse

Ótimo, agora meu comentário não faz sentido! : p Brincadeira, obrigado pela sua resposta. Era exatamente o que eu estava procurando.
Alekop 23/05

1
Boa explicação. Eu tenho um blog que cobre a mesma técnica com código real e resolução de telha: kitsu.github.io/2016/07/18/roguelike-project-05
kitsu.eb

3

Eu recomendo que você dê uma olhada nesta página útil para obter mais informações, pois ela detalha praticamente todos os aspectos do que você está fazendo, bem como algumas otimizações em potencial: http://www.angryfishstudios.com / 2011/04 / aventuras-em-bitmasking /

O tldr é que você consulta cada célula adjacente e armazena a combinação em um campo de bits / byte, depois passa por um mapa que converte um número de 0 a 255 em um valor de 0 a 47, o que corresponde a uma imagem exclusiva.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.