Minimaps in tilebasierten Spielen
1. Warum schreibe ich so ein Dokument?

Wenn man im Internet nach einem Paper zu Minimaps sucht, wird man leider nicht sehr weit kommen. Man findet vielleicht ein paar Infomationen, jedoch sind diese sehr rar. Damit andere nicht noch einmal lange rumsuchen müssen biete ich hier ein paar grundlegende Dinge.

2. Was sind Minimaps überhaupt und über was geht dieses Paper?

Minimaps sind kleine Karten die man meist in RTS Spielen, wie z.b. AoE II oder C&C, auffinden kann. Diese stellen die Karte in einem kleinen Fenster dar, welche sich meist im Interface befinden. Normalerweise ist darauf nicht nur die rohe Karte, sprich der Boden inklusive Umgebung, zu sehen, was natürlich nicht sehr nützlich wäre, sondern auch noch Einheiten, der Nebel des Krieges und vielleicht sogar Missionsziele.
Ich werde mich in diesem Paper auf Minimaps beziehen die tilebasierte Karten betreffen. Zu der Theorie findet man am Ende noch ein Quelltext, der die Theorie ein wenig verdeutlicht, welcher in C/C++ mit der Verwendung der SDL geschrieben ist. Hier noch ein paar Beispiele zu Minimaps:

minimap_aoe
Minimap aus Age of Empires II
minimap_sc.jpg
Minimap aus Starcraft

3. Wie baut man eine Minimap auf?

Im Grundlegenden ist eine Minimap wie eine tilebasierte Karte aufgebaut und besteht aus einem Array von Tiles bzw. irgendwelchen Referenzen auf Tiles. Hat die Karte mehrere Ebenen muss man dies natürlich bei der Erstellung der Minimap beachten.
Dieses Array besteht wie gesagt meist aus Zahlen oder Zeichen, in den seltesten Fällen wird man Tiles sprich Grafikdaten direkt in der Karte speichern. Die Karte findet sich also in einem Array. Nun zur Minimap. Wir müssen uns erstmal klar machen wie diese aufgebaut ist.
Genauso wie die reale Karte sollte diese aus einem Array bestehen, welches der Größe der Karte natürlich entspricht. Dieses Array beinhaltet jedoch keine Referenzen auf Tiles sondern lediglich die Farben der Pixel. Wie kommt man jedoch auf die Daten des Arrays? Und wo genau kommt dieser Pixel her?
Ganz einfach. Bei der Initialisierung der Karte, manche mögen es auch als Laden bezeichnen, berechnet man die Farbe die eine Tile im Durschnitt besitzt. Dies macht man für sämtliche Tiles und speichert diese dann in dem oben genannten Array.
In den meisten Fällen will man wohl, dass seine Minimap von der Größe her konstant bleibt. Dazu würde ich vorschlagen eine standard Kartengröße zu haben. Größere Karten als diese bzw. auch kleinere werden dann einfach beim Finden des durschnittlichen Farbwertes mit dem Faktor 2 multipliziert bzw. dividiert.
Im Klartext soll dies heißen dass man bei kleineren Karten eine Tile für vier, acht oder sechszehn Pixel nimmt. Und für größere Karten nimmt man dann mehrere Tiles, sprich vier, acht oder sechszehn Tiles für ein Pixel. So wird die Größe deiner Minimap konstant bleiben. Gut geeignete Kartengrößen wären dann z.b. 64x64,128x128 oder 256x256.
Fassen wir also zusammen. Unsere Minimap wird aus einem Array bestehen welches Farbwerte für eine konstante Kartengröße enthält. Ist die Karte größer oder kleiner müssen wir dies beim Berechnen der Farbwerte beachten.

4. Wie finde ich den durschnittlichen Farbwert?

Ja, wie finden wir denn jetzt den Farbwert den unser Pixel in der Minimap braucht. Das ist auch nicht schwer, gehen wir mal von eine 32x32 Pixel großen Tile aus ( natürlich geht das auch mit 64x32 und anderen ). Wie man einen Durschnitt rechnet weiss jeder, man rechnet also die Farbwerte der Pixel zusammen und teilt diese dann durch die Anzahl. Das war's schon? Ja, das war's schon.
Allerdings hat man oftmals die Farbwerte in dieser Form 0x452365. Diese sollte man natürlich nicht einfach so zusammen rechnen. Filtert am besten die einzelnen Werte für R, G und B heraus, summiert und teilt anschließend diese. Hat man nun eine Karte die größer ist sollte man die Pixel von den anderen Tiles hinzuaddieren und natürlich durch die Anzahl der Pixel aller Tiles die man mitgerechnet hat teilen. Hier erstmal Code wie man dies für ein Tile bewerkstelligen könnte:

farbwert getDurschnittsFarbwert( bild )
{
    r, g, b = 0;
    anzahlPixel = bild.breite * bild.höhe;
    für( i = 0; i < anzahlPixel; i = i + 1 )
    {
       r = r + bild.farbwert[ i ].R;
       g = g + bild.farbwert[ i ].G;
       b = b + bild.farbwert[ i ].B;
    }
    r = r / anzahlPixel;
    g = g / anzahlPixel;
    b = b / anzahlPixel;
    gibZurueck farbwert( r, g, b );
}

Das sollte ja nicht so schwer zu verstehen sein. Diese Funktion ist auch nochmal im C/C++ Beispielcode implementiert.

5. Ok, ich habe den Farbwert was nun?

Nun gut, wie man das nun weiterhin handelt ist einem ganz selbst überlassen. Da gibt es jetzt verschiedene Möglichkeiten, wie z.b. die Farbwerte in einem Array zu speichern, bzw. das ganze noch in eine Klasse zu packen. Oder man könnte die Farbwerte den Tiles zuordnen und eine Zeichenroutine machen.

6. Beispielcode

Hier gibt es ein Beispielprogramm, welches eine minimalistische tilebasierte Karte zeichnet die 10x10 tiles groß ist. Rechts daneben wird eine 10x10 Pixel große Minimap angezeigt.
Das Programm wurde in C/C++ mit Verwendung der SDL und der SDL_image geschrieben.
Und das ganze sieht dann so aus:

minimap.png
All trademarks and copyrights on this page are owned by their respective owners | © 2003 Marcus Körner