2D - Map speichern

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

2D - Map speichern

Beitrag von nufan » Fr Mär 20, 2009 6:09 pm

Hallo!
Mal eine allgemeine Frage zu Spielen :)

Ich wundere mich immer öfters bei Spielen (vor allem GB/GBA-Spielen) wie z.B. dem klassischen Mario, wie die Maps gespeichert werden. Ich glaube nämlich nicht, dass alles in 1 Surface gespeichert wird.

Meine Idee:
* Tilesheet mit allen möglichen Grafiken erstellen
* einen Editor schreiben mit dem man die Tiles platzieren kann und die Infos einer Struktur (mit Position in der Map, welche Grafik, "fest" oder nicht, ...) in ein File schreibt
* beim Programmstart alle Tiles laden (aus Performancegründen natürlich nicht jeden Frame laden)
* alle Strukturen aus dem File in eine Liste schreiben
* jeden Frame alle Listenelemente prüfen, ob sie im aktuellen Bild sind
* jeweilige Tiles blitten

So :)
Nur ist das ziemlich aufwendig jeden Frame alle Listenelemente zu prüfen. Wie wird das denn wirklich gemacht?

PS: Nein, ich will (noch ^^) keinen Mario-Klon schreiben. Es ist einfach eine Frage, die mich nicht in Ruhe lässt :)

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: 2D - Map speichern

Beitrag von cloidnerux » Fr Mär 20, 2009 6:19 pm

Ich glaube in Solchen Spielen wird alles nach kategorien gespeichert(Mauern, Gras, Items). Dann ist in der Map gespeichert was wo ist(Gras, Wand). Im editor kannst man dann die Map ändern.
Redundanz macht wiederholen unnötig.
quod erat expectandum

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: 2D - Map speichern

Beitrag von nufan » Fr Mär 20, 2009 6:28 pm

cloidnerux hat geschrieben:Ich glaube in Solchen Spielen wird alles nach kategorien gespeichert(Mauern, Gras, Items). Dann ist in der Map gespeichert was wo ist(Gras, Wand). Im editor kannst man dann die Map ändern.
Der Typ sollte natürlich auch in der Struktur stehen.
Mir geht es eher darum, wie die Map im File gespeichert und besonders wie sie dann ausgegeben wird. Meine Methode würde wahrscheinlich funktionieren, nur wäre das ziemlich aufwendig immer die komplette Liste zu prüfen.

Mal angenommen im Spiel sind alle Tiles gleich groß (sieht dann nicht gut aus, ist ja nur ein Beispiel). Die Map ist 10 Standard-Tiles hoch und 1000 breit. Das wären dann nach meiner Theorie schon 10.000 Knoten, die jeden Frame geprüft werden müssten... Da muss es doch was einfacheres geben. ;)

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: 2D - Map speichern

Beitrag von cloidnerux » Fr Mär 20, 2009 7:34 pm

Also, du unterteilst dein Speilfeld einfach in Quadrathte(Rechtecke) von gleicher Größe. Jezt sieht deine map so aus:

Code: Alles auswählen

1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 3 0 0 0 1
1 0 0 2 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 4 4 4 4 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
1 steht für eine Normale Mauer, die das Spielfeld eingränzt.
0 Steht für Boden -> also nichts womit der Spieler Kolidieren kann
2 und 3 wären evt. Items.
4 Wäre eine Erweiterte Wnad, wo man Hochklettern kann oder sowas.
Jedes Elment aknnst du als Char Darstellen und hast so eine kleine map.
Jezt leist ud einfach die damit Refernzietren bilder uas und gibts diese aus. Damit hast du weniger Verwaltungsaufwand.
Redundanz macht wiederholen unnötig.
quod erat expectandum

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: 2D - Map speichern

Beitrag von nufan » Fr Mär 20, 2009 8:55 pm

cloidnerux hat geschrieben:Also, du unterteilst dein Speilfeld einfach in Quadrathte(Rechtecke) von gleicher Größe. [...]
Ok, das ist mal ein einfacher Ansatz. Nur muss ich das wieder in einen Array oder eine Liste packen und immer weiterverschieben (bei Bewegung). Aber da wird man sowieso nicht drumrum kommen. Es hat aber den Vorteil, dass man die Map in einem Texteditor verändern kann. Nur "ungerade" Grafiken kann man damit nicht platzieren. Ich bin vorerst zufrieden :)

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: 2D - Map speichern

Beitrag von cloidnerux » Fr Mär 20, 2009 9:14 pm

Dann bin ich aber Froh :)
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: 2D - Map speichern

Beitrag von Xin » So Mär 22, 2009 10:36 pm

dani93 hat geschrieben:Ich wundere mich immer öfters bei Spielen (vor allem GB/GBA-Spielen) wie z.B. dem klassischen Mario, wie die Maps gespeichert werden. Ich glaube nämlich nicht, dass alles in 1 Surface gespeichert wird.
Was verstehst Du unter einer Surface? Eine große Grafik?
dani93 hat geschrieben:Meine Idee:
* Tilesheet mit allen möglichen Grafiken erstellen
* einen Editor schreiben mit dem man die Tiles platzieren kann und die Infos einer Struktur (mit Position in der Map, welche Grafik, "fest" oder nicht, ...) in ein File schreibt
* beim Programmstart alle Tiles laden (aus Performancegründen natürlich nicht jeden Frame laden)
* alle Strukturen aus dem File in eine Liste schreiben
* jeden Frame alle Listenelemente prüfen, ob sie im aktuellen Bild sind
* jeweilige Tiles blitten

So :)
Nur ist das ziemlich aufwendig jeden Frame alle Listenelemente zu prüfen. Wie wird das denn wirklich gemacht?
Statt einer Liste verwendet man ein 2D-Array oder wenn man sich mehr Aufwand macht einen Quad-Tree.
dani93 hat geschrieben:PS: Nein, ich will (noch ^^) keinen Mario-Klon schreiben. Es ist einfach eine Frage, die mich nicht in Ruhe lässt :)
Schade... wenn ich mal Zeit hätte, wäre das eines der ersten Projekte, die ich angehen würde. ;-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: 2D - Map speichern

Beitrag von nufan » Mo Mär 23, 2009 3:21 pm

Xin hat geschrieben:Was verstehst Du unter einer Surface? Eine große Grafik?
War im Bezug auf SDL-Surfaces gemeint. Etwas genauer:
Ich glaube nicht, dass das alles in 1 Grafik gespeichert wird, da die sonst ziemlich groß wäre. Außerdem kann man dann nicht feststellen, wo man sich gerade bewegt. Dann bräuchte man erst wieder eine Liste oder einen Array.
Xin hat geschrieben:Schade... wenn ich mal Zeit hätte, wäre das eines der ersten Projekte, die ich angehen würde. ;-)
Ich auch :)
Aber ich komm ja nicht mal dazu an meinem anderen Programm weiterzuschreiben. Wobei - einen gewissen Reiz hat es schon. ;)
Außerdem sind wir in der Schule gerade beim Umstieg auf C++. Vielleicht wird das mein erstes größeres C++-Programm :)

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: 2D - Map speichern

Beitrag von nufan » Do Mai 21, 2009 1:53 pm

Ich hab mich in letzter Zeit wieder ein bisschen damit beschäftigt und möchte euch jetzt mein "Konzept" dazu vorstellen :)

Also:
Ich hab einen kleinen Editor mit SDL geschrieben. Er verwendet 3 Klassen. Die 1. zur Verwaltung der Map (also zeichnen, speichern usw.). Die . ist ein einzelnes Tile. Die ist recht klein, enthält nur die Nummer der 32*32 Pixel Grafik im Tilesheet und einen Konstruktor. Die 3. ist ein (selbst implementierter ;) ) 3D-Vektor aus Tiles. Dies ist also die eigentliche Map und ist auch in der 1. Klasse enthalten.
Die Map hat x, y und z (fixe Layers) Koordinaten. Sie ist mindestens 20*20 Tiles groß, aber eben dynamisch. Und wie bestimme ich jetzt die Position eines Tiles in der Map? Der Cursor im Editor ist das aktuelle Tile, rechts unten wird auch die aktuelle Schicht angezeigt. Klickt man jetzt auf einen Platz in der Map, übergebe ich den SDL_Event an die Methode LayTile.

Diese sieht so aus:

Code: Alles auswählen

void CMap::LayTile (SDL_Event event, int tile, int layer)   // Klick-Event, Nummer des Tiles, Schicht
{

  int x, y, xpos, ypos;                       // Koordinaten

  x = event.button.x - (event.button.x % 32);           // Koordinaten auf die letzte durch 32 teilbare Zahl abrunden
  y = event.button.y - (event.button.y % 32);

  xpos = x / 32;                                                     // durch 32 dividieren, ergibt die Position im 3D-Vektor
  ypos = y / 32;

  map.v[xpos + distleft][ypos + distup][layer].SetTile (tile);      // Wert im Vektor setzen

}
Also ich runde auf die letzte im x- und y-Bereich teilbare Zahl ab. Dann bin ich am linken oberen Eck des Feldes (im Fenster), wo die Grafik hinkommen soll. Dividiere ich durch 32, erhalte ich die x- bzw. y-Position im Vektor. "distleft" und "distup" sind Member der Klasse und die Entfernungen vom linken bzw. oberen Rand, der durch das Scrollen in der Map entsteht. Layer wird von main übergeben. So kann ich bequem ins binary-File schreiben und muss mir keine Gedanken über Ordnung machen, da der Vektor ja schon geordnet ist.

Wie findet ihr diesen Ansatz?
Mir gefällt er gut, da er recht einfach ist und auch das Scrollen in der Map nicht schwer zu implementieren war.

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: 2D - Map speichern

Beitrag von Kerli » Do Mai 21, 2009 2:53 pm

dani93 hat geschrieben:Wie findet ihr diesen Ansatz?
Mir gefällt er gut, da er recht einfach ist und auch das Scrollen in der Map nicht schwer zu implementieren war.
Der Ansatz schaut eigentlich ganz gut aus. 'distleft' und 'distup' ist wahrscheinlich der aktuelle Offset oder? Nur das Runden kannst du dir sparen, da bei einer Integerdivision sowieso alle Nachkommastellen abgeschnitten werden...

Was ich nicht so gut finde ist das die Benennung etwas inkonsistent ist. So heißt es zb einmal 'SetTile' und dann wieder 'LayTile'. Ich würde in der Map eine Methode 'setTile' implementieren der man Koordinaten und Wert übergibt und diese dann auch für ein SDL Klickevent überladen die dann wieder die erste Version aufruft...
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Antworten