Wie kann ich Worms-artiges Terrain erzeugen?


48

Ich arbeite an einem Spiel im Worms-Stil und möchte prozedural etwas Terrain generieren. Ich habe zuvor viel Terrain mit Perlin-Rauschen erzeugt, und das ist, was ich für dieses Spiel verwendet habe. Das einzige Problem dabei ist, dass es zu einfach und langweilig ist und mir ein paar Hügel gibt, aber nicht die Komplexität, die ich will. Ich hätte gerne Höhlen und hängende Berge und schwimmende Inseln und so. So etwas, aber noch verrückter wäre in Ordnung:

Bildbeschreibung hier eingeben

Ich dachte zuerst daran, das Terrain mit klassischem Perlin-Rauschen zu erzeugen, dann nur Teile zu entfernen, um Höhlen zu erzeugen, und was nicht, aber ich habe Probleme, das Entfernen dieser Teile zu steuern. Gibt es Alternativen zur Erzeugung eines solchen Geländes?


Stellt das Rot Höhlen dar oder ist das nur ein Teil des Geländes?
Richard Marskell - Drackir

Es ist Teil des Terrains. Ich habe gerade dieses Bild googelt und es war das, was ich am ehesten erreichen möchte. Der "Höhlenteil" könnte das kleine Loch auf der rechten Seite sein, wenn er weiter im Gelände links davon verläuft.
Xeon06,

@Drackir, bearbeitet das Bild.
Xeon06,

Related: gamedev.stackexchange.com/questions/6721/… (aber kein Duplikat, da es sich anscheinend auf die Implementierung im Vergleich zu den Generierungsalgorithmen konzentriert).
Josh

@ JoshPetrie in der Tat. Ich bin gut mit der Zerstörung. Es ist die Generation, mit der ich Probleme habe.
Xeon06

Antworten:


51

Ich würde vorschlagen, dass Sie mit 2D Perlin-Rauschen beginnen. Etwas wie das:

Perlin-Rauschen

Wenden Sie dann einen Schwellenwert auf das Bild an, sodass Sie mehrere isolierte Inseln erhalten, wie hier gezeigt:

Perlin-Rauschen mit Schwelle

Ich habe eine Schwelle von 0,04 gewählt, alles, was über der Schwelle liegt, wird blau gefärbt. Der Rest bleibt schwarz. Danach ist es Zeit zu bestimmen, welche "Inseln" behalten und welche weggeworfen werden sollen.

Ein möglicher Ansatz wäre, das Bild in verschiedenen Höhen von links nach rechts zu durchlaufen und sich überschneidende "Inseln" mit einer bestimmten Wahrscheinlichkeit auszuwählen. Im Beispielbild hat die unterste Linie eine Wahrscheinlichkeit von 100%, sodass jede Insel, die sie überquert, ausgewählt wird (weiß gefüllt). Die zweite Zeile hat eine Wahrscheinlichkeit von 50% und die oberste Zeile eine Wahrscheinlichkeit von 10%.

Sobald Sie Ihre Inseln so markiert haben, können Sie die Lücken zwischen ihnen schließen, indem Sie eine morphologische Operation anwenden ( erweitern ).

erweiterte Inseln

Und es gibt eine mögliche Landschaft.

Die "Granularität" des Rauschens wird bestimmen, wie klein die Details in Ihrer Welt sein werden. Daher ist es wahrscheinlich am besten, mit diesen Werten zu experimentieren.

Auch wo und mit welchen Wahrscheinlichkeiten Ihre "Auswahllinien" positioniert sind, wird das Ergebnis sehr unterschiedlich ausfallen. Wenn Sie eine Linie in der Nähe des oberen Bildrandes haben, mit der Sie mit hoher Wahrscheinlichkeit eine Insel "auswählen" können, können Sie eine Art Höhlenlandschaft usw. bauen.


Vielen Dank für die tolle ausführliche und bebilderte Antwort! Genau das werde ich tun.
Xeon06,

Hätten Sie Tipps zur Erzeugung eines solchen Perlin-Rauschens mit diesem Detaillierungsgrad und dergleichen? Ich habe den ganzen Abend versucht und komme nicht weiter.
Xeon06,

@ Xeon06 Ich habe gerade die Perlin-Rauschfunktion von Flash verwendet . Die Parameter waren 24für baseXund baseY, 1 Oktave und ich entschied mich für die Ausgabe von Graustufenrauschen und deaktiviertem "Fraktal". In welcher Sprache setzen Sie das um?
Bummzack

Ich implementiere es JavaScript. Ich habe das Web nach einer guten Implementierung durchsucht, die für eine Woche ähnliche Ergebnisse liefert, aber nichts findet.
Xeon06

Ich habe eine andere Frage an den Perlin Noise Teil betreffend gemacht gamedev.stackexchange.com/questions/20880/fast-noise-generation
Xeon06

6

Ich würde mit einem Perlin-Geräusch beginnen, das sorgfältig gefiltert wurde. Sie würden mit so etwas wie dem Bild enden, das der Frage beigefügt ist, mit schwimmenden Inseln. Juste entfernen Sie die schwimmenden Inseln danach mit einem Zählalgorithmus wie hier diskutiert


Oh, ich glaube, ich verstehe es jetzt. Ich muss 2D-Perlin-Rauschen verwenden, nicht 1D. Könnten Sie diese Filterung näher erläutern?
Xeon06

2
Ich kann momentan keine Bilder posten, aber ich spreche nur von einem einfachen Schwellenwertfilter à la if (0.3> pixelValue> 0.5) KeepIt () ;. Bei dem "sorgfältigen" Bit geht es darum, 0,3 und 0,5 richtig zu machen. Sie können auch einen linearen (oder nicht linearen) Gradienten haben, der oben mit hohem Alpha beginnt und unten allmählich auf 0 steigt, sodass Sie Platz für einen Himmel haben und der Boden größtenteils gefüllt ist. Ich hoffe, das hilft.
Ravachol

@Ravachol Wenn Sie einen Link zu einem Bild veröffentlichen, kann ihn jemand mit mehr Vertretern zu Ihrem Beitrag hinzufügen.
Richard Marskell - Drackir

"if (0.3> pixelValue> 0.5)", ich denke, das ist nur ein Tippfehler, aber es kann verwirrend sein, widersprüchliche Dinge in Ihrem Beitrag zu haben ... Können Sie das bitte bearbeiten?
jcora

Ich kann einen Kommentar scheinbar nicht bearbeiten. Lesen Sie offensichtlich "if (0.3 <pixelValue <0.5)".
Ravachol

4

Ich habe diese ausgehend von Bummzack ausgezeichnete Antwort tatsächlich umgesetzt.

Hier sind die Schritte, mit denen ich endete:

  1. Erzeugen Sie ein Bild mit Perlin-Rauschen
  2. Überflutung, wo Sie etwas Gelände wollen
  3. Dilatation + Erosion zum Entfernen der zu kleinen Vertiefungen
  4. Entfernen Sie die verbleibenden Hintergrundbereiche im Gelände
  5. Kantenglättung

Und das ist ein Beispiel für das Ergebnis: Beispiel für generiertes Gelände

Ich schrieb einen ausführlichen Artikel über den gesamten Prozess hier und den Code (JavaScript) ist Open Source, check it out , wenn Sie etwas bereit zu verwenden wollen;)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.