Diese Woche habe ich angefangen, an einem neuen Thema zu arbeiten: der Erzeugung von Dungeons und Höhlen. Ich habe Raumpartitionierung verwendet, um RĂ€ume zu generieren, Labyrinth-Generierungsalgorithmen, um Korridore zu generieren, und zellulare Automaten, um den Höhlen ein natĂŒrlicheres Aussehen zu verleihen.
Raumaufteilung
Es gibt viele Möglichkeiten, DungeonrÀume zu generieren (
zufÀllige Platzierung ,
agentenbasierte Generierung , Verwendung des
Trennungslenkverhaltens oder einer
physischen Engine usw.). Aber meine Lieblingsmethode ist es, den Raum zu teilen, weil er leicht zu steuern und zu erweitern ist.
Es gibt auch viele Möglichkeiten, den Raum zu teilen: Aufteilung in Gitter, binĂ€re Aufteilung des Raums, Aufteilung des Raums durch einen Quadrantenbaum, Voronoi-Diagramme usw. Ich habe mich fĂŒr eine binĂ€re Raumaufteilung entschieden, da sie sich gut zur Erzeugung rechteckiger RĂ€ume eignet. Diese Methode hat dank eines
Artikels ĂŒber RogueBasin an PopularitĂ€t gewonnen.
Die einzige KomplexitÀt dieses Algorithmus ist die Wahl der Trennposition. Wenn wir die Trennposition nicht einschrÀnken, erhalten wir seltsame Raumpartitionen:
Es gibt verschiedene Möglichkeiten, um dieses Verhalten zu vermeiden. Eine davon besteht darin, die Trennposition auf zwei AspektverhĂ€ltnisse zu beschrĂ€nken, beispielsweise im Bereich von 30% bis 70% oder von 40% bis 60%. Eine andere Möglichkeit besteht darin, anstelle einer gleichmĂ€Ăigen Verteilung Normal- oder Binomialwerte zu verwenden, wodurch die Wahrscheinlichkeit einer Trennung in der Mitte der Seite und nicht an den RĂ€ndern erhöht wird. Diese Methoden beheben das Problem, aber es ist schwer zu verstehen, wie genau sich die Parameter auf das Endergebnis auswirken.
Daher habe ich eine andere Methode verwendet, deren Vorteil darin besteht, dass sie einen Parameter hat und leicht zu verstehen ist: das maximal zulĂ€ssige VerhĂ€ltnis zwischen LĂ€nge und Breite der Zellen. Wenn ich eine neue Trennung abtaste, berechne ich zuerst die minimalen und maximalen Werte, die sie haben kann, damit das VerhĂ€ltnis fĂŒr zwei neue Zellen unter dem Grenzwert liegt, und fĂŒhre dann eine einheitliche Abtastung zwischen diesen beiden Grenzen durch. Hier ist das Ergebnis beim Variieren des maximal zulĂ€ssigen VerhĂ€ltnisses:
Gute Ergebnisse werden mit einem maximalen VerhÀltnis von 2,0 zu 3,0 erzielt:
Raumgenerierung
Die nÀchste Stufe ist die Erzeugung in jeder Zelle des Raumes. Hier gibt es keine besonderen Probleme, ich habe nur Grenzen gesetzt, damit die RÀume nicht zu klein und nicht zu nahe an den ZellwÀnden sind.
Hier sind die Ergebnisse:
Rippenauswahl
In binÀren Teilungs-Dungeon-Generatoren wird der im Teilungsschritt verwendete BinÀrbaum normalerweise wiederverwendet, um Korridore zu erzeugen. Ich habe das nicht getan, weil mir ein solcher Ansatz einschrÀnkend erscheint.
Stattdessen baue ich beim Teilen des Raums die
Struktur einer doppelt verbundenen Liste von Kanten auf , anhand derer wir erkennen können, welche Zellen sich nebeneinander befinden. Auf diese Weise erhalte ich folgende Grafiken:
Dieser Ansatz bietet drei Vorteile. Erstens: Wenn ich in Zukunft die Art der Raumteilung Ă€ndern möchte, bleibt der Rest des Generators gĂŒltig, da er am Eingang nur eine Halbkanten-Datenstruktur empfĂ€ngt. Zweitens: Um nun die Kanten auszuwĂ€hlen, die zu Korridoren werden sollen, kann ich einen beliebigen
Algorithmus zum Erzeugen von Labyrinthen verwenden . Drittens: Wenn ich dem Dungeon Schleifen hinzufĂŒgen möchte, kann ich dies einfach implementieren.
Im Moment verwende ich nur den Kruskal-Algorithmus und den Abstand der Stadtblöcke, um Kanten auszuwÀhlen. Hier sind die Ergebnisse:
Korridorgenerierung
Der nÀchste Schritt besteht darin, Korridore aus den ausgewÀhlten Kanten zu generieren. Dies ist wahrscheinlich der schwierigste Teil des Generators, da ich vorsichtig sein muss, damit sich kein Korridor mit einem anderen schneidet.
Hier sind die Ergebnisse:
Höhlengeneration
Die vorherigen Ergebnisse waren fĂŒr die Erstellung von Dungeons, Krypten und anderen kĂŒnstlichen Strukturen geeignet, aber ich wollte den Höhlen und Minen ein natĂŒrlicheres Aussehen verleihen. Die klassische Art, Höhlen zu erzeugen, ist die Verwendung eines zellularen Automaten, wie in
diesem RogueBasin-
Artikel beschrieben . Das groĂe Problem bei zellularen Automaten ist, dass ihre Ergebnisse nicht vollstĂ€ndig kontrolliert werden.
Wie auch immer, ich entschied mich dafĂŒr, zellulare Automaten zu verwenden, um ein natĂŒrliches Erscheinungsbild zu erzeugen, aber ihnen EinschrĂ€nkungen aufzuerlegen, um ein kontrolliertes Ergebnis zu erzielen. Anstelle von nur zwei ZustĂ€nden: tot und lebendig verwende ich vier: absolut tot, tot, lebendig, definitiv lebendig. "Perfekt genaue" ZustĂ€nde können sich dabei nicht Ă€ndern, sie werden verwendet, um die Ergebnisse einzuschrĂ€nken.
Die in den vorherigen Schritten generierten RĂ€ume und Korridore sind mit âgenau lebendigenâ Zellen gefĂŒllt. Das heiĂt, wir haben noch unterstĂŒtzende RĂ€ume und wir garantieren, dass sie miteinander verbunden werden. Die nicht ausgewĂ€hlten Kanten werden mit âgenau totenâ Zellen gefĂŒllt, sodass keine neuen Pfade zwischen den RĂ€umen angezeigt werden. SchlieĂlich machen wir in RĂ€umen und Korridoren zufĂ€llig einige Zellen lebendig. Hier ist die Erstkonfiguration:
Dann starten wir den zellularen Automaten:
Hier sind einige weitere Beispielergebnisse:
SpĂ€ter werde ich eine FĂŒllung hinzufĂŒgen, um nicht erreichbare Teile zu entfernen.
Dies ist der erste Schritt auf einer langen Reise, um einen interessanten Dungeongenerator zu erstellen. Ich bin mit den Ergebnissen zufrieden. Ich bin besonders stolz auf die eingeschrĂ€nkte Methode der zellularen Automaten, kontrollierte und natĂŒrliche Höhlen zu schaffen. Ich mag auch die Tatsache, dass jede Generationsstufe von den anderen getrennt ist und individuell modifiziert werden kann.
Isolierte Zellen löschen
Dann habe ich eine FĂŒllung implementiert, um unzugĂ€ngliche Zellen zu entfernen:
Mehrere Korridore zwischen den RĂ€umen
Beim Experimentieren mit den Parametern des Generators stellte ich fest, dass Sie interessante Ergebnisse erzielen, wenn Sie zwischen den VerbindungsrĂ€umen ein wenig Rauschen hinzufĂŒgen.
Hier ist der Unterschied in den Ergebnissen vor dem Anlegen von LÀrm an VerbindungsrÀume und unmittelbar danach Àndert sich der Parameter nur um eine Einheit:
Wenn Sie die RĂ€ume etwas gröĂer machen, wird das Ergebnis noch interessanter:
Es ist groĂartig, dass wir einen Unfall haben und schöne Strukturen entstehen, aber gleichzeitig bleiben die Struktur der Grafik und die Bezeichnungen der RĂ€ume erhalten, was nĂŒtzlich sein wird:
Fliesenerzeugung fĂŒr Höhlen
Ich habe die meiste Zeit damit verbracht, Fliesen zu generieren. Es ist nicht sehr schwierig, aber fĂŒr die korrekte Implementierung sind ein paar Tricks erforderlich.
Hier sind Beispielergebnisse:
Das Tolle ist, dass Sie sehr einfach von einer Steinhöhle zu Sand oder Eis wechseln können:
Die nĂ€chsten Schritte bei der Erstellung des Dungeons sind das HinzufĂŒgen von Landschaften und Monstern.