Texte / Der dynamische Kartengenerator - Teil I
Einführung
Bis zur GWE3 konnte man Landschaften auf drei Weisen definieren: Exakt (pixelgenaue Landscape.bmp), statisch
(Verkleinerte Landscape.bmp) oder dynamisch. Bei letzterer Variante waren jedoch nur einfache, durch Sinusschwingungen
generierte Landschaften möglich. Dies brachte ein wenig zusätzliche Abwechslung in die Runden; dafür waren die
Gestaltungsmöglichkeiten der Karte aber sehr begrenzt.
Genau hier sollte nun der MapCreatorS2 ansetzen: Es sollten abwechslungsreichere, dynamische Landschaften mit den
Gestaltungsmöglichkeiten einer statischen Karte kombiniert werden.
Der neue Landschaftsgenerator setzt dabei allerdings eine Menge technisches Denken sowie logisches Verständnis voraus.
Wer im Mathematikunterricht immer Probleme mit der Mengenlehre hatte, sollte vielleicht lieber erst einmal bei statischen
Karten bleiben.
Funktionsweise
Ein Hauptziel des neuen Landschaftsgenerators war, möglichst abwechslungsreiche und spannende Landschaften zu kreieren.
Darum ist es auch manchmal schwer, seine exakten Vorstellungen einer Zufallskarte umzusetzen - denn der Designer gibt nicht
an, dass beispielsweise fünf Goldfelder in Größe X im Boden verteilt werden sollen. Stattdessen werden Bitebenen definiert,
die mit einer zweidimensionalen 1-Bit-Textur versehen werden. Diese werden dann mit einem Material-Textur-Tupel, sowie
weiteren, inneren Ebenen belegt. Die Textur wird algoritmisch aus den Parametern der Ebene generiert.
Um die Sache etwas anschaulicher zu machen, kann man sich eine so definierte Landschaft als aufeinandergelegte
Lochmasken vorstellen (Dieser Vergleich hinkt bei komplexeren Kombinationen aber leider etwas).
Eine erste Landschaft
Grau ist alle Theorie, und so wollen wir nun einfach einmal eine kleine Landschaft von Grund auf neu erstellen. Dazu
lege ein neues Szenario mit möglichst wenig geladenen Objekten an (LocalOnly ist optimal), und teste deine Karten direkt im
Frontend. Im Szenario erstelle eine neue Datei mit dem Namen "Landscape.txt", in die du diese Beispiele kopieren kannst
(immer nur eine gleichzeitig!). Es empfiehlt sich, das Szenario zu entpacken, und die Landscape.txt dann extern direkt aus
dem Windows-Explorer zu öffnen. Dies erspart die Laufzeitupdates des Frontends.
Die Beschreibungssprache vom MapCreatorS2 arbeitet mit Schachtelungen (vergleichbar mit z.B. HTML, XML, oder anderen
SGML-Varianten), und darum beginnen wir natürlich mit dem äußersten Element: Der Karte. Hier ein einfachstes Beispiel:
/* Eine erste Testkarte
mit mehrzeiligem Kommentar!*/
map Example1 { // meine erste Zufallslandschaft!
mat=Water; tex=Smooth;
};
|
Eine erste
Zufallskarte!
|
Die Karte wird hier einfach komplett mit Wasser gefüllt. Eine kurze Erklärung der einzelnen Elemente: Die Erste Zeile
ist ein Kommentar, eingeschlossen durch /* und */. Der Parser (das ist der Teil des Landschaftsgenerators, der den Text für
den eigentlichen Generator einliest) ignoriert den Text zwischen diesen Zeichen. Dasselbe gilt für den Text hinter dem
doppelten Schrägstrich. Hier wird der folgende Text bis zum nächsten Zeilenumbruch ignoriert. Darauf folgt in der dritten
Zeile das Schlüsselwort "map". Das bedeutet, dass die Definition einer Karte folgt. Daran schließt sich der Identifikator
"Example1" an - der Name der Karte. Die darauf folgende öffnende, geschweifte Klammer leitet den Block ein, der diese Karte
definiert. Alles bis zur schließenden Klammer definiert also den Inhalt der Karte. Nach der schließenden Klammer folgt ein
Semikolon, um die Definition abzuschließen.
Die Definition in der Klammer ist also das, was die Karte ausmacht. In diesem Fall werden einfach zwei Eigenschaften der
Karte definiert: Das Material (mat) und die darauf aufgelegte Textur (tex). Die Textur wird später benutzt, wenn aus der
Karte die vergrößerte Landschaft benutzt wird. Gültige Texturen lassen sich in der Material.c4g finden, und dienen nur dazu,
dass die sonst einfarbigen Materialflächen etwas schöner aussehen.
In dieser ersten, einfachen Karte wird also nur die unterste Ebene definiert, und ihr wird das Material Wasser und die
Textur Smooth zugewiesen. Dementsprechend enthält die Karte auch nur Wasser :)
Wo man Zeilenumbrüche setzt, wie man den Text einrückt, oder wo und wie viele Kommentare man plaziert, ist dem Parser
übrigens egal. Man hätte auch die gesamte Karte in eine Zeile schreiben, oder aber in jede Zeile nur ein Wort oder Zeichen
setzen können. Nur sollte man bedenken, dass jede veröffentlichte Zufallskarte potentielles Lehrmaterial für angehende
Entwickler sein kann. Wer also alles zum Ausdruck längs oder quer auf Klopapier schreibt, der macht es nur angehenden
Entwicklern unnötig schwer.
Es wird bunt!
Unsere erste Karte ist nun noch etwas trist, und höchstens für U-Bootschlachten geeignet. Darum soll in die Hauptebene
noch eine weitere gelegt werden:
Reichtümer im
Rechteck |
map Example2 {
mat=Water; tex=Smooth;
overlay {
mat=Gold; tex=Rough;
x=10; y=10; wdt=80; hgt=80;
};
};
|
Hier ist eine weitere Ebene hinzugekommen. Diese Ebene wird mit Gold gefüllt, und ihr Bereich ist eingegrenzt. x, y, wdt
und hgt geben die Grenzen an: x und y sind die Koordinaten der linken, oberen Ecke des Rechtecks; wdt und hgt sind Breite und
Höhe des selbigen. Alle Werte sind prozentual zur übergeordneten Ebene - also zur gesamten Karte.
Auf diese Weise lassen sich also aus Rechtecken alle möglichen Figuren zusammenbauen. Diese werden bei veränderten
Kartengrößen sogar automatisch skaliert.
Kombinationskisten
Ebenen lassen sich nun auf verschiedene Weisen kombinieren. Folgendes Beispiel soll dies erläutern:
map Example3 {
mat=Water; tex=Smooth;
overlay {
mat=Gold; tex=Rough; x=10; y=10; wdt=80; hgt=80;
overlay { x=10; y=10; wdt=50; hgt=50; }
^ overlay { mat=Rock; tex=Rough; x=40; y=40; wdt=50; hgt=50; };
};
};
|
Mengenlehre in Clonk
|
Nun wird es schon komplizierter. In die erste Ebene wurden zwei weitere gelegt und mit einem Operator verknüpft. Da die
beiden Ebenen in der ersten stehen, werden sie nur innerhalb derselbigen gezeichnet, und auch alle Koordinaten beziehen sich
auf die umschließende Ebene.
Die beiden inneren Ebenen sind mit einem Operator verknüpft. Dadurch wird zunächst einmal das Füllmaterial der letzten
Ebene in der Operatorkette (die durchaus auch länger sein könnte - Operatoren werden dann von links nach rechts abgearbeitet)
für die Füllung verwendet. Darum enthält die erste der inneren Ebenen auch keinen mat- oder tex-Eintrag. (Normalerweise
bedeutet ein weggelassener Eintrag, dass Himmel verwendet wird. Nicht kein Material!).
Der Operator ^ steht für exklusives Oder. Das heißt, dass die Ebene gezeichnet wird, wenn entweder der linke oder der
Rechte Operand erfüllt ist (d.h. die links oder rechts stehende Ebene gezeichnet würde), nicht aber beide. Dies ist im
Beispiel leicht erkennbar. Der graue Fleck oben links liegt in der ersten der beiden innersten Ebenen, der unten rechts in
der zweiten. Der nicht grau gezeichnete Fleck in der Mitte läge in beiden - der ^-Operator besagt aber, dass genau dann nicht
gezeichnet werden soll. Und so scheint hier weiter die äußere Ebene, das Gold, durch.
Ebenen lassen sich beliebig schachteln und verknüpfen. Weitere Operatoren sind das logische Und (&), bei dem beide
Operanden erfüllt sein müssen; sowie das logische Oder (|), bei dem nur eine Ebene erfüllt sein muss.
Das war alles?
Dies waren natürlich nur die wichtigsten Grundlagen der Ebenenkombination, auf die die folgenden Teile des Tutorials
aufbauen werden. Trotzdem sollte jeder einmal versuchen, mit diesen Elementen ein wenig herumzuspielen. Besonders mit
Operatorketten und Ebenenverknüpfungen sollte man gut vertraut sein, um die Algorithmen später sinnvoll einsetzen zu können
(z.B. was passiert wenn man Ebenen mit untergeordneten Ebenen mit Operatoren verknüpft, usw.).
Weiter zum nächsten Teil.
Sven2 27.01.2002
5 Kommentare
|
Dickes Lob und so ;)
Für Anfänger sehr zu empfehlen.
mfg Dragonclonk
Zuletzt geändert: 06.04.2007 21:36
Oder den Entwicklermodus, woher man den bekommt willst du wissen?
http://www.clonk.de/ <-wäre hilfreich, wenn du da mal vorbeischaust(wegen Entwicklermodus).