Laden...

Worldmap bei GDI+ Game als Bitmap oder Array-Map

Erstellt von Animal21 vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.299 Views
A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 11 Jahren
Worldmap bei GDI+ Game als Bitmap oder Array-Map

Hallo Freunde,

ich versuche mich aktuell an Game-Development mit GDI+, um mich etwas an das Thea heran zu tasten.
Es soll ein 2D-Old-School-Single-Player-Mini-RPG werden. ^^

Ich hab aktuell einen TickBasierten Game-Cycle und die Basis-Klassen für meine Game-Objekte. (Bitmap sprite, Point pos, Size size, ..., so etwas)

Nun soll es an die Weltkarte gehen und ich frage mich, ob ich eine Karte als Bitmap mache und die nach Bewegung des Helden einfach verschiebe, oder ob ich lieber ein Array mit Cells und Tile-Informationen machen soll.

Bei der Bitmap-Variante müsste ich natürlich noch Objecke, wie Berge, extra auf der Map plazieren. Bei der Array-Variante könnte ich diese direkt in die Tile-Information mit reinschreiben, bzw erkennen.

Was ist besser, schlechter oder lauf ich komplett in die falsche Richtung?

gruß
ani

S
269 Beiträge seit 2010
vor 11 Jahren

Es kommt aus meiner Sicht unter anderem darauf an, wie die Bewergung später ablaufen soll... also läuft man, klassisch RPG Style (in Anlehnung an den RPG Maker XP) mit einer Schrittweite von einem Tile oder läuft man eher "dynamisch", will heißen man läuft solange die Richtungstaste gedrückt wird und beim loslassen steht man still... (unabhängig von der aktuellen "Position" im Walk-Cycle")?!

Wenn hier Tile-Steps ausgeführt werden, würde ich zur Variante 2 greifen, wenngleich ich nicht wirklich ein Array als Tile-Store nutzen würde. Dafür gibt es sicher bessere Collections 😉
Außerdem sehe ich hier eher den Vorteil von Tile-States (Objekt-States).

Andernfalls kann man es auch so machen, wie bei deiner Variante 1. Du müsstest halt irgendwo auch noch Speichern, welche Gebiete "walkable" sind und welche nicht (Berge, Wasser, etc.) und auch unter welchem Vorraussetzungen (Schwimmen, Boot, Flugmittel... etc.)

Auf jeden Fall sollte deine Map mehrere Ebenen haben:
Background-Layer: Hintergrund-Tiles/Grafiken, wie Gras, Sand, mgl. auch Wasser (wenn man nicht schwimmen kann z.B.)
Object-Layer: Welt-Objekte, wie Bäume, Berge und auch Wasser (wenn Schwimmen möglich sein soll)
Player-Layer: Das Layer, auf welchem du deine Spielfigur platzierst.
Foreground-Layer: Für simple Grafiken, welche auch man den Spieler und andere Objekte überdecken können... Wolken, Baumwipfel, Splashscreens... und natürlich das UI, außer man packt das auf ein extra UI Layer... 😉
Text-Layer: Zur Anzeige von Nachrichten

P.S.: manche Layer lassen sich u.U. auch zusammenfügen, wie Player-Layer und Object-Layer

so far
Karill Endusa

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Animal21,

wenn du meinst, dass die komplette Karte eine einzige große Bitmap sein soll, kommst du sicher sehr schnell an die Grenzen. Das bedeutet aber nicht, dass du Tiles (im Sinn von einem Satz vorgegebener wiederverwendeter "Plättchen" für die einzelnen Felder) verwenden musst. Aber irgendeine Aufteilung deiner Gesamtkarte in Teile handhabbarer Größe wirst du brauchen.

herbivore

A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 11 Jahren

Die Bewegung soll eigentlich frei sein.

Das mit den Layern klingt gut, wie realisiert sich das genau?

Ich hab aktuell mit den Objekten so gedacht:
Alle Objekte in einer Liste, welche bei jedem Render-Cycle durchgegangen wird und einen Draw für jedes Ojekt ausführt.

Layer würde ja heißen das ich entweder mehrere Listen habe, die einfach nur eine bestimmte Reihenfolge haben:
foreach(Mesh m in Background) m.Draw(...);
foreach(Mesh m in Objects) m.Draw(...);
foreach(Mesh m in Player) m.Draw(...);
foreach(Mesh m in Foreground) m.Draw(...);
foreach(Mesh m in Text) m.Draw(...);
foreach(Mesh m in UI) m.Draw(...);

oder die Objekte sind einfach in einer Liste entsprechend sortiert. Abe rich denke eine Trennung wäre da einfacher

Im Prinzip würde ich Tiles im Kachelmuster schon schön finden (oder gibt es noch eine bessere variante das umzusetzen?).
Ich dachte an soetwas wie: Player ist z.b. 30x30 Groß und ein Tile 5x5 (für Boden, Sand Wasser z.b.), um eine feinere Struktur zu bekommen.
Objekte etc. wären halt größer.
Dinge wie Wolken könnte man als pngs ja einfach "drüber schweben" lassen.

Womit ich glaube das grüßte Problem habe, ist die Karte nur teilweise zu laden. Also ich muss ja nur meinen aktuellen "Viewport" zeichnen und icht alles was es gibt.

Jedes Tile müsste dann ja trotzdem eine entsprechende Graphik laden...

B
357 Beiträge seit 2010
vor 11 Jahren

Das ist richtig. Aber du weißt ja (hoffentlich), an welcher Position sich deine Spielfigur befindet. Davon ausgehend kannst du deinen Viewport bestimmen und dementsprechend die Zeichnung veranlassen. Klar muss für jedes Tile eine Grafik gezeichnet werden, aber eben nicht eine einzige riesengroße Bitmap, die immer im Speicher rumdümpelt, obwohl man nur den Viewport davon bräuchte.

S
269 Beiträge seit 2010
vor 11 Jahren

Wenn das dein größtes Problem ist, dann kannst du ja froh sein 😉
Ein Mesh-Objekt hat ja eine eindeutige Position auf der Gesamtkarte.
Dein Player hat zu jedem Zeitpunkt ebenfalls eine eindeutige Position auf der Gesamtkarte.
Aus der Player-Position lässt sich ohne Weiteres ein Viewport generieren.
Beim Durchgehen deiner Meshes musst du dann nur noch prüfen, ob es sich zum aktuellen Zeitpunkt (teilweise) innerhalb deines Viewports befindet... das ist, da es sich beim Viewport selbst ja nur um ein Rechteck handelt (bzw. handeln sollte), recht simple Geometrie (davon abgesehen, dass das .Net Framework dafür schon Methoden bereitsstellt (Rectangle.Contains Method)

A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 11 Jahren

OK, für den Render-Bereich ist mir nun klar, einfach das entsprechende Rechteck nur Zeichnen, den Rest ignorieren.

Für den Ladevorgang, bzw Update Vorgang heißt das was:

  • ich Lade die Ressource (also das Bild) erst, wenns es gezeichnet werden soll
  • oder ich lade trotzdem alle Mesh-Ressourcen schon, aber zeichne sie nur wenn ich sie brauche?