Elija mosaico basado en mosaicos adyacentes

10

Estoy trabajando en un editor de mapas en mosaico, y necesito elegir mosaicos automáticamente, en función de los mosaicos adyacentes. Por ejemplo, al colocar un mosaico de carreteras, junto a otro mosaico de carreteras, los dos deben estar orientados para que formen una carretera continua. Si hay otras carreteras a su alrededor, es posible que necesitemos usar mosaicos de esquina o intersección.

¿Alguien puede recomendar algunos algoritmos para hacer esto? El juego utiliza un mapa de mosaico cuadrado de 8 direcciones.

alekop
fuente
¿No puede simplemente examinar todos los 8 mosaicos circundantes cada vez que el usuario coloca un nuevo mosaico y orientar el nuevo mosaico en consecuencia? Por supuesto, deberá almacenar información adicional sobre cada mosaico, como la orientación y el tipo.
XiaoChuan Yu
Estoy examinando todos los mosaicos circundantes, pero no sabía cómo manejar todas las combinaciones de mosaicos. Por ejemplo, tiene siete mosaicos posibles para elegir (horizontal, vertical, cuatro esquinas y una cruz). Pensé en usar declaraciones de cambio complicadas, pero eso se sintió mal.
alekop

Respuestas:

18

Tal vez así es como se hace típicamente. Tiene su lista de diferentes mosaicos que representan los mosaicos de una carretera en todas sus orientaciones posibles. De izquierda a derecha, las cuatro esquinas, de arriba a abajo, lo que sea. Ahora indexará todos esos mosaicos con un byte cada uno. 8 bits, uno para cada dirección. Esto podría estar en un hashmap o por nombre de archivo ... sin embargo, desea hacer esto.

Entonces tienes esto:

ingrese la descripción de la imagen aquí

El código de byte para el mosaico anterior es 00000000 . Entonces su mosaico que va de izquierda a derecha (o de derecha a izquierda) es así:

ingrese la descripción de la imagen aquí

El código de byte para ese mosaico es 10001000 , o 136. Como otro ejemplo, veamos una intersección de tres vías:

ingrese la descripción de la imagen aquí

El código de byte para ese mosaico es 10101000 .

Probablemente veas a dónde voy. Establece posiciones de bit en el byte que representa las conexiones. Esto es mucho mejor que tratar de hacer una gran cadena if / else que he visto antes. Cuando busque colocar un mosaico, examine los mosaicos a su alrededor y cree un byte en el camino. Establezca 1 para las fichas que tienen carreteras (o lo que sea que desee conectar) y 0 para las fichas que no. Cuando haya terminado, tendrá el código de bytes para el mosaico exacto que necesita.

Tenga en cuenta que al crear los activos puede reutilizar muchos de ellos simplemente girando y asignándole el código de byte correcto.

EDITAR : imágenes actualizadas para ser menos horrible. Sí, esos son mejores que antes.

MichaelHouse
fuente
¡Muy agradable! Simple y eficiente. Lo único que no entiendo es cómo estás obteniendo esas máscaras de bits. Por ejemplo, ¿cómo está obteniendo una máscara de bits de 17 de los números 3 y 7?
alekop
No importa, veo lo que estás haciendo. Estás configurando los bits 3 y 7, pero estás contando desde la izquierda, en lugar de desde la derecha.
alekop
Oh wow, qué vergonzoso. Tengo mi Endianness todo mezclado. ¡Eso fue un accidente, lo arreglaré!
MichaelHouse
¡Genial, ahora mi comentario no tiene sentido! : p Es broma, gracias por tu respuesta. Eso es exactamente lo que estaba buscando.
alekop
1
Buena explicación. Tengo una publicación de blog que cubre la misma técnica con código real y resolución de mosaico: kitsu.github.io/2016/07/18/roguelike-project-05
kitsu.eb
3

Le recomendaría que eche un vistazo a esta práctica página para obtener más información, ya que entra en detalles sobre casi todos los aspectos de lo que está haciendo, así como algunas optimizaciones potenciales: http://www.angryfishstudios.com / 2011/04 / adventures-in-bitmasking /

El tldr es que consulta cada celda adyacente y almacena la combinación en un campo de bits / byte, luego la pasa a través de un mapa que convierte un número de 0 ~ 255 en un valor de 0 ~ 47, que corresponde a una imagen única.

Kyle Baran
fuente