Contexte
Avec un ami, je travaille sur un jeu 2D qui se déroule dans l'espace. Pour le rendre aussi immersif et interactif que possible, nous voulons qu'il y ait des milliers d'objets flottant librement, certains regroupés, d'autres à la dérive dans un espace vide.
Défi
Pour décharger le moteur de rendu et de physique, nous devons implémenter une sorte de partitionnement spatial. Nous devons surmonter deux défis. Le premier défi est que tout bouge, donc la reconstruction / mise à jour de la structure de données doit être extrêmement bon marché car cela devra être fait à chaque trame. Le deuxième défi est la distribution des objets, comme dit précédemment, il pourrait y avoir des grappes d'objets ensemble et de vastes espaces vides et, pour aggraver encore, il n'y a pas de limite à l'espace.
Technologies existantes
J'ai examiné des techniques existantes telles que les arbres BSP, les arbres Quad, les arbres kd et même les arbres R, mais pour autant que je sache, ces structures de données ne sont pas parfaites depuis la mise à jour de nombreux objets qui ont été déplacés vers d'autres cellules est relativement cher.
Ce que j'ai essayé
J'ai pris la décision d'avoir besoin d'une structure de données plus orientée vers l'insertion / la mise à jour rapide que pour redonner le moins de résultats possibles à une requête. À cette fin, j'ai rendu les cellules implicites afin que chaque objet, étant donné sa position, puisse calculer dans quelle (s) cellule (s) il devrait être. Ensuite, j'utilise un HashMap
qui mappe les coordonnées des cellules à un ArrayList
(le contenu de la cellule). Cela fonctionne assez bien car il n'y a pas de mémoire perdue sur les cellules «vides» et il est facile de calculer les cellules à inspecter. Cependant, la création de tous ces ArrayList
s (pire cas N) est coûteuse et augmente donc HashMap
beaucoup de fois (bien que cela soit légèrement atténué en lui donnant une grande capacité initiale).
Problème
OK donc cela fonctionne mais n'est pas très rapide. Maintenant, je peux essayer de micro-optimiser le code JAVA. Cependant, je n'attends pas trop de cela, car le profileur me dit que la plupart du temps est consacré à la création de tous les objets que j'utilise pour stocker les cellules. J'espère qu'il y a d'autres astuces / algorithmes qui rendent cela beaucoup plus rapide alors voici à quoi ressemble ma structure de données idéale:
- La priorité numéro un est la mise à jour / reconstruction rapide de toute la structure de données
- Il est moins important de diviser finement les objets en bacs de taille égale, nous pouvons dessiner quelques objets supplémentaires et effectuer quelques vérifications de collision supplémentaires si cela signifie que la mise à jour est un peu plus rapide
- La mémoire n'est pas vraiment importante (jeu PC)