header YouTube
Clonk Livestream auf Twitch.tv!

Clonkspot

Statische vs Dynamische Karte

Ich hab irgendwann mal versucht ein System zu basteln, welches eine Karte mit MapZoom=10 einließt und die Material-Werte in einem mehrdimensionalen Array abspeichert. Ziel des ganzen war es den dynamischen Kartengenerator dazu zu missbrauchen während der Laufzeit statische Kartenabschnitte, via "DrawMap()" zu generieren. Es hat aber nie so ganz funktioniert. Ich hab mir das neulich nochmal angesehen und den Fehler entdeckt, der Schlüssel war "mask=1" damit sich überschneidende Overlays nicht gegenseitig löschen wenn in dem letzteren nur Sky gezeichnet wird.
Warum ich das ganze ursprünglich gemacht habe weiß ich leider nicht mehr. Aber es klappt, also hab ich mir mal eine meiner Lieblingskarten, Xeron, geschnappt und eingelesen. Das ganze wäre allerdings unspektakulär wenn er die Karte einfach so wieder ausspuckt. Aber zum Glück kann der dynamische Kartengenerator, wie ich gelernt habe, mehrere Overlays übereinander legen. Ich werd mir noch ein sinnvolles Spielziel überlegen und an dem dynamischen Teil schrauben aber hier ist mal ein Screenshot von einer Runde Xeron vs Himmelsinseln (Himmelsinseln nur mit Erde, Erz und Kohle in diesem Fall).

Wow, ich finds geil.
Damit hat man von beiden Kartentypen die Vorteile. zB. Siedelkarten Semi-Dynamisch zu machen ist ziemlich kuhl.
Stellst du das System zur Verfügung? :stuck_out_tongue:

Wenn es so ist, wie ich's verstanden habe dann: Nett!

Jo, ich werd es aber noch ein bisschen aufräumen, sieht momentan nämlich noch echt nicht gut aus. Ich werd das ganze einfach im System.c4g von dem Szenario lassen, man könnte sich die Karte auch als String auf die Konsole schreiben lassen, von da kopieren und in's Landscape.txt packen.

Guter Mann! Da kriegt man direkt Lust zu entwickeln. :grin:

Es hat dann doch etwas länger gedauert (Da hat es mich wieder gepackt noch mehr Kleinigkeiten einzubauen). Aber hier findet ihr die Xeron Siedelversion mitsamt dynamischen Kartengenerator Hack. Das schöne an dem ist auch das die Karte zur Laufzeit generiert wird. Ich hab allerdings nicht getestet ob das in Netzwerkspielen zu Desyncs führt. Aber wenn man nach einem Fehltritt von einem Savegame lädt ist nicht sicher, dass die Karte wieder so generiert wird wie sie letztes mal war.

Ich weiß nicht wie viele tatsächlich mal geguckt haben wie das ganze hier Funktioniert aber alles in allem war es nicht ganz so doll. Deswegen habe ich das ganze mal überarbeitet. Mittlerweile kann man mit nur einem Befehl eine beliebige Karte mit beliebiger Größe einlesen und bekommt einen String zurückgegeben, welcher vom Dynamischen Kartengenerator benutzt werden kann um die selbe Karte zu zeichnen. Verbessert ist dabei, dass keine Chunks mehr benötigt werden, man also nicht mehr darauf achten muss das die Karte in 100x100 Pixel Blöcke aufteilbar ist. Stattdessen wird einfach ein Zweidimensionaler Array erstellt der die Karte von Oben nach Unten von Links nach Rechts enthält. Dank Jan habe ich auch herausgefunden, dass es möglich ist die Textur eines Materials abzufragen. Damit gehen jetzt die Texturen nicht mehr verloren.

Wozu das ganze?
Man kann mit dem ganzen jetzt eine Menge mehr Dinge machen die ansonsten mit ziemlichem Aufwand verbunden sind. Beispielsweise kann man zwei Karten die unterschiedliche TexMaps haben einlesen und nebeneinander generieren lassen ohne sich Gedanken darüber zu machen das die Materialien durcheinander kommen. So kann man durch das ändern eines Blocks in der Karte im Editor und einem Klick auf ‘Szenario speichern’ eine neue Map.bmp mit passender TexMap.txt generieren (solange man nicht über die 128 Material-Textur Kombinationen kommt). Oder man kann den Zoom einer Karte auf 10 setzen ohne das sich die Maße oder das Aussehen groß verändert.

Als Beispiel habe ich mir mal das Alte ‘Unterwasser’ aus dem CE Missionsordner genommen und ‘Heilung der Welt’ mit einem dynamischen Füllalgorithmus drüber gelegt. Das Kombinieren der beiden Karten wäre an sich nicht ganz einfach, da ‘Unterwasser’ einen Zoom von 14 und ‘Heilung der Welt’ Zoom von 15 hat aber es wäre möglich gewesen. Den dynamischen Füllalgorithmus drauf zu legen wäre allerdings unmöglich gewesen, da beide Karten statisch sind. Dann habe ich noch ein kleines Script geschrieben damit die Übergänge von Wasser zu Tunnel durch Erde unterbrochen werden (siehe Screenshot) und voilà ein neues Siedelszenario mit halbdynamischer Karte. Es ist vielleicht ein bisschen schwer zu erkennen, dass die Teile in der Karte mit Säure und Öl Teile aus der statischen Karte von ‘Heilung der Welt’ sind aber so ein paar erkennt man vielleicht wieder.

Momentan funktioniert das Einlesen der Karte in 10x10 Pixel Blöcken, was bedeutet das anders gezoomte Karten ein bisschen abgeschätzt werden. Ich könnte dem System noch beibringen die Zoomstufe beim Einlesen als Parameter zu akzeptieren. Den String den man zurück bekommt kann man allerdings beliebig Zoomen. Auch kann es passieren das Materialien die Stark in andere überlappen verhindern das der korrekte Material-Textur-Wert eingelesen wird, was an manchen Rändern leider nicht so leicht vermeidbar ist. Beachten muss man noch das im Szenario.txt die richtigen Maße für die Map gewählt werden müssen, sonst wird die Karte unten und rechts abgeschnitten. Momentan ist das ganze auch noch nicht so super Performant, große Maps brauchen vielleicht länger zum Laden.

In dem DynMapStatic.c des System.c4g des attatchetem Szenarios findet ihr ein GetDynMapString(), welches einen ziemlich großen String in den Log schreibt. Den könnt ihr in ein Landscape.txt mit “map Mapname{ ‘Insert String here’ };” einfügen und mal gucken wie das ganze aussieht. Viel Spaß!