Antecedentes
Junto con un amigo estoy trabajando en un juego 2D que se desarrolla en el espacio. Para hacerlo lo más inmersivo e interactivo posible, queremos que haya miles de objetos flotando libremente, algunos agrupados, otros a la deriva en el espacio vacío.
Desafío
Para descargar el motor de renderización y física, necesitamos implementar algún tipo de partición espacial. Hay dos desafíos que tenemos que superar. El primer desafío es que todo se está moviendo, por lo que la reconstrucción / actualización de la estructura de datos debe ser extremadamente económica, ya que tendrá que hacerse en cada cuadro. El segundo desafío es la distribución de objetos, como se dijo antes, podría haber grupos de objetos juntos y vastos trozos de espacio vacío y, para empeorar aún más, no hay límite para el espacio.
Tecnologías existentes
He analizado las técnicas existentes como BSP-Trees, QuadTrees, kd-Trees e incluso R-Trees, pero por lo que puedo decir, estas estructuras de datos no se ajustan perfectamente desde la actualización de muchos objetos que se han movido a otras celdas Es relativamente caro.
Lo que he intentado
Tomé la decisión de que necesito una estructura de datos que esté más orientada a la inserción / actualización rápida que a devolver la menor cantidad de visitas posibles dada una consulta. Para ese propósito, hice las celdas implícitas para que cada objeto, dada su posición, pueda calcular en qué celda (s) debería estar. Luego uso un HashMap
que asigna coordenadas de celda a un ArrayList
(el contenido de la celda). Esto funciona bastante bien ya que no se pierde memoria en las celdas 'vacías' y es fácil calcular qué celdas inspeccionar. Sin embargo, crear todos esos ArrayList
s (el peor de los casos, N) es costoso y, por lo tanto, está creciendo HashMap
muchas veces (aunque eso se mitiga ligeramente al darle una gran capacidad inicial).
Problema
Bien, esto funciona pero aún no es muy rápido. Ahora puedo intentar micro-optimizar el código JAVA. Sin embargo, no espero demasiado de eso, ya que el generador de perfiles me dice que paso la mayor parte del tiempo creando todos los objetos que uso para almacenar las celdas. Espero que haya otros trucos / algoritmos que lo hagan mucho más rápido, así que aquí está mi estructura de datos ideal:
- La prioridad número uno es la rápida actualización / reconstrucción de toda la estructura de datos.
- Es menos importante dividir finamente los objetos en contenedores de igual tamaño, podemos dibujar algunos objetos adicionales y hacer algunas comprobaciones adicionales de colisión si eso significa que la actualización es un poco más rápida
- La memoria no es realmente importante (juego de PC)