Klingt so, als wollten Sie etwas über Bäume lernen!
Und ich meine es ernst, wenn Sie derzeit eine Schleife über ein Array all Ihrer Cubes erstellen, sollten Sie sich wirklich mit verschiedenen räumlichen Datenstrukturen befassen. In diesem Fall können Sie sich Ihre Würfelwelt am besten als Baum vorstellen.
Bevor wir auf die Gründe eingehen, warum, lassen Sie uns über unser Problem nachdenken. Wir suchen nach einer Lösung, mit der wir zu möglichst geringen Kosten eine Liste von Würfeln in der Nähe abrufen können, mit denen der Spieler möglicherweise kollidiert. Diese Liste sollte so klein und genau wie möglich sein.
Um diese Zone zu bestimmen, müssen wir den Koordinatenraum unseres Spielers auf den Koordinatenraum der Würfelkarte abbilden. Das heißt, wir müssen die Gleitkommaposition des Players auf einen diskreten Index des mehrdimensionalen Arrays von Cubes abbilden (Beispielnotation könnte zB world[31][31][31]
genau die Mitte für ein mehrdimensionales 64 * 64 * 64-Array sein).
Wir könnten einfach die umgebenden Blöcke mit derselben diskreten Indizierung berechnen, vielleicht nur die nahe gelegenen Würfel abtasten, aber dies erfordert immer noch eine ständige Neuberechnung und lässt keine Objekte zu, die nicht diskret platziert sind (dh möglicherweise nicht dem Würfel zugeordnet sind Karte).
Die ideale Situation ist ein Satz von Eimern, die unsere Würfelsätze für bestimmte Abschnitte unserer Würfelkarte enthalten, die gleichmäßig aufgeteilt sind. Statt die Umgebung neu zu berechnen, bewegen wir uns einfach in diese Zonen hinein und aus diesen heraus . Bei einer nicht trivialen Berechnung kann das Speichern dieser Daten dazu führen, dass nicht alle Cubes wiederholt werden, sondern nur die einzelnen Sets in der Nähe.
Die Frage ist: Wie setzen wir das um?
Stellen Sie sich für die 64 * 64 * 64-Welt vor, dass sie in 8 * 8 * 8- Zonen unterteilt ist . Dies bedeutet, dass Sie in Ihrer Welt 8 Zonen pro Achse haben (X, Y, Z). Jede dieser Zonen enthält 8 Würfel, die mit diesem neuen vereinfachten Index leicht abgerufen werden können.
Wenn Sie eine Operation für eine Gruppe benachbarter Cubes ausführen müssen, anstatt jeden Cube in Ihrer Welt zu durchlaufen, können Sie diese Zonen einfach durchlaufen und dabei die maximale Anzahl von Iterationen von 64 * 64 * 64 (262144) bis auf aufschlüsseln nur 520 (8 * 8 * 8 + 8).
Zoomen Sie nun aus dieser Zonenwelt heraus und ordnen Sie die Zonen in größere Superzonen ein . wobei jede Superzone 2 · 2 · 2 reguläre Zonen enthält . Da Ihre Welt derzeit 512 (8 * 8 * 8) Zonen enthält , können wir die 8 * 8 * 8- Zonen in 64 (4 * 4 * 4) Superzonen aufteilen, indem wir 8 Zonen durch 2 Zonen pro Superzone teilen . Wendet man dieselbe Logik von oben an, würde dies die maximalen Iterationen von 512 auf 8 unterbrechen, um die Superzone zu finden . und dann maximal 64, um die vorgehende Zone zu finden(insgesamt max 72)! Sie können sehen, wie viele Iterationen dadurch bereits gespart werden (262144: 72).
Ich bin sicher, Sie können jetzt sehen, wie nützlich Bäume sind. Jede Zone ist eine Verzweigung im Baum, wobei jede Superzone eine vorangehende Verzweigung ist. Sie durchqueren einfach den Baum, um das zu finden, was Sie brauchen. Verwendung kleinerer Datensätze zur Minimierung der Gesamtkosten.
Das folgende Diagramm soll Ihnen helfen, das Konzept zu visualisieren. (Bild von Wikipedia: Octrees ):
Haftungsausschluss:
In einer idealen Konfiguration wie oben, in der Ihre Voxel-Welt bereits in einem mehrdimensionalen Array fester Größe angeordnet ist, können Sie einfach die Spielerposition abfragen und dann die umgebenden Blöcke mit einem O (1) -Kosten indexieren! (Siehe Olhovskys Erklärung) Dies wird jedoch schwieriger, wenn Sie bedenken, dass Ihre Welt in einem Voxel-Spiel selten eine feste Größe hat. und Sie benötigen möglicherweise Ihre Datenstruktur, um ganze Superzonen von der Festplatte in den Speicher laden zu können. Im Gegensatz zu einem mehrdimensionalen Array mit fester Größe ermöglichen Bäume dies ohne großen Zeitaufwand für kombinatorische Algorithmen.