Wie ich Karten der Kontinente für mein Spiel erstellt habe

Bild

Teil 1. SVG- und Koordinatensysteme


Bis vor kurzem waren die Kartengrößen in meinem Spiel " Dragons Abound" fest und etwas nicht deterministisch. Ich betrachtete sie als „regional“ - nicht als Karten der ganzen Welt, sondern ihrer bedeutenden Teile, wie zum Beispiel der Westküste der USA oder eines Teils Europas. Ich war ziemlich zufrieden mit dieser Skala, aber ich wollte ein bisschen mit dem Spiel experimentieren, um zu sehen, ob ich Karten der ganzen Welt (oder zumindest einer größeren) erstellen kann. Aber bevor ich anfange, lassen Sie uns ein wenig über Fantasy-Weltkarten sprechen.

Die Welt ist ein großer Raum. Die meisten Fantasy-Weltkarten ähneln nicht einmal der tatsächlichen Größe. Nehmen wir zum Beispiel Mittelerde, in der die Aktion Herr der Ringe stattfindet:


Obwohl es den Anschein hat, dass eine riesige Welt darauf gefangen ist, wurde Mittelerde tatsächlich auf der Grundlage Europas geschaffen.


Das heißt, die reale Karte der „Welt“ für die Tolkien-Welt wird ungefähr 50-mal größer sein als die Karte von Mittelerde (!). Tatsächlich spiegeln die meisten Fantasy-Weltkarten, die ich gesehen habe, ein Gebiet von der Größe eines Kontinents wider:


Dies scheint der größte Bereich zu sein, der im Fantasy-Kartenstil gut visualisiert ist.

Das heißt, die Aufgabe, echte „Weltkarten“ zu erstellen, ist wahrscheinlich zu ehrgeizig. Es ist besser, eine Karte des Kontinents (oder eines Teils des Kontinents) zu erstellen. (Es ist jedoch noch bequemer, die Karte als die Größe der "Welt" zu betrachten.) Welche Größe sollte die Karte haben? Wenn die aktuellen Dragons Abound-Karten eine „subkontinentale“ Größe haben, können wir davon ausgehen, dass Sie 8-10-mal größere Karten generieren müssen.

Bevor ich mit der Erstellung großer Karten fortfahre, muss ich die verschiedenen Koordinatensysteme, die in meinem Spiel verwendet werden, besser verstehen. Ich habe viele Koordinatensysteme aus dem Quellcode von Martin O'Leary ausgeliehen, und ihre Interaktionen können verwirrend sein, selbst wenn Sie zwei Jahre lang mit ihnen arbeiten. Normalerweise konnte ich ohne Experimente auskommen, aber es ist offensichtlich, dass ich dies tun muss, um große Karten zu erstellen.

Zunächst wird die „Welt“ der Regionalkarte derzeit auf einem Einheitsquadrat generiert. Jede Regionalkarte hat Koordinaten von (-0,5, -0,5) bis (0,5, 0,5), und der Ursprung (0,0) liegt in der Mitte der Region.


Eine der Kuriositäten hier ist, dass die Y-Achse im Vergleich zu dem, was wir in der Schulgeometrie studiert haben, invertiert ist. -0,5 befindet sich oben auf der Karte und 0,5 befindet sich unten. In der Computergrafik wird die Y-Achse häufig umgedreht. Ich habe gehört, dass dies durch die Art und Weise erklärt wird, wie die ersten Monitore (Fernseher) einen Scan von oben nach unten durchgeführt haben, dh die erste Scanlinie war oben, die nächste unmittelbar darunter, und so weiter, dh der Index Y der Scanlinien hat sich von Null oben zu einer positiven Zahl geändert unten. Wie dem auch sei, im SVG-Format (Scalable Vector Graphics) wird dasselbe Koordinatensystem verwendet, weshalb es auch viele Drachen gibt .

Dieses Koordinatensystem ist unabhängig davon, wie die Karte angezeigt wird. Dies ist nur ein dimensionsloses System zur Schaffung der Welt - die Stadt befindet sich bei (0,12875, -0,223), die Grenze verläuft von (0,337, 0,010) nach (0,333, 0,017) und so weiter. Und obwohl meine aktuellen regionalen Karten auf einen Bereich von 0,5 bis -0,5 beschränkt sind, ist dies nicht die Grenze des Koordinatensystems. Ich kann eine Welt jenseits dieser Grenzen erschaffen.

Das nächste Koordinatensystem nennt SVG Viewbox. Es legt die wahren Koordinaten fest, die zum Zeichnen der Grafiken verwendet werden. Zum Beispiel setzt Dragons Abound am Anfang das Ansichtsfeld auf die Koordinaten (-500, -500) und hat eine Breite von 1000 und eine Höhe von 1000:


(Das Bild enthält einen Tippfehler. Der obere Rand der Y-Achse sollte leider -500 sein.)

Möglicherweise stellen Sie fest, dass in diesem Fall die Transformation zwischen dem ersten und dem zweiten Koordinatensystem nur darin besteht, alle mit 1000 zu multiplizieren. Um etwas zu zeichnen, findet das Spiel die Koordinaten dieses Objekts, multipliziert sie mit 1000 und zeichnet SVG in diesen Koordinaten.

Das heißt, ich kann die Koordinaten des Ansichtsfelds verwenden, um eine Linie von (0, 0) bis (250, 250) zu zeichnen. Tatsächlich möchte ich jedoch keine Linie von (0, 0) bis (250, 250) auf dem Computerbildschirm ziehen. Dies würde bedeuten, dass ich die Koordinaten aller Kartenobjekte ändern und neu zeichnen muss, wenn ich die Karte an einer anderen Stelle auf dem Bildschirm anzeigen möchte. Das wäre ein großer Job.

Um die Koordinaten für die Anzeige von Grafiken auf dem Bildschirm zu steuern, verfügt SVG über ein drittes Koordinatensystem namens Ansichtsfenster. Das Ansichtsfenster ist der Teil der Seite, auf dem Grafiken gezeichnet werden sollen (auf der Webseite ist dies das <svg> -Element). Es hat eine Breite, Höhe und Lage. Die Position sind die Koordinaten der oberen linken Ecke des Ansichtsfensters. Das heißt, wenn ich die Karte im Ansichtsfenster mit Koordinaten (30, 100) anzeigen würde, die eine Höhe und Breite von 800 haben, würde das Koordinatensystem des Ansichtsfensters folgendermaßen aussehen:


In SVG sind das Ansichtsfeld und das Ansichtsfenster des Koordinatensystems miteinander verbunden, und SVG selbst befasst sich mit dem Übergang zwischen ihnen. Wir zeichnen einfach in das Viewbox-Koordinatensystem und alles, was gerendert wird, wird an der entsprechenden Position des Ansichtsfensters angezeigt. (Beim Erstellen eines Ansichtsfelds und eines Ansichtsfensters mit unterschiedlichen Seitenverhältnissen treten einige Probleme auf. Anschließend werden die Objekte je nach Wert des AttributserveAspectRatio entweder abgeschnitten oder gestreckt. Ich empfehle, dies überhaupt nicht zu tun.)

Zusammenfassend: Eine Stadt in Weltkoordinaten (0,10, 0,33) wird in Koordinaten (100, 330) gezeichnet und in (110, 764) auf dem Bildschirm angezeigt.

Jetzt können Sie verstehen, warum dies verwirrend sein kann!

Was passiert, wenn ich jedes dieser Koordinatensysteme ändere? Angenommen, ich werde im ersten Koordinatensystem auf jeder Achse eine Welt zwischen -0,25 und 0,25 erzeugen. Dann ist die resultierende Welt viermal kleiner als die übliche Welt und füllt nur den mittleren Teil des Ansichtsfensters:


(Sie können auch Artefakte an den Rändern bemerken, die normalerweise ausgeblendet sind.) Wenn ich die Größe des ersten Koordinatensystems (SK) verdopple, wird der größte Teil der Karte nicht angezeigt, da sie sich außerhalb der Ränder des Ansichtsfensters befindet.

Was passiert, wenn ich die Größe der Viewbox verdopple? Wenn ich auch das Verhältnis zwischen dem ersten SC und der Viewbox verdopple (von 1000 auf 2000), ändert sich nicht viel. Wenn das Verhältnis gleich 1000 bleibt, wird die Karte erneut halbiert.


Diesmal hat die Karte jedoch eine Anfangsfläche von 1x1. Wir können wieder Artefakte an den Rändern bemerken, die normalerweise verborgen sind (zum Beispiel konvexe Teile von Wäldern). Sie können auch sehen, dass das Ozeanmuster falsch ist - ich muss einige Annahmen über die Größe der Ansichtsbox fest verdrahtet haben. Außerdem scheint sich der Kompass nicht an der Ecke der Karte zu befinden, sondern an der Ecke der Ansichtsbox.

Und umgekehrt, wenn ich die Größe des Ansichtsfelds um die Hälfte reduziere, wird ein Kartenzoom-Effekt erzeugt:


Hier sehen wir nur das mittlere Viertel der Karte. Dies ist keine sehr bequeme Methode zum Zoomen, da nur die Hälfte der Karte einige Probleme aufweist - beispielsweise ging die Stadtmarkierung „South Owenson“ über den Bildschirm hinaus. Außerdem verdoppelt es die Größe der Schriftarten und anderer Dinge, die ich nicht benötige.

Ein nützlicherer Aspekt des Ansichtsfelds ist das Ändern des Ursprungs. Bisher wurde das Ansichtsfeld auf der Karte zentriert, dies ist jedoch nicht erforderlich. Zum Beispiel kann ich die Karte nach rechts verschieben, indem ich das Ansichtsfeld auf einen Punkt auf der linken Seite der Karte zentriere:


Wir können wieder die Auswirkungen auf die Grenzen und einige andere Probleme bemerken, aber im Wesentlichen hat sich die Karte nach rechts verschoben. Die Nützlichkeit davon mag nicht offensichtlich sein, aber stellen Sie sich vor, ich werde eine Karte erzeugen, deren Breite doppelt so breit ist wie die einer regulären Karte. Standardmäßig sieht es so aus:


Es sieht aus wie jede andere Karte, ist aber in Wirklichkeit nur der zentrale Teil einer größeren Karte. Das heißt, jetzt kann ich das Ansichtsfeld ändern, um andere Teile der Karte in das Übersichtsfenster zu übertragen:


Hier habe ich den Blickwinkel nach links verschoben, sodass wir einen Teil der Welt östlich der ursprünglichen Ansicht sehen. Einige Namen auf der Karte haben sich geändert, da Dragons Abound bestimmte Funktionen ausführt (z. B. Objekte benennt), je nachdem, ob sie sichtbar sind. Ich muss dies ändern, damit die Karte beim Verschieben der Ansichtsbox konstant bleibt. Später kann ich jedoch das Ansichtsfeld auf einer großen Karte verschieben und regionale Karten für jedes gewünschte Gebiet erstellen. Das heißt, ich kann große Karten von der Größe eines Kontinents erstellen und anzeigen, aber ich kann auch regionale Karten von Gebieten innerhalb einer großen Karte erstellen.

Zusammenfassend: Das Spiel verwendet drei Koordinatensysteme. Der erste ist ein abstrakter SC für Weltobjekte. Das zweite ist das Ansichtsfeld, es definiert den sichtbaren Bereich der Welt. Das dritte ist das Ansichtsfenster, das steuert, wo die Karte auf dem Bildschirm gezeichnet wird. Um eine größere Welt zu zeichnen, muss ich den ersten SC erweitern. Um mehr auf dem Bildschirm anzuzeigen, müssen Sie das Ansichtsfeld erweitern. Ich kann auch die Ansichtsbox verschieben, um verschiedene Teile der großen Welt anzuzeigen.

Teil 2. Karten dauerhaft machen


Im vorherigen Teil habe ich Koordinatensysteme untersucht und gelernt, wie das SVG des Ansichtsfensters so verschoben wird, dass nur einzelne Teile der großen Welt angezeigt werden. Dieser Ansatz hat jedoch einige Probleme, da ich früher angenommen habe, dass alles, was für uns unsichtbar ist, keine Rolle spielt. In diesem Teil werde ich diese Annahmen beseitigen, damit es möglich ist, verschiedene Teile unveränderlicher großer Karten zu generieren und anzuzeigen.

Das Problem mit der Platzierung von Namen, das ich im vorherigen Teil beschrieben habe, ist offensichtlich bei diesen beiden Arten einer Karte erkennbar:


Hier ist die gleiche Welt, nur der Blick ist nach links verschoben:


Möglicherweise stellen Sie fest, dass die Geografie identisch ist, aber viele Namen haben sich geändert. Da in zwei Typen unterschiedliche Objekte sichtbar sind und der Prozess des Erstellens von Namen durch Zufallszahlen gesteuert wird, werden unterschiedliche Namen erhalten.

Beim Betrachten des Codes stellte ich fest, dass fast alle Objekte abhängig von ihrer Sichtbarkeit Namen erhalten. Es gibt jedoch nur eine Ausnahme, die es schwierig macht, allen nachfolgenden Objekten Namen zu geben. In unserem Fall ist die Ausnahme, dass Dragons Abound nur sichtbare Küsten erzeugt. Die Gründe dafür sind sehr verwirrend. Tatsächlich gibt es eine „Küste“ entlang des gesamten Randes der Welt, aber die Schaffung dieser Linie zerstört einen Teil der Programmlogik, weil sie die ganze Welt umfasst. Um dies zu vermeiden, habe ich nur die sichtbare Küste generiert. Da die Karte jetzt weit über das Ansichtsfenster hinaus erweitert werden kann, sieht diese Lösung nicht mehr gut aus. Stattdessen muss ich aufhören, Küstenlinien zu generieren, wenn ich mich dem tatsächlichen Rand der Karte nähere. (Was ich immer noch außerhalb des Bildschirms lasse, um Probleme an den Rändern zu verbergen.)

Nachdem dieses Problem behoben wurde, bleiben die Namen auf den beiden Karten konstant:


und:


Ein weiterer Hinweis für die Zukunft: Wenn ich die Interaktivitätsfunktion verwende , um die Namen von Kartenobjekten zu ändern, wird diese Änderung nicht in ihrer aktuellen Form neu erstellt und ist wahrscheinlich nicht einmal reproduzierbar. Es lohnt sich, darüber nachzudenken.

Wenn Sie sich die vorherige Karte genau ansehen, können Sie sehen, dass das Meeresgebiet in der Nähe des unteren mittleren Teils der Karte mit einem hängenden Etikett „Meb Island“ versehen ist. Es geschah, weil Dragons Abound tatsächlich glaubt, dass die Region des Ozeans eine Insel ist. Ich werde nicht auf technische Details eingehen, aber es ist überraschend schwierig, Inseln von Seen zu unterscheiden, wenn sie über die Karte hinausgehen. Der Algorithmus ist verwirrend für die Änderung, die ich an der Erzeugung unsichtbarer Küsten vorgenommen habe, und um solche Probleme zu vermeiden, muss dies behoben werden.

Vervierfachen wir nun die Größe der Karte und zeigen nur ein Viertel davon im Kartenfenster an:


Im Allgemeinen sieht alles gut aus (es gibt ein interessantes Flusssystem auf der Karte, einen großen See, aber Sie können sehen, dass Städte sehr selten sind. Dies geschah, weil Dragons Abound 10 bis 20 Städte erzeugt. Dieses Intervall ist gut geeignet für eine normal große Welt, aber schlecht. Wenn die Größe viermal größer ist, muss das Intervall entsprechend der relativen Größe der Welt geändert werden. Wahrscheinlich muss es an mehreren Stellen durchgeführt werden.

Hier ist dieselbe Karte, nachdem das Problem behoben wurde:


Jetzt gibt es auf der Karte eine logischere Anzahl von Städten, aber dies zeigt uns ein anderes Problem. Sie können viele zusätzliche Namen an den Rändern der Karte sehen, zum Beispiel Nanmrummombrook, Marwynnley und Noyewood in der unteren linken Ecke. Dies geschieht, weil die Platzierungscodemethode versucht, sie dort zu platzieren, wo sie sichtbar sind. Bisher musste sich dieses Verfahren nie um Beschriftungen außerhalb des Bildschirms kümmern, da in Karten mit regionaler Größe normalerweise die ganze Welt sichtbar ist. Aber jetzt befinden sich möglicherweise Städte und andere Objekte außerhalb des Bildschirms. Daher muss ich der Beschriftungsplatzierungsprozedur Logik hinzufügen, die nicht versucht, Beschriftungen für unsichtbare Kartenobjekte zu erstellen.


Jetzt ist das Bild logischer. Auf der rechten Seite ist Cumden auf der Karte kaum sichtbar, aber das Etikett befindet sich immer noch dort, wo es sichtbar ist.

Es gibt einen Aspekt, der auf großen Karten nicht sofort erkennbar ist: Die Anzahl der Standorte auf der Welt hat sich nicht geändert. Obwohl die Karte (gewissermaßen) viermal größer geworden ist, ist ihre Gesamtfläche immer noch durch die gleiche Anzahl von Orten begrenzt. Die erste Phase der Kartenerstellung bestand darin, die Welt mit einem Voronoi-Diagramm mit einer konstanten Anzahl von Standorten abzudecken. Das heißt, wenn die Karte größer wird, werden auch Voronois Zellen größer.

Es wäre logisch, die Anzahl der Orte entsprechend der Größe der Karte zu skalieren, aber leider ist die Abhängigkeit der Ausführungsgeschwindigkeit von Dragons Abound von der Anzahl der Orte viel schlimmer als linear, dh das Erstellen einer Karte mit einer großen Anzahl von Orten kann viel Zeit in Anspruch nehmen. Hier ist ein Beispiel für eine Karte mit vierfacher Auflösung (Anzahl der Standorte):


Hinzugefügte Standorte ändern den Generierungsprozess, sodass sich das Gelände von den oben gezeigten Karten unterscheidet. Darauf sehen Sie jedoch die hinzugefügten Details an den Küsten.

Glücklicherweise habe ich bei der Profilerstellung der Leistung beim Generieren großer Karten festgestellt, dass der größte Teil der Prozessorzeit von offensichtlichen Problemen beansprucht wird. Nach dem Debuggen habe ich die störendsten beseitigt, wodurch ich noch mehr Karten erstellen konnte. Hier ist die ganze 4x Karte:


25% Zoom durchgeführt. Es sieht ungefähr nach der maximalen Kartengröße aus, die Chrome anzeigen kann. Das World Generation-Verfahren kann größere Karten verarbeiten, aber beim Versuch, sie anzuzeigen, stürzt der Browser ab. In diesem Sinne scheint Firefox funktionaler zu sein. Es können Karten angezeigt werden, die 9-mal größer als die Originalgröße sind. Hier ist ein Teil einer solchen Karte - ich habe sie in voller Größe belassen, sodass Sie sie in einem separaten Fenster öffnen können, um die Größe und die Details besser zu verstehen.


Firefox kann Karten dieser Größe generieren, aber ich kann nur Screenshots mit der maximalen Größe des Browserfensters machen. Ich habe eine Funktion zum Speichern der Karte als PNG-Datei, aber sie kann nur den angezeigten Teil der Karte speichern. Ich denke, Sie können die Karte scrollen, einzelne Bildschirme erfassen und miteinander verbinden, aber es wird zeitaufwändig sein.

Die beste Lösung besteht darin, das SVG selbst zu speichern, damit es in einem Programm wie Inkscape geöffnet werden kann.

Früher konnte ich SVG-Karten ausschneiden und in Inkscape einfügen, aber SVGs für Weltkarten sind so groß, dass der Browser beim Ausschneiden abstürzt! Glücklicherweise habe ich FileSaver.js gefunden und Sie können es verwenden, um das SVG direkt in einer Datei zu speichern und es dann in Inkscape zu öffnen, wodurch ein sehr großes Bild erstellt wird.

Zumindest theoretisch. Wenn ich versuche, diese Karten in Inkscape zu öffnen, treten einige Probleme auf.

Das erste Problem besteht darin, dass sich die Inkscape-Annahmen beim Öffnen von SVG von den Annahmen von Chrome und Firefox unterscheiden. Insbesondere wenn die Füllfarbe im Pfad nicht angegeben ist, gehen die Browser davon aus, dass keine Füllung vorhanden ist. Inkscape geht davon aus, dass der Umriss mit Schwarz gefüllt ist. Wenn ich das gespeicherte SVG in Inkscape öffne, ist es daher fast vollständig schwarz, da die oberste Ebene der Karte keine Füllfarbe enthält. Dies kann behoben werden, indem an den erforderlichen Stellen "fill: none" angegeben wird, sodass die Umrisse sowohl im Browser als auch in Inkscape gleichermaßen angezeigt werden.

Das zweite Problem ist, dass Inkscape Fehler bei der Verarbeitung von Masken aufweist. Inkscape scheint Masken mit nur einem Element zu erstellen und behandelt Masken mit mehreren Elementen schlecht. Dragons Abound erstellt viele Masken mit mehreren Elementen. Sie können dieses Problem umgehen, indem Sie alle Elemente jeder Spielmaske in einem (optionalen) Gruppenelement gruppieren.

Das dritte Problem betrifft Bilder und andere herunterladbare Ressourcen. In der ursprünglichen SVG werden Verweise auf sie in relativer Form angegeben, z. B. "images / background0.png". Meine Quellen sind so angeordnet, dass der separate Webserver, den ich verwende , diese Ressourcen an den angegebenen Stellen finden kann. Wenn ich dieselbe SVG-Datei in Inkscape öffne, werden diese relativen Pfade als URL „file:“ behandelt, und Inkscape sucht nach Ressourcen in Bezug auf den Ordner, in dem die SVG gespeichert wurde. Dieses Problem kann leicht umgangen werden, indem die SVG-Datei in einem Ordner gespeichert wird, in dem sich bereits Ressourcen an den richtigen Stellen befinden. Dies kann derselbe Stammordner sein, der vom Webserver verwendet wird, oder ein anderer Ort, an dem sich Kopien von Ressourcen auf denselben (relativen) Pfaden befinden.

Das vierte Problem sind Schriftarten. Dragons Abound verwendet sowohl Web-Schriftarten als auch lokal gespeicherte Schriftarten. beide im WOFF2-Format. Im Browser werden sie im Stil der CSS-Schriftfamilie auf den Text angewendet. Vor dem Generieren der Karte werden alle möglichen Schriftarten auf die Webseite hochgeladen, um sie zur Verwendung bereit zu halten. Wenn dieselbe Datei im Spiel geöffnet wird, sucht sie im System-Schriftartenverzeichnis nach Schriftarten, und es sieht so aus, als ob in keiner Weise ein anderes Schriftartenverzeichnis angegeben werden kann. Eine einfache Lösung (zumindest auf dem Computer, auf dem ich entwickle) besteht darin, die vom Spiel verwendeten Schriftarten im Systemschriftartenverzeichnis zu installieren. Es ist jedoch nicht so einfach, wie es scheint, da die Schriftnamen übereinstimmen müssen und es unter Windows keine einfachen Möglichkeiten gibt, den Schriftnamen zu ändern. Ein solches Schema funktioniert jedoch natürlich nicht auf Computern, auf denen nicht alle erforderlichen Schriftarten installiert sind. Eine tragbarere Lösung besteht darin, SVG-Schriftarten in Karten einzubetten . Dies wird auf meiner TODO-Liste stehen.

Am Ende kam ich zu dieser Kartengenerierungsoberfläche:


Umfangs-Eingabefelder geben die Gesamtgröße der Welt an, wobei 1x1 die Größe der Quellkarten ist. Die Größe von vbx (Ansichtsfeld) bestimmt die Größe eines auf der Karte angezeigten Weltfragments. Im Screenshot hat es auch einen Wert von 1x1, dh die Karte zeigt die ganze Welt an. Die Felder für das vbx-Zentrum geben den Standort des Kartenzentrums in der Welt an. 0, 0 ist das Zentrum der Welt. Schließlich geben SVG-Parameter die Anzahl der Bildschirmpixel pro 1 Viewbox-Größeneinheit an. Bei einem Wert von 775 wird eine 1x1-Karte mit einer Größe von 775x775 Pixel auf dem Bildschirm angezeigt. Dies ist praktisch, wenn ich eine sehr große Karte erstelle. Durch Einstellen des Parameters auf einen niedrigen Wert (z. B. 150 Pixel) kann ich eine große Karte auf dem gesamten Bildschirm anpassen.

Durch Ändern dieser sechs Parameter kann ich die Größe der Welt und den Bruchteil der Welt steuern, der auf der Karte angezeigt wird. Die Schaltfläche "Generieren" funktioniert genau so, wie Sie es sich vorstellen können. Die Schaltfläche Anzeigen zeigt einfach einen Teil der Welt an, dh ich kann eine Welt generieren und dann ihre einzelnen Teile anzeigen, wobei die Viewbox-Parameter geändert werden, ohne dass die Welt neu generiert werden muss. (Ein Programmierer implementiert dies besser als Skalieren und Scrollen.) Mit der Schaltfläche PNG speichern wird die sichtbare Karte als PNG-Datei gespeichert. Die Schaltfläche SVG speichern speichert die SVG-Datei der gesamten Karte. Mit der Schaltfläche Test It wird Testcode ausgeführt, der sich während der Entwicklung verschiedener Funktionen ändert.

Jetzt, da ich alle Teile der großen Welt erzeugen und reflektieren kann, kann ich die Form des Landes an größere Karten anpassen.

Teil 3. Sushi-Formen


Nachdem ich im vorherigen Teil verschiedene Änderungen vorgenommen habe, kann ich jetzt Welten generieren, die viel größer sind als die vorherigen (bis zu 8-mal mehr) und sie als große grafische Bilder speichern:


(Öffnen Sie das Bild in einem separaten Fenster, um die Karte in voller Auflösung 4800 x 2400 in Flickr anzuzeigen.)

Ich generiere diese Karten mit derselben prozeduralen Generation, mit der die regionalen Karten erstellt wurden. Die oben gezeigte Karte hat eine ziemlich regelmäßige kontinentale Form und einige interessante äußere Inseln. Es kommt jedoch hauptsächlich auf das Glück an. Hier ist eine andere Karte:


Diese Karte ist nur Chaos von den Inseln und Schweizer Sushi-Käse.

Hier ist ein weiteres Beispiel, etwas zwischen den beiden vorherigen Karten. Es ist nicht ganz realistisch, aber es kann für Fantasy-Umgebungen interessant sein:


Dies ist eine riesige kontinentale Landmasse, aber es gibt ziemlich viele seltsame Landformen, und im Allgemeinen sieht die Welt nicht ganz „real“ aus. (Obwohl für jemanden eine solche Welt für die Fantasie durchaus geeignet erscheint.) Welche Formen sollte die Karte der „Welt“ haben?

Die meisten der Fantasy-Weltkarten, die ich gesehen habe, repräsentieren beispielsweise einen großen Inselkontinent (mit kleinen Inseln), wie diese Karte von Andelen :


Oder die Halbinsel des Kontinents, wie auf dieser Karte von Angorun :


Von Zeit zu Zeit besteht eine Karte ausschließlich aus Land oder mehreren Inselkontinenten, es ist jedoch wahrscheinlicher, dass sie Ausnahmen von der Regel darstellen.

Lassen Sie uns zunächst die Generation der Inselkontinente herausfinden. Wie sich in meinem Spiel herausstellt, gab es bereits eine Funktion, die unter Berücksichtigung der Größe der Karte eine große zentrale Insel auf der Karte generiert. Daher sollte sie für die Generierung der Hauptform des Kontinents geeignet sein. Lärm und zusätzliche Inseln kümmern sich um den Rest.


Ich habe auf dieser Karte kein großes zentrales Meer erwartet, aber es ist eine angenehme Überraschung. Hier ist ein weiteres Beispiel:


Das Problem mit der Funktion der Zentralinsel ist, dass sie mit einem Kreis beginnt, der für die von mir gezeigten quadratischen Karten geeignet ist, für rechteckige jedoch nicht sehr gut. (Nachfolgend finden Sie Beispiele mit geringer Verzerrung, damit die Grundformen besser sichtbar sind.)


Dies kann leicht korrigiert werden, indem Sushi anstelle eines Kreises mit einer Ellipse (verzerrt) maskiert wird, die entsprechend der Größe der Karte erstellt wird:


Diese zentralen Inseln sind skaliert, um die Karte zu füllen, aber in vielen Fällen müssen wir für Kontinentalkarten eine „Grenze“ um den Kontinent herum lassen. Zwei Parameter steuern die Größe der Karte, die die Insel entlang der X- und Y-Achse füllt.


Hier ist das gleiche Grenzmanagementsystem mit logischeren Verzerrungen:


Es ist zu sehen, dass der östliche und der westliche Teil der Karte der Ozean bleiben. (Sie können die Karte in einem separaten Fenster öffnen, um sie genauer zu studieren.) Dies bedeutet, dass die Karte die gesamte Welt (und ihre rechten und linken Ränder können verbunden werden) oder einen Teil der Welt anzeigt, der mit einer anderen Karte verbunden werden kann, die auch einen Ozean vom entsprechenden Rand hat.

Ein aufmerksamer Leser, der die vorherige Karte studiert hat, hat möglicherweise bemerkt, dass die Muster des Ozeans und des Landes in der Mitte der Karte anhalten.Zuvor hatte ich Karten mit einer Größe von nur 1x1, daher wurden die Größen der Muster des Ozeans und des Landes an diese Karten angepasst. Bei größeren Karten muss ich Muster auf der Karte manuell kacheln, daher habe ich diese Funktion hinzugefügt. (In SVG gibt es eine Möglichkeit, Musterkacheln durchzuführen. In Chrome enthält es jedoch einen Fehler, sodass ich ihn nicht verwenden kann.) Dies ist eine gute Funktion, da ich jetzt kleinere Land- und Ozeanmuster verwenden kann, die automatisch gekachelt werden. Ich weiß nicht, warum ich es vorher nicht bemerkt habe!

Jetzt funktionieren die Inselkontinente einwandfrei, und wir werden mit der Implementierung der „Halbinsel“ -Kontinente fortfahren - Karten, auf denen der Kontinent von seinem Rand auf der Karte erscheint.


In diesem Fall kann der Kontinent nicht an drei Kanten zusammenbrechen. Das Hauptmerkmal solcher Karten ist jedoch, dass sie eine signifikante Landverbindung zwischen dem auf der Karte angezeigten Kontinent und dem Land außerhalb der Karte aufweisen.

Der einfachste Weg, eine solche Verbindung außerhalb der Karte herzustellen, besteht darin, während der Erzeugung einen niedrigen Meeresspiegel einzustellen. Wir werden also die auf der Karte angezeigte Landfläche vergrößern, was die Wahrscheinlichkeit großer Landmassen und das Auftreten von Land (anstelle des Meeres) entlang der Kartenränder erhöht.


Dies garantiert natürlich nicht, dass die Landmasse sehr interessant sein wird, und tatsächlich wird sie vereinheitlicht:


Die Ähnlichkeit eines einzelnen Kontinents kann mit derselben Generation des Inselkontinents erzeugt werden, während gleichzeitig die Insel an den Rand der Karte verschoben wird. Sie bekommen so etwas:


Es ist zu sehen, dass der Kontinent (hauptsächlich) die zentrale Insel ist, die nach oben und rechts verschoben ist. Da dies ein Kontinent ist und keine strenge Inselform beibehalten werden muss, können Sie der Form mehr Verzerrungen hinzufügen.


Natürlich gibt es viele andere Ansätze zur Erzeugung von Erleichterungen, aber diese beiden geben mir zumindest die Möglichkeit, die häufigsten Landformen auf kontinentaler Ebene zu erzeugen.

Ein aufmerksamer Leser konnte die seltsamen Formen von Wäldern in Form von Streifen auf vielen Karten der Kontinente bemerken. Das nächste Mal werde ich mich mit den Problemen von Windmodellen und Biomen befassen, die diese Kuriositäten verursachen.

Teil 4. Windmodell


Wie gesagt, die Größe der Kontinente auf Dragons Abound- Karten zeigte unrealistische Wetter- und Biomuster. Dieses Beispiel zeigt, dass der Wald entlang der vorherrschenden Windrichtung ausgerichtet ist:


Der Grund liegt nicht im fehlerhaften Code. Vielmehr sind die Wetter- und Biomodelle zu einfach, und im großen Maßstab wird dies deutlich. Um diese Probleme zu lösen, habe ich zunächst das Windmodell überarbeitet.

Ich möchte, dass mein Windmodell die Dynamik des Erdwinds besser widerspiegelt: Hadley-Zellen , Passatwinde und dergleichen. Eine solche Dynamik kann dazu beitragen, seltsame Wettermuster auf Kontinentalkarten zu beseitigen. Als sie jedoch hinzugefügt wurden, zeigte sich erneut eine schmerzhafte Unzufriedenheit mit dem langsamen und zu komplizierten Windmodell Dragons Abound . (Lesen Sie hier über die erste Implementierung des Windmodells ..) Nachdem ich einige Tage darüber nachgedacht hatte, entschied ich, dass die meisten Probleme darauf zurückzuführen sind, dass die Spielkarte als Voronoi- Diagramm dargestellt wird . (Oder besser gesagt, die Delaunay-Triangulation des Voronoi-Diagramms.) Es hat viele Vorteile bei der Erzeugung von Gelände - in Kombination mit Lärm kann es natürlich aussehende Landmassen erzeugen. Deshalb wird es so oft verwendet, um Erleichterung zu erzeugen. Da einzelne Dreiecke jedoch unterschiedliche Größen und Ausrichtungen haben, werden alle Berechnungen, einschließlich Windmodelle, die benachbarte Nachbarzellen verwenden, ziemlich kompliziert. Es wird viel einfacher sein, den Wind durch ein Gitter gleichmäßig verteilter identischer Bereiche zu modellieren. Außerdem muss das Windmodell höchstwahrscheinlich nicht so detailliert sein wie Land.

Aber ich möchte das Voronoi-Diagramm, das dem Dragons Abound zugrunde liegt, nicht ganz aufgeben . (Zumindest muss dafür fast das gesamte Programm neu geschrieben werden!) Stattdessen möchte ich mit dem Binden der Karte an ein einheitliches Raster experimentieren, das Windmodell darin ausführen und dann die umgekehrte Bindung durchführen. Wenn der Verlust beim Hin- und Herkopieren nicht zu groß ist, kann dies das Windmodell schneller und einfacher machen.

Welches Gitter soll ich verwenden? Idealerweise sollte das Gitter aus gleichen Flächen bestehen, die gleich weit von seinen Nachbarn entfernt sind. Und diese Beschreibung ist wie ein Sechseckgitter.


Tatsächlich ist ein Sechseckgitter der beste Weg , eine flache Oberfläche in gleiche Bereiche zu unterteilen.

Der nächste Schritt besteht darin, zu bestimmen, wie das Sechseckgitter in meinem Programm dargestellt werden soll. Ich suchte ein wenig im Netzwerk nach Hilfe und jeder Link brachte mich auf die Seite über die Gitter der Sechsecke von Amit Patel zurück ( Übersetzung in Habré). Wahrscheinlich ist es notwendig, damit zu beginnen; Es ist auch gut, zuerst die Red Blob Games-Website zu erkunden, wenn Sie Informationen zur Implementierung der Spielmechanik suchen. Amit erklärt es besser als ich. Wenn also etwas nicht klar ist, dann lies seine Seite.

Die erste Wahl ist die Art und Weise, wie das Sechseckgitter gespeichert wird. Der einfachste Weg ist, es als zweidimensionales Array zu speichern, dann brauche ich die Fähigkeit, Gitterzellen an das Array zu binden. Hier gibt es viele Optionen (lesen Sie Amits Seite ), aber ich werde das verwenden, was er ungerade-r nennt:


Die Zahlen in jeder Zelle sind die Indizes der Zelle im zweidimensionalen Array. (Das Bild wurde von Amits Seite gestohlen . Auf seiner Seite sind sie interaktiv, daher rate ich Ihnen, mit ihnen zu experimentieren.)

Nachdem ich eine Auswahl getroffen habe, muss ich nun lernen, wie man Indizes an ein Sechseckraster anfügt. Wenn ich zum Beispiel nach einer sechseckigen Zelle (3, 3) suche, welche Nachbarn werden sie dann sein? Wenn jede Zelle eine Breite von 5 Pixeln hat, wie lauten dann die Koordinaten der Mitte der Zelle (3, 3)? Usw.Der Umgang damit kann schwierig sein, deshalb bin ich froh, dass Amit es für mich getan hat.

Angenommen, wir können Amit alles stehlen, was wir brauchen, muss ich zuerst herausfinden, wie die Sechsecke auf der Karte angeordnet werden. Zu diesem Zeitpunkt brauche ich noch kein Array, ich kann so tun, als wäre es und sehen, wo die Sechsecke sein werden. Wenn ich die Position der Sechsecke kenne, dividiere ich einfach die Breite der Karte durch den horizontalen Abstand zwischen ihnen, um die Anzahl der Spalten zu erhalten, und mache dasselbe vertikal, um die Anzahl der Zeilen zu erhalten. Danach zeichne ich an jeder Stelle ein Sechseck:


Diese Sechsecke sind viel größer als die, die ich für das Windmodell verwenden werde, aber sie zeigen mir, dass alles richtig platziert ist.

Hier habe ich die Ränder der Karte geöffnet und nur das zentrale Sechseck und an den Rändern gezeichnet, um zu überprüfen, ob ich die gesamte Karte wirklich schließe:


Oben und unten befinden sich außerhalb der Karte, aber das Vorhandensein mehrerer Zellen im Ausland ist nicht wichtig, wenn ich keinen Teil der Karte verpasse.

Der nächste Schritt besteht darin, ein Array für das Sechseckgitter zu erstellen und alle Delaunay-Dreiecke an den entsprechenden Sechsecken auszurichten. Da Javascript keine negativen Indizes von Arrays unterstützt , muss ich die Zelle (0, 0) von der Mitte der Karte in die obere rechte Ecke verschieben. Nachdem ich dies getan habe, gehe ich um alle Delaunay-Dreiecke herum und füge sie den entsprechenden Zellen des Sechseckgitters hinzu. Ich kann dies überprüfen, indem ich die Sechsecke färbe, die Land enthalten:


Um festzustellen, ob eine Zelle Land ist, mittle ich die Höhe aller Orte, die in diese Zelle fallen. Möglicherweise stellen Sie fest, dass bei einigen Küstensechsecken der Durchschnitt selbst bei Land unter Null liegt. Sie können auch die maximale Höhe aller Positionen im Sechseck verwenden:


In diesem Fall erfolgt die Suche in die entgegengesetzte Richtung - das Sechseck wird als Land markiert, wenn sich Land darin befindet. Was besser ist, hängt davon ab, was Sie brauchen.

In jedem Fall kann ich die Genauigkeit erhöhen, indem ich die Größe der Sechsecke reduziere:


Jetzt ist die Küste viel besser geworden, aber es ist ein neues Problem aufgetreten - viele innere Sechsecke, die nicht als Land gelten. Dies geschieht, weil, wenn die Sechsecke klein genug werden, in einigen von ihnen überhaupt keine Delaunay-Dreiecke vorhanden sind. Daher haben sie keine "Höhe". (Dies zeigt auch die Ungleichmäßigkeit der Delaunay-Dreiecke.)

Sie können diese Lösung verwenden - nehmen Sie die Höhe der fehlenden Dreiecke als Durchschnitt ihrer Nachbarn oder als Maximum ihrer Nachbarn.


Wenn die Bindung zwischen Sechsecken und Positionen nicht eins zu eins ist, sind im Allgemeinen Korrekturen erforderlich, um die fehlenden Informationen auszufüllen.

Nachdem ich das Sechseckgitter auf die Karte gelegt habe, können wir mit der Implementierung des Windmodells beginnen. Die Hauptidee des Windmodells besteht darin, einige Winde (Passatwinde) zu simulieren und auf der Karte zu verteilen, bis sie einen Zustand der Unbeweglichkeit erreichen. Auf der Ebene der Sechsecke (oder der Ebene der Orte, wenn ich es auf Delaunay-Dreiecken mache) umfasst dies zwei Stufen: (1) Wir fassen alle Winde zusammen, die in das aktuelle Sechseck eintreten, und (2) wir bestimmen, wie der summierte Wind das Sechseck verlässt.

Die erste Stufe ist recht einfach. Jedes Sechseck hat sechs Nachbarn, und jedes dieser Sechsecke trägt dazu bei. Wenn wir jeden der Winde, die in das Sechseck eintreten, als einen Vektor betrachten, ist der Gesamtwind in der Zelle die Summe dieser Vektoren, d.h. zwei genau entgegengesetzte Winde gleicher Stärke heben sich gegenseitig auf.

Die zweite Stufe (Bestimmen, wie der Gesamtwind das Sechseck verlässt) erfordert Überlegungen. Der einfachste Fall ist der Wind, der direkt durch das Sechseck weht:


In diesem Fall erwarten wir, dass sich der Wind unverändert zur nächsten Zelle bewegt. (Hier ist der rote Vektor der ursprüngliche Wind und der blaue der Vektor des sich ausbreitenden Windes.)

Aber was ist, wenn der Wind nicht direkt in die benachbarte Zelle bläst?


In diesem Fall scheint es logisch, dass ein Teil des Windes in ein Sechseck direkt darüber weht, der andere Teil in eine Zelle, die sich gegen den Uhrzeigersinn von dieser befindet, und die Proportionen sollten von der Richtung abhängen, in die der Pfeil zeigt. In unserem Fall bewegt sich der Hauptteil des Windes zur oberen Zelle und weniger zur benachbarten Zelle.

Es ist auch notwendig, die Richtung des sich ausbreitenden Windes zu bestimmen. Eine Möglichkeit besteht darin, die Richtung des ursprünglichen Windes beizubehalten:


Es scheint, dass dies die realistischste Option ist, aber es gibt noch eine andere - die Richtung des Windes entsprechend der Kante des Sechsecks zu ändern, das es schneidet:


Dieser Ansatz ist weniger genau, hat aber den Vorteil, dass eingehende Winde immer in eine von sechs Richtungen weisen, was die Berechnungen vereinfachen kann.

Eine weitere Schwierigkeit ergibt sich bei der Betrachtung des Geländes. Was soll passieren, wenn sich ein Berg im Wind erhebt?


In diesem Fall geht ein Teil des Windes über den Berg (wodurch möglicherweise Niederschlag entsteht), aber ein Teil des Windes dreht sich zu den Seiten.


Daher hängt die Art und Weise, wie der Wind aus dem Sechseck kommt, von seiner Richtung sowie von der Topographie in benachbarten Zellen ab.

Lassen Sie uns nun darüber sprechen, wie Vektoren dargestellt werden. Es gibt zwei Hauptoptionen. Erstens kann ein Vektor beispielsweise wie folgt als X- und Y-Werte dargestellt werden:


Wenn wir einen Vektor zeichnen, der bei (0, 0) beginnt, dann sind (X, Y) die Koordinaten der Endpunkte. Eine solche Aufzeichnung macht es sehr einfach, Vektoren zu summieren. Wir addieren einfach alle Werte (X, Y) und erhalten einen neuen Vektor:


Eine andere Möglichkeit besteht darin, den Winkel und die Länge des Vektors zu verwenden:


In dieser Form ist es einfach, Operationen wie das Drehen von Vektoren oder das Ändern ihrer Länge auszuführen.
Für die Mehrzahl der im Windmodell erforderlichen Operationen ist die erste Option besser, in einigen Fällen ist die zweite besser, sodass es zweckmäßig wäre, bei Bedarf zwischen ihnen zu wechseln. Um das Rad nicht neu zu erfinden, habe ich nach einer Vektorbibliothek für Javascript gesucht und Victor.js ist vollständig aufgetaucht , also habe ich sie ausgenutzt.

Ich füge zunächst jedem Sechseck einen Windvektor hinzu und prüfe, ob ich ihn visualisieren kann:


Es sieht soweit gut aus.

Der nächste Schritt besteht darin, zu überprüfen, ob ich den Windvektor richtig teilen und an die nächste Zelle verteilen kann. Zunächst müssen Sie die Winkel berechnen, die zu anderen Zellen führen. Ich fand die Antwort wieder auf Amits Seite :


Das heißt, ein Vektor bei 0 Grad zeigt auf ein Sechseck rechts, bei 60 Grad - auf ein Sechseck unten rechts und so weiter. Ein Vektor, der zwischen diesen beiden Richtungen zeigt, wird proportional zwischen zwei Zellen aufgeteilt - das heißt, ein Vektor in einem Winkel von 30 Grad wird gleichmäßig zwischen der Zelle rechts und der Zelle von unten nach rechts aufgeteilt. Jeder Vektor liegt irgendwo zwischen den Ecken der Flächen zweier benachbarter Zellen. Sehen Sie sich also den Winkel des Windvektors an, stellen Sie fest, dass er zwischen die zentralen Ecken zweier Sechsecke fällt, und teilen Sie ihn dann proportional zwischen diesen beiden Sechsecken auf.

Wenn der Windvektor beispielsweise einen Winkel von 22 Grad hat:


dann breiten sich 38/60 des Wertes zur Zelle rechts und 22/60 des Vektorwerts zur Zelle unten rechts aus. Wenn die Vektoren als Paar von X- und Y-Werten dargestellt werden, können Sie sie verteilen, indem Sie jeden Wert des ursprünglichen Vektors mit einem Bruch multiplizieren (z. B. mit 22/60) und ihn dann dem Windvektor im neuen Sechseck hinzufügen.

Um dies zu testen, kann ich die Winde in verschiedene Richtungen anordnen und sie oben und seitlich auf der Karte platzieren und prüfen, ob sie sich korrekt auf der Karte ausbreiten können. Wenn Winde kollidieren, sollten sie kombiniert werden und die durchschnittliche Richtung mit erhöhter Geschwindigkeit wählen:


Hier sehen wir, dass sich Winde entlang der Diagonale treffen und zusammen in Richtung der unteren Ecke wehen.

Der nächste Schritt besteht darin, den Einfluss von Land auf den Wind zu berücksichtigen. Natürlich sind echte Windmodelle sehr komplex, aber ich interessiere mich hauptsächlich dafür, wie sich die Landgeographie auf Oberflächenwinde auswirkt. Auf der einfachsten Ebene ist dies der Einfluss von Landhöhen und Tiefland auf die Richtung und Geschwindigkeit des Windes. Ich habe mit vielen verschiedenen Ansätzen experimentiert, mich aber auf zwei einfache Regeln festgelegt :

  1. Der Wind wendet sich von Hindernissen ab.
  2. Der Wind verlangsamt sich, wenn er steigt, beschleunigt und fällt ab.

Ein Hindernis tritt auf, wenn der Wind in eine Zelle mit einer höheren Höhe bläst, beispielsweise in eine Zelle mit einem Berg. Wenn dies passiert, schaue ich auf die beiden Zellen, in die der Wind weht, und ändere den Winkel des Windes so, dass er mehr auf das untere der beiden Sechsecke zeigt. Die Größe der Winkeländerungen hängt vom Höhenunterschied zweier Zellen ab. Wenn der Wind also in zwei benachbarte Zellen mit Bergen bläst, ändert sich seine Richtung kaum. Wenn er jedoch in eine Zelle mit einem Berg und eine Zelle mit einer Ebene bläst, dreht er sich mehr in Richtung der leeren Zelle:


Die Stärke des Windes kann eingestellt werden. Auf der Karte oben ist er zu stark, was zur Entstehung vieler unrealistischer Biome führen wird. Hier ist eine logischere Bedeutung:


Ein großer Teil der durch die Reliefs verursachten Windbewegung bleibt bestehen, aber die großen Lücken und Täler des starken Windes sind kleiner geworden.

Ein weiteres Merkmal, das den Realismus verbessert, ist die Streuung des Windes. Zum Beispiel zeigt die Karte oben, dass der Wind direkt über der Stadt Breeches nach Westen weht. Obwohl es über große Entfernungen weht, löst es sich nie so auf, wie wir es erwarten würden. Wenn ein wehender Wind auf eine andere Luft trifft, zieht er normalerweise den Wind mit. Um dies zu simulieren, kann ich einen kleinen Teil des Windes, der in jedem Sechseck weht, auf alle benachbarten Zellen verteilen. So sieht die Karte oben mit einer kleinen Streuung aus:


Wie Sie sehen können, hat der Wind über den Reithosen begonnen, sich ein wenig nach unten zu zerstreuen.

Diese Operation bestimmt den Großteil der Windrichtungen. Der zweite Teil ist die Verzögerung des Windes beim Aufsteigen und die Beschleunigung beim Absenken. Ich kann dies erkennen, indem ich die relative Höhe der Zelle, aus der der Wind kommt, und die Höhe der Zelle, in die der Wind weht, betrachte und gegebenenfalls beschleunige / verlangsame.

So sieht alles aus:


Jetzt sehen wir, dass ein Teil des Windes, der durch die hohen Berge im zentralen Teil der Insel weht, abgeschnitten wurde. Und umgekehrt - im westlichen Teil der Insel traten mehrere neue Winde auf, bei denen sich die Luft von relativ hohem Land zum Meer bewegt. (Dies ist eine Küstenbrise ! Obwohl nicht wirklich: Der Mechanismus ist dort anders.)

Jetzt kann ich einen neuen Wind in den vorhandenen Niederschlagsalgorithmus einsetzen. Hier ist ein Vergleich (alte Winde links, neue Winde rechts):


(Klicken Sie auf das Bild, um eine größere Version anzuzeigen.) Offensichtlich gibt es Unterschiede zwischen den Windmodellen. Auf beiden Karten weht der Wind von Osten. Berge in der Nähe der Kartenmitte drehen den Wind nach Süden, verursachen starke Regenfälle und bilden südlich der Berge einen Sumpf und Wälder. Im unteren Teil weht der Wind störungsfrei und entlang der östlichen Inselhälfte bilden sich Wälder. Im ursprünglichen Windmodell wehte genug Wind über die zentralen Berge und Sümpfe, um im westlichen Teil der Insel einen Wald zu schaffen. Beim neuen Modell wird der größte Teil des Windes abgeschnitten und auf der anderen Seite der Berge bilden sich grasbewachsene Biome.

Das alte Modell hat die Variabilität zufälliger Parameter (innerhalb eines bestimmten Intervalls), und es ist wahrscheinlich, dass eine Kombination dieser Parameter ein Bild ergibt, das eher einer neuen Karte ähnelt. Tatsächlich müssen wir jedoch nicht das genaue Verhalten des alten Modells reproduzieren, sondern nur ein Modell, das überzeugend aussehende Ergebnisse liefert.

Ziel all dessen ist es, die Erzeugung von Wind zu beschleunigen und zu vereinfachen, damit den Kontinentalkarten neues Windverhalten hinzugefügt werden kann. Habe ich es getan Ich habe das ursprüngliche Windmodell und das neue sechseckige Modell profiliert. Es stellte sich heraus, dass das neue Modell 15-20 mal schneller ist als das Original (!). Dies ist eine sehr signifikante Beschleunigung, die wenig Einfluss auf die Karten hat. Die Experimente machen deutlich, dass das Modell nicht besonders empfindlich auf die Größe der Sechsecke reagiert. Wenn nötig, kann ich den Algorithmus noch weiter beschleunigen, indem ich die Größe der Zellen erhöhe.

Das nächste Mal werden wir daran arbeiten, ein neues Windmodell zu verwenden, um Windmuster im kontinentalen Maßstab zu implementieren und sie dann mit dem Niederschlagsmodell und den Biomen zu verbinden.

Source: https://habr.com/ru/post/de429620/


All Articles