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?
Respuestas:
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.
fuente
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.
fuente