Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Procedural Content Generation
Gamedevelopment

Erstellen Sie ein prozedural generiertes Dungeon-Höhlensystem

by
Difficulty:IntermediateLength:LongLanguages:

German (Deutsch) translation by Katharina Nevolina (you can also view the original English article)

Für viele ist die prozessuale Erzeugung ein magisches Konzept, das nicht zu erreichen ist.  Nur erfahrene Spieleentwickler wissen, wie man ein Spiel erstellt, das seine eigene Ebene erstellen kann ... oder?  Es mag magisch erscheinen, aber PCG (prozeduraler Content-Generierung) kann von Spielentwicklern für Anfänger erlernt werden.  In diesem Tutorial zeige ich Ihnen, wie Sie ein Dungeon-Höhlensystem prozedural erzeugen.


Was werden wir abdecken 

Hier ist eine SWF-Demo, die zeigt, welche Ebenenlayouts diese Technik generieren kann:


Klicken Sie auf die SWF-Datei, um eine neue Ebene zu erstellen.

Das Erlernen der Grundlagen bedeutet in der Regel viel Google-Suche und Experimentieren.  Das Problem ist, dass es sehr wenige einfache Anleitungen gibt, um zu beginnen.  Hier finden Sie einige ausgezeichnete Informationsquellen zu diesem Thema, die ich studiert habe:

Bevor wir ins Detail gehen, sollten Sie überlegen, wie wir das Problem lösen.  Hier sind einige einfach zu verdauliche Brocken, mit denen wir diese Sache einfach halten:

  1. Platzieren Sie Ihre erstellten Inhalte zufällig in der Spielwelt.
  2. Stellen Sie sicher, dass der Inhalt an einer sinnvollen Stelle platziert ist.
  3. Vergewissern Sie sich, dass der Player mit Ihren Inhalten erreichbar ist.
  4. Wiederholen Sie diese Schritte, bis Ihre Ebene gut zusammenkommt.

Nachdem wir die folgenden Beispiele durchgearbeitet haben, sollten Sie über die erforderlichen Fähigkeiten verfügen, um mit PCG in Ihren eigenen Spielen zu experimentieren.  Aufregend, wie? 


Wo platzieren wir unsere Spielinhalte?

Das erste, was wir tun werden, ist die zufällige Platzierung der Räume einer prozedural erzeugten Dungeon-Ebene.

Um zu folgen, ist es eine gute Idee, ein grundlegendes Verständnis für die Funktionsweise von Kachelkarten zu haben.  Wenn Sie einen schnellen Überblick oder eine Auffrischung benötigen, sehen Sie sich dieses Kachel-Map-Tutorial an.  (Es ist auf Flash ausgerichtet, aber selbst wenn Sie mit Flash nicht vertraut sind, ist es dennoch gut, um den Kern von Kachelkarten zu erhalten.)

Erstellen eines Raums, der in Ihrer Dungeon-Ebene platziert werden soll

Bevor wir loslegen, müssen wir unsere Fliesenkarte mit Wandfliesen füllen.  Alles, was Sie tun müssen, ist, jeden Punkt auf Ihrer Karte (idealerweise ein 2D-Array) zu durchlaufen und die Kachel zu platzieren.

Wir müssen auch die Pixelkoordinaten jedes Rechtecks in unsere Gitterkoordinaten konvertieren.  Wenn Sie von Pixel zu Rasterposition wechseln möchten, teilen Sie die Pixelkoordinate durch die Kachelbreite.  Um vom Raster zu den Pixeln zu wechseln, multiplizieren Sie die Koordinate mit der Kachelbreite.

Wenn wir beispielsweise die obere linke Ecke unseres Zimmers in (5, 8) in unserem Raster platzieren möchten und wir eine Kachelbreite von 8 Pixeln haben, müssen wir diese Ecke in (5 * 8, 8 * 8) oder (40, 64) in Pixelkoordinaten.

Lassen Sie uns eine Room-Klasse erstellen. Im Haxe-Code könnte es so aussehen:

Wir haben Werte für die Breite, Höhe, Mittelpunktposition und vier Ecken jedes Raums und eine Funktion, die uns sagt, ob dieser Raum einen anderen schneidet.  Beachten Sie außerdem, dass sich alles außer dem x- und y-Wert in unserem Gitternetzkoordinatensystem befindet.  Das liegt daran, dass es das Leben viel einfacher macht, bei jedem Zugriff auf die Raumwerte kleine Zahlen zu verwenden.

Okay, wir haben den Rahmen für ein Zimmer.  Okay, wir haben den Rahmen für ein Zimmer. Wie generieren und platzieren wir nun einen Raum?  Dank der eingebauten Zufallszahlengeneratoren ist dieser Teil nicht allzu schwierig.

Alles, was wir tun müssen, ist, zufällige x- und y-Werte für unseren Raum innerhalb der Grenzen der Karte anzugeben und zufällige Breiten- und Höhenwerte innerhalb eines vorbestimmten Bereichs anzugeben.prozessuale Inhalte-Platzierung

procedural-content-room-placement

Ist unsere zufällige Platzierung sinnvoll?

Da wir für unsere Räume zufällige Positionen und Dimensionen verwenden, werden wir uns beim Füllen unseres Dungeons zwangsläufig mit zuvor erstellten Räumen überschneiden.  Nun, wir haben bereits eine einfache intersects()-Methode codiert, um uns zu helfen, das Problem zu lösen.

Jedes Mal, wenn wir versuchen, einen neuen Raum zu platzieren, rufen wir einfach auf jedem Zimmerpaar in der gesamten Liste intersects() auf.  Diese Funktion gibt einen booleschen Wert zurück: true, wenn sich die Räume überschneiden, andernfalls false.  Wir können diesen Wert verwenden, um zu entscheiden, was mit dem Raum geschehen soll, den wir gerade versucht haben.

procedural-content-intersection-diagram
Überprüfen Sie die Funktion intersects().  Sie können sehen, wie sich die x- und y-Werte überschneiden und true zurückgeben.

Der Schlüssel hier ist der failed Boolean; Es ist auf den Rückgabewert von intersects() und so ist es true gesetzt. Wenn also (und nur wenn) sich Ihre Räume überlappen, gilt dies als wahr.  Sobald wir aus der Schleife ausbrechen, überprüfen wir diese failed Variable. Wenn sie falsch ist, können wir den neuen Raum herausarbeiten.  Ansonsten verwerfen wir einfach den Raum und versuchen es erneut, bis wir die maximale Anzahl von Zimmern erreicht haben.


Wie sollten wir mit unerreichbaren Inhalten umgehen?

Die große Mehrheit der Spiele, die prozedural generierten Inhalt verwenden, bemüht sich, den gesamten Inhalt für den Spieler erreichbar zu machen, aber es gibt einige Leute, die glauben, dass das nicht unbedingt die beste Designentscheidung ist.  Was wäre, wenn Sie einige Räume in Ihrem Dungeon hätten, die der Spieler nur selten erreichen konnte, aber immer sehen konnte?  Das könnte Ihrem Dungeon eine interessante Dynamik verleihen.

Unabhängig davon, auf welcher Seite des Arguments Sie sich befinden, ist es wahrscheinlich immer noch eine gute Idee, sicherzustellen, dass der Spieler immer im Spiel vorankommt.  Es wäre ziemlich frustrierend, wenn Sie zu einem Level im Dungeon des Spiels gelangen würden und der Ausgang vollständig blockiert wäre.

Wenn man bedenkt, dass die meisten Spiele auf zu 100% erreichbaren Inhalten zielen, bleiben wir dabei.

Behandeln wir diese Erreichbarkeit

Inzwischen sollten Sie eine Kachelübersicht haben und es sollte ein Code vorhanden sein, um eine variable Anzahl von Räumen unterschiedlicher Größe zu erstellen.  Sehen Sie sich das an; Sie haben bereits einige clevere, prozedural generierte Dungeonräume!

Nun ist es das Ziel, jeden Raum miteinander zu verbinden, sodass wir durch unseren Dungeon gehen können und schließlich einen Ausgang erreichen, der zum nächsten Niveau führt.  Wir können das erreichen, indem wir Korridore zwischen den Räumen ausarbeiten.

Wir müssen dem Code eine point-Variable hinzufügen, um die Mitte jedes erstellten Raums zu verfolgen.  Wann immer wir einen Raum erstellen und platzieren, bestimmen wir seinen Mittelpunkt und verbinden ihn mit dem vorherigen Raum.

Zuerst werden wir die Korridore implementieren:

Diese Funktionen verhalten sich fast gleich, aber eine wird horizontal und die andere vertikal ausgerichtet. 

procedural-content-corridor-diagram-1

Um den ersten Raum mit dem zweiten Raum zu verbinden, sind ein vCorridor und ein hCorridor erforderlich.

Dafür brauchen wir drei Werte.  Für horizontale Korridore benötigen wir den Startwert x, den Endwert x und den aktuellen Wert y.  Für vertikale Korridore benötigen wir die Anfangs- und Endwerte von y zusammen mit dem aktuellen Wert von x.

Da wir uns von links nach rechts bewegen, benötigen wir die zwei entsprechenden x-Werte, aber nur einen y-Wert, da wir uns nicht nach oben oder unten bewegen.  Wenn wir uns vertikal bewegen, benötigen wir die y-Werte.  In der for-Schleife am Anfang jeder Funktion werden vom Anfangswert (x oder y) bis zum Endwert iteriert, bis der gesamte Korridor ausgeschnitten ist.

Jetzt, da wir den Korridorcode eingerichtet haben, können wir unsere Funktion placeRooms() ändern und unsere neuen Korridorfunktionen aufrufen:

procedural-content-corridor-diagram-2

In der obigen Abbildung können Sie die Erstellung des Korridors vom ersten bis zum vierten Raum verfolgen: Rot, Grün, dann Blau.  Abhängig von der Platzierung der Räume können Sie interessante Ergebnisse erzielen. Beispielsweise bilden zwei nebeneinander liegende Korridore einen doppelt breiten Korridor.

Wir haben einige Variablen hinzugefügt, um die Mitte jedes Raums zu verfolgen, und wir haben die Räume mit Korridoren zwischen ihren Zentren verbunden.  Jetzt gibt es mehrere nicht überlappende Räume und Korridore, die die gesamte Dungeonebene miteinander verbinden.  Nicht schlecht.

procedural-content-room-connection

Wir sind fertig mit unserem Dungeon, richtig?

Sie haben einen langen Weg hinter sich, um Ihre erste prozedural erzeugte Dungeon-Ebene aufzubauen, und ich hoffe, Sie haben erkannt, dass PCG keine magische Bestie ist, die Sie niemals erlegen werden.

Wir haben uns überlegt, wie Sie mit einfachen Zufallszahlengeneratoren Inhalte zufällig um Ihre Dungeon-Ebene platzieren können, und ein paar vorgegebene Bereiche, damit Ihr Inhalt die richtige Größe hat und ungefähr am richtigen Ort liegt.  Als Nächstes haben wir einen sehr einfachen Weg gefunden, um festzustellen, ob Ihre zufällige Platzierung sinnvoll ist, indem Sie nach überlappenden Räumen suchen.  Zum Schluss haben wir noch ein bisschen über die Vorteile gesprochen, die es Ihnen ermöglichen, Ihren Inhalt erreichbar zu halten, und wir haben einen Weg gefunden, mit dem Ihr Spieler jeden Raum in Ihrem Dungeon erreichen kann.

Die ersten drei Schritte unseres vierstufigen Prozesses sind abgeschlossen, was bedeutet, dass Sie die Bausteine eines großen Dungeons für Ihr nächstes Spiel haben.  Der letzte Schritt liegt bei Ihnen: Sie müssen das, was Sie gelernt haben, durchlaufen, um mehr prozedural generierten Inhalt für endlose Wiederspielbarkeit zu erstellen.

Es gibt immer mehr zu lernen

Die Methode zum Ausarbeiten einfacher Dungeonebenen in diesem Lernprogramm zerkratzt nur die Oberfläche von PCG, und es gibt einige andere einfache Algorithmen, die Sie leicht aufgreifen können.

Meine Herausforderung für Sie ist es, mit den Anfängen Ihres Spiels zu experimentieren, die Sie hier erstellt haben, und nach weiteren Methoden zu suchen, um Ihre Dungeons zu verbessern.

Eine hervorragende Methode zum Erstellen von Höhlenebenen ist die Verwendung von Zellularautomaten, die unendlich viele Möglichkeiten zur Anpassung von Dungeonebenen bieten.  Eine andere großartige Methode ist das Binary Space Partitioning (BSP), das einige böse aussehende gitterähnliche Dungeonebenen erzeugt.

Ich hoffe, dies hat Ihnen einen guten Start in die Erstellung von prozeduralen Inhalten ermöglicht.  Vergewissern Sie sich, dass Sie im Folgenden alle Ihre Fragen kommentieren und ich würde gerne einige Beispiele sehen, was Sie mit PCG erstellen.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.