Estoy buscando crear un sistema que reconozca ciertos tipos de edificios y habitaciones que puedes crear en el juego, como cómo Terraria detecta las "residencias". En ese juego, se puede construir una casa en un mundo basado en fichas construyendo una zona de bloques que satisfaga un conjunto de condiciones:
- La zona está completamente aislada del "exterior" por bloques colocados por jugadores.
- La zona puede caber en un rectángulo de 5x7.
- Hay al menos una mesa, una fuente de luz y una silla en el área cerrada.
- Hay una puerta que sale de la zona.
- Terraria tiene una capa de mosaico de primer plano y de fondo. Todo el fondo de la zona debe llenarse con bloques colocados por jugadores.
¿Cómo puedo detectar eficientemente cuando un jugador ha construido un área de tamaño adecuado, y cómo puedo verificar eficientemente que el área contenga todos los muebles / componentes requeridos?
Ejemplo de una zona interior que satisface todos los requisitos de vivienda:
spatial-partitioning
Bernardo Becker
fuente
fuente
Respuestas:
No estoy familiarizado con Terraria, pero eso se puede hacer fácilmente usando un algoritmo de relleno de inundación .
En lugar de píxeles, verifica los mosaicos, y para cada mosaico marcado, evalúa si el algoritmo puede continuar comprobando otros mosaicos, mientras almacena en una matriz o lista qué objetos se encuentran durante el proceso.
El algoritmo comienza en el mosaico donde está el personaje. Puede comenzar cada 1 segundo, 2 ... es cuestión de ajustar para encontrar el mejor intervalo.
También es una buena idea evitar que el algoritmo se ejecute durante demasiado tiempo, lo que se puede lograr limitando la cantidad de mosaicos que el algoritmo puede ejecutar por ejecución; de lo contrario, su algoritmo causará largos retrasos cuando el personaje se encuentre en un área abierta.
Editar
Como se indicó en los comentarios, puede usar otros enfoques sobre cuándo iniciar el algoritmo, como cuándo el jugador cambia un mosaico o los mosaicos que tienen una
am I modified?
variable que, sitrue
, inicia el algoritmo. Sin embargo, debe tener cuidado con este enfoque:Podría implementar algún tipo de enfoque para detectar estas modificaciones en los mosaicos en los que su personaje no está, pero ejecutar el algoritmo en intervalos es el enfoque más simple y menos propenso a errores. Solo asegúrese de no ejecutar el relleno de inundación en cada cuadro.
Fin de editar
fuente
isRoom()
Como dijo @Ferreira da Selva, pruebe el algoritmo de relleno de inundación. Sin embargo, puede utilizar algunos criterios diferentes al ejecutar el algoritmo para determinar si está incluido.
Por ejemplo, para cada mosaico verifica si hay un mosaico de fondo, y si no lo hay, entonces sabe que no está encerrado. O podría hacer que realice una ejecución diferida separándolo en varios cuadros, aligerando así la carga en el procesador y reduciendo el retraso. O podría crear un límite de tamaño de sala al que el jugador tendría que cumplir.
El uso de una combinación de estos le permitiría hacerlo de manera más eficiente y efectiva.
fuente
Hay 2 problemas difíciles en informática. Nombrar cosas, invalidación de caché y errores fuera de uno.
Este es un problema de invalidación de caché.
Si tiene un registro de "es esto dentro", cada vez que se coloca o elimina un bloque, es bastante fácil actualizarlo y su región a través de un relleno de inundación.
Para optimizar esto, es posible que desee tener un conjunto de niveles de "interioridad".
Una "celda" es una región rodeada de bloques colocados por jugadores (hasta cierto tamaño).
Una "habitación" es una celda con mosaicos de fondo.
"Inside" es una habitación con una puerta, una luz y una silla.
Cuando coloque un bloque de primer plano colocado por el jugador, realice una caminata en sentido horario / antihorario para ver si se forma una nueva celda. Cuando elimine un bloque de primer plano colocado por el jugador, examine si rompe alguna celda; de ser así, vea si se forma una nueva celda al fusionar las dos.
Cuando se forma o se forma una nueva celda, verifique si es una habitación o un interior.
Las celdas pueden realizar un seguimiento de cuántos mosaicos de fondo necesitan para ser una habitación. Luego, un recuento simple cuando se forma una celda, se agrega o elimina un mosaico de fondo de la celda, puede determinar si se trata de una habitación.
Del mismo modo, las celdas pueden realizar un seguimiento de cuántas sillas y fuentes de luz (y de hecho objetos de todo tipo) están dentro de ellas. Entonces el control interno es trivial.
También se puede hacer un recuento de entradas.
Entonces aumentamos el mapa con "celdas". Cuando se agregan o eliminan fichas, verificamos la celda de la ubicación e incrementamos / disminuimos el recuento en la celda.
Use la marcha en sentido horario / antihorario para definir el interior y el exterior de una celda cuando se agrega o elimina un bloque de primer plano. Como el tamaño de las celdas es limitado, esta caminata tendrá un número limitado de pasos.
Como beneficio adicional, ahora tiene una forma barata de hablar sobre habitaciones "opulantes", o "la habitación está bendecida por una fuente sagrada", o cualquier otra cosa sobre una habitación, ya que las habitaciones tienen un recuento de cada tipo de objeto dentro de ellas. (O, como las habitaciones están limitadas en tamaño, solo haga una iteración; esto elimina un caché).
Cada ubicación se encuentra como máximo en una celda, por lo que puede almacenar la identificación de celda de cada ubicación en el mapa principal.
fuente
Cuando use el algoritmo de relleno de inundación, haga también una variable, que se incrementará con cada mosaico marcado, por lo que si es superior a 35 (7 * 5, el tamaño máximo de la habitación) ¡simplemente deja de verificar!
fuente