¿Cómo puedo detectar "habitaciones" en un juego de desplazamiento lateral en 2D?


24

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:

  1. La zona está completamente aislada del "exterior" por bloques colocados por jugadores.
  2. La zona puede caber en un rectángulo de 5x7.
  3. Hay al menos una mesa, una fuente de luz y una silla en el área cerrada.
  4. Hay una puerta que sale de la zona.
  5. 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:

ingrese la descripción de la imagen aquí


55
¿Podrías dar más detalles? ¿Qué quiere decir con "tipos de construcciones" y qué es una "residencia" en Terraria? Tenga en cuenta que no todos han jugado ese juego, también enfóquese en una pregunta si desea que la gente ayude, y asegúrese de que esa pregunta tenga una respuesta definitiva (no opiniones)
TomTsagk

1
Con los tipos me refiero a diferentes componentes / mosaicos utilizados. Mi pregunta se resuelve a continuación. Intentaré trabajar más y ser más específico en futuras preguntas, gracias por la ayuda.
Bernardo Becker

1
Por otro lado, asegúrese de que haya una diferencia entre un habitación y una residencia . Su lista de viñetas sugiere que las vea como la misma definición. Usando Terraria como ejemplo, los enemigos no se generan en habitaciones, incluso si no son elegibles como residencias (por ejemplo, falta una mesa, o solo 5x5 en dimensión)
Flater

Respuestas:


37

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, si true, inicia el algoritmo. Sin embargo, debe tener cuidado con este enfoque:

  • ¿Qué pasa si se modifica una ficha que es parte de la habitación, pero no una ficha en la que se encuentra tu personaje? Tal vez el mosaico fue cambiado por otro jugador, o un evento ambiental, o la vida útil del mosaico terminó. Tu personaje no será consciente de la modificación y no ejecutará el algoritmo para detectar la sala actualizada, una situación propensa a errores.

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


99
¿Por qué no llenar con inundación solo entre las fichas de "bloque colocado por el jugador"? Esto podría prevenir o reducir el relleno de inundación infinito en áreas abiertas (siempre que las cuevas / mansiones no estén llenas de "bloques colocados por el jugador").
jimbo1qaz

20
¿Por qué ejecutarías esto en un intervalo fijo? Seguramente puede ejecutarlo cuando se coloca un bloque (o se destruye, si corresponde, y ambos casos probablemente se pueden hacer en tiempo constante amortizado por bloque) o al cargar una parte particular del mapa, y luego almacenar el resultado desde allí.
NotThatGuy

3
@immibis: estoy bastante seguro de que Terraria no requiere que cambies el piso. Tampoco esperaría que un juego cambie su comportamiento de reconocimiento de sala en función de quién colocó la ficha. ¿Qué sucede si, por ejemplo, construyo una habitación adyacente a un acantilado?
Flater

3
Terraria requiere uno para poner paredes de fondo y no formará una casa con tierra / roca de fondo natural. Realmente verifica solo los bloques colocados por el jugador.
loa_in_

3
Para guardar la CPU, solo ejecutaba el algoritmo en el cambio de bloque y luego almacenaba el estado de cada bloque. Con esto, es simpleisRoom()
Herr Derb

3

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.


3

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.


0

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!


7 * 5 es el rectángulo de tamaño mínimo que debe caber dentro de la habitación
Rick
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.