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 aus Age of Empires II
|
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:
|