Determinar si la estructura creada por el jugador coincide con una plantilla en un juego basado en bloques 3D


8

Descargo de responsabilidad: esta es una de esas temidas preguntas de estilo Minecraft, pero creo que es más una pregunta de estructuras de datos y algoritmos

Soy realmente nuevo en las estructuras de datos 3D y me pregunto cuál es la mejor manera de almacenar y combinar una estructura de bloques 3D.

En este momento, el jugador puede colocar bloques en cualquier espacio arbitrario y cuando estos bloques coinciden con una estructura predefinida, ocurre un evento. La forma en que lo hago actualmente es cuando un jugador coloca un bloque, el juego verifica recursivamente cada bloque adyacente para encontrar el bloque con la coordenada x, y, z más baja y hace que ese bloque sea el bloque raíz. Luego verifica el resto de los bloques, basados ​​en el bloque raíz, para asegurarse de que coincidan con una plantilla determinada. El problema es que a medida que la plantilla se vuelve más complicada, también lo hace mi código (terriblemente ineficiente).

Creo que la mejor manera de hacer esto es almacenar algún tipo de matriz que defina la estructura y luego compararla con la matriz cada vez que un jugador coloque un bloque. ¿Ya existen estructuras / algoritmos de datos que coincidan con este tipo de problema?


1
Como ejemplo, ¿estás pensando en cómo modelar estructuras como un portal de Minecraft?
desaceleratedcaviar

1
@Daniel En realidad, supongo que sería un buen ejemplo. Aunque, mi objetivo sería tener una estructura arbitrariamente grande / compleja. Los portales son bastante simples.
WillP

1
No es una respuesta, sino solo un pensamiento: si las estructuras se vuelven arbitrariamente grandes y la lista de estructuras objetivo (que tiene que buscar para encontrar una coincidencia) se vuelve increíblemente grande, esto se convierte en un problema de reconocimiento de patrones, como reconocer texto o voz. Luego te alejas de la comparación de la fuerza bruta hacia métodos estadísticos como los modelos ocultos de Markov entrenados en tus estructuras objetivo. Eso sería genial.
Pieter Müller

@ Harikawashi Oh hombre, eso sería genial. Aunque mi objetivo no es algo astronómicamente grande, puedo hacerlo de todos modos solo para poder jugar con eso. ¡Gracias!
WillP

Respuestas:


10

Para ser honesto, tomaría la solución simple.

Haz una matriz que defina la estructura. Siempre que se cambie un bloque, intente aplicar esa matriz a todas las ubicaciones que podrían haber creado la nueva estructura. Serán ubicaciones de ancho * profundidad * altura, ya que el jugador podría haber terminado cualquier punto de la estructura, pero no debería ser tan malo porque la mayoría de estas ubicaciones saldrán temprano cuando falle la primera verificación.

Básicamente, tienes una matriz 3d, y la estás comparando con otra matriz 3d, en un montón de desplazamientos.

Desde aquí hay un montón de optimizaciones totalmente opcionales que puedes hacer. Por ejemplo, si su estructura es extremadamente escasa, es decir, el jugador está construyendo una torre alta con una esfera en la parte superior, pero no le importa si la parte inferior de la torre está rodeada de árboles, puede convertirla en una lista de bloques en lugar de una matriz. (Generaría la lista a partir de la matriz; la matriz será mucho más fácil de mantener directamente).

Si querías ser súper inteligente, divide la estructura en bloques. Si sabes que el jugador acaba de cambiar el bloque 1,2,3, y sabes que colocar tu estructura en las coordenadas 0,0,0 requeriría que el bloque 1,2,3 sea obsidiana, y el bloque 1,2,3 es madera , entonces ni siquiera necesitas probar el bloque 1,2,3. Genere todas las compensaciones posibles para la estructura dado que el jugador acaba de colocar un tipo específico de bloque. Luego, cuando el jugador coloca ese bloque, simplemente verifica las posibles compensaciones pregeneradas.

Pero, en serio, todo esto es optimización. Simplemente haga una matriz, luego compare su matriz con el estilo mundial de fuerza bruta. Asumiendo que estás haciendo algo Minecrafty, la gente realmente no coloca tantos bloques, unos cuantos bloques por segundo como máximo. A menos que tenga cientos de estructuras enormes, podrá probar eso fácilmente.


3
Tienes razón. La fuerza bruta realmente no debería ser un gran problema de rendimiento. Siento que he caído en la trampa de la optimización prematura. Gracias por tu perspicacia.
WillP

0

Bueno, se te ocurre un problema interesante. Sugeriría algo como lo siguiente: use sus bloques como píxeles y realice una detección de colisión por píxel, donde todos los bloques deben coincidir para devolver una verdadera colisión.

Esto funcionaría bien, sin embargo, asegúrese de hacerlo solo cuando cambien los objetos / bloques. Por lo tanto, recomendaría un sistema de eventos simple para pasar un cambio a un verificador de objetos, que ciertamente puede usar su algoritmo. Lo que luego haría lo que quieras que haga ese objeto. También recomendaría verificar la altura y el ancho, antes de ejecutar el algoritmo, porque si no es lo suficientemente alto / es demasiado alto, obviamente no coincidirá.

En cuanto a una estructura de datos, lo haría un vector simple, o tal vez una estructura de datos personalizada.

Interesante pregunta.

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.