Beste Weg, um eine Karte für ein 2D-Spiel zu erstellen?

16

Ich entschuldige mich für das subjektive "beste" Keyword.

Mein Freund und ich haben begonnen, ein 2D-Abenteuerspiel zu entwickeln. Es wird von oben nach unten im Stil von Pokemon oder Zelda (nur die Perspektive) sein. Wir haben Methoden zur Erstellung einer großen Weltkarte besprochen, die der Spieler durchqueren kann, ohne die Speicherkapazität unseres Computers zu belasten.

Unser erster Impuls war, eine große Karte und einen Kreis um den Player zu erstellen, in den der Inhalt geladen werden soll. Wir dachten, dass dies nicht lange anhält und beschlossen, die Karte in Abschnitte zu unterteilen. Zuerst hatten wir vier große Abschnitte, aber wir erkannten, dass wir es einfach in viele winzige Abschnitte aufteilen konnten.

Ich habe Zelda von der SNES gespielt und gesehen, dass der Inhalt während des Verschiebens einer Karte gerade dann geladen werden konnte. Ich meine, anstatt nur einen rechteckigen Bereich auf zu ladende Daten zu prüfen, teilen wir die Karte einfach in viele winzige Abschnitte auf, die Daten laden und entladen, wenn wir uns von Kartenabschnitt zu Kartenabschnitt bewegen.

Heute sagte er mir, er wolle eine einfache 2D-Array-Karte [WIDTH] [HEIGHT] erstellen, die Daten zu jedem Raster im Spiel enthält und eine permanente Operation zum Speichern von Daten auf der Festplatte darstellt, die wir nicht benötigen.

Ich bin mir bei diesen Ideen nicht sicher und dachte, dass ich es hier könnte. Alle Links, Ressourcen oder Tutorials zu diesem Thema sowie direkte Antworten auf unsere Frage, wie Sie dies effizient tun können, sind sehr willkommen.

IAE
quelle
Welche Maschine benutzen Sie?
David Titarenco
Bisher Windows mit C ++ und SFML (Änderungen vorbehalten; C ++ nicht). Wir streben keine Portabilität an.
IAE
2
Wenn Sie sich für Zelda der alten Schule auf dem NES entscheiden, werden nur Karten mit einem Bildschirm verwendet. Kleine Karten helfen den Spielern, den Bereich ihrer Absichten zu fokussieren (dh in einem Dungeon beschäftigen Sie sich nur mit Ihrem Raum. In Diablo haben sich Monster nicht auf und ab bewegt) und lassen sie sich fertig fühlen, wenn sie das gesamte Gebiet durchsucht haben dass Open-Space-Spiele wie FAllout3 und Oblivion Sie nicht geben.
Stephen Furlani

Antworten:

27

Schätzen Sie zunächst Ihre Kartengröße. Gehen Sie nicht einfach davon aus, dass eine "große Welt" nicht in die Erinnerung passt. Heutzutage ist eine Karte, die mehr als 10 MB Speicher benötigt, absolut akzeptabel, und Sie können in einer einfachen kachelbasierten 2D-Welt eine Menge von 10 MB speichern.

Wenn Sie eine sehr große Welt haben, ist die robusteste Lösung die Verwendung von Kartenstücken. Teilen Sie Ihre Welt in Blöcke fester Größe auf (z. B. 64 x 64). Laden Sie Chunks im laufenden Betrieb, während sich der Spieler bewegt, und lassen Sie mindestens einen Chunk in alle Richtungen geladen (dh laden Sie den Chunk, in dem sich der Spieler befindet, und alle seine Nachbarn).

Beim Entladen von Chunks können Sie zwischen mehreren Strategien wählen. Eifriges Entladen bedeutet, dass Sie alle Blöcke entladen und auf der Festplatte speichern, sobald sich der Player weit genug entfernt. Sie können das Entladen jedoch auch verzögern, um die Leistung zu verbessern (das Speichern von Datenblöcken wie bei jedem Datenträgerzugriff ist ein kostspieliger Vorgang).

Keine Ursache
quelle
6
Zur Veranschaulichung: 10 MB Tile * s ergeben ein Quadrat mit 1619 Kacheln pro Seite. Die ursprünglichen Zelda-Karten hatten 256 Kacheln auf der langen Seite und weniger als die Hälfte auf der kurzen Seite - Ihre Karte könnte also mehr als 36x größer sein als die der ersten Zelda mit dieser Speichernutzung. Bist du wirklich bereit, so viel Inhalt zu machen ? (Nr.)
@ user744 Dieser Kommentar ist unglaublich irreführend. Um eine Karte zu erstellen, benötigen Sie mehr als nur Zeiger auf Kacheln. Sie müssen auch die Daten speichern, die die Kacheln enthalten. Nicht jedes 2D-Spiel verfügt über eine festgelegte Anzahl vordefinierter fester Kacheln.
Jeroen
5

Persönlich würde ich die Karte mit einem bestimmten Kachel-Editor wie TileEd erstellen . Dieser Ansatz bietet mehrere Vorteile:

  • Verbraucht weniger Ressourcen. Sie müssen nur ein Kachelblatt und eine Datendatei mit Indizes laden, um eine potenziell endlose Karte zu erstellen.
  • Da Ihre Karte in sehr kleine Teile unterteilt ist (abhängig von Ihrer Kachelgröße), können Sie problemlos Zeilen / Spalten hinzufügen / entfernen, während sich der Charakter durch die Welt bewegt.
  • Wenn Sie über eine Datendatei verfügen, die Ihre Karte beschreibt, können Sie auch problemlos Geländeinformationen hinzufügen. Dies ermöglicht verschiedene Kacheltypen wie Wände oder Seen (dh Hindernisse) oder einen Sumpf, in dem die Bewegung des Charakters verlangsamt werden könnte ...
  • Last but not least ist eine kachelbasierte Karte auch viel einfacher zu bearbeiten und später zu optimieren, da Sie jederzeit den Editor starten, einige Dinge ändern und eine neue Datendatei speichern können.

Ich schlage vor, dass du es vermeidest, Teile der Karte während des Spiels zu laden, um Verzögerungen zu vermeiden. Wie bereits erwähnt, sollte dies nicht erforderlich sein, da Sie das Kachelblatt wahrscheinlich im Speicher behalten können. Wenn der Charakter einen anderen Teil der "Welt" betritt, könnte man das Kachelblatt mit einem anderen tauschen (zB Schneekacheln durch Wüstenkacheln ersetzen).

Das Blenden der Kacheln auf den Bildschirm ist wahrscheinlich der schnellste Weg, um Ihre Karte zu rendern. Ich kenne SFML nicht, aber in den Dokumenten auf ihrer Site sollten Sie sich die SpriteKlasse ansehen oder die CopyFunktion der ImageKlasse verwenden.

Update: Ich habe gerade einige der SFML-Dokumente gelesen und Sie sollten auf jeden Fall Drawableoder verwendenSprite Bilder anstatt sie zu manipulieren, um die Leistung zu verbessern. Anscheinend gibt es da draußen einen gekachelten SFML-Loader . Das ist wahrscheinlich ein guter Weg, um etwas schnell zum Laufen zu bringen.

Blödmann
quelle
1

Stellen Sie zunächst die Größe der Karte so ein, dass sie die Geschichte erzählt, die das Spiel erzählen soll. Testen Sie auf dem Computer mit den Mindestanforderungen, die zum Spielen Ihres Spiels erforderlich sind. Wenn es zu langsam ist, profilieren und optimieren Sie.

Daniel X Moore
quelle
0

Die Verwendung eines 2D-Arrays einzelner Kacheln ist meiner Meinung nach am besten. Sie können die gesamte große Karte als ein 2D-Array haben und nur den Teil davon zeichnen, der zu einem bestimmten Zeitpunkt angezeigt werden muss. Das Folgende ist ein Beispiel für die Verwendung eines 2D-Kartenarrays mit der HTML5-Spielebibliothek tabageos (tbgs.js). http://actiontad.com/tabageosHTML5/Examples/BlitMathCameraAndTravelers/

Mrall
quelle
-3

Sofern Sie nicht vorhaben, ultima-online (Fallout 3 oder Oblivion) ​​neu zu erstellen, gibt es keinen Grund, warum die Welt nahtlos sein muss. Baldur's Gate und Icewind Dale sind zwei denkbare Spiele, die effektive Karten implementieren, die das Gameplay nicht beeinträchtigen.

Zugegeben, Sie haben viel mehr Rechenleistung als sie, daher sollten die Ladebildschirme minimal sein, aber auch Fallout und Oblivion haben Ladebildschirme für einige Dinge.

Ich kann Ihnen nur sagen, dass ich eine kleine Obj-C-Bibliothek für das iPhone schreibe, die ein 32x32-Kachelset nimmt und es in ein NSImage zeichnet. Auf diese Weise erhalte ich ungefähr 10 fps, und ich sollte wahrscheinlich OpenGL verwenden, aber ich muss nur neu zeichnen, wenn sich der Charakter aus dem Rect herausbewegt.

Sie sollten die Karte in 9 Bildschirmgrößen aufteilen (für mich sind es 960x640 Blöcke). Wenn sich der Charakter aus dem mittleren Block herausbewegt, zeichne ich die 9 Bildschirme in ein großes Bild (etwa 1,2 MB - ergibt viel) Speicherplatz unter der 20-MB-Grenze für das iPhone 3G). Dies geschieht ziemlich langsam (viel langsamer als 10 fps), sodass das erneute Zeichnen während des Spiels nicht bemerkt wird.

Ich werde wahrscheinlich irgendwann zu OpenGL ES wechseln, aber im Moment funktioniert es einwandfrei.


[BEARBEITEN]

Lassen Sie mich das klarstellen.

Der Zeichnungsalgorithmus für den 9-Bildschirm-Hintergrund dauert 0,1 Sekunden (10 fps flat-out). Solange Ihr Player nicht in weniger als einer Zehntelsekunde den gesamten Bildschirm durchlaufen kann, sollte das erneute Zeichnen während des Spiels nicht wahrnehmbar sein.

Stephen Furlani
quelle
Nur weil 10fps für Ihr Spiel akzeptabel sind, ist dies keine gute Idee, insbesondere auf einem Gerät mit eingeschränkten Leistungsmerkmalen wie einem iPhone. Möglicherweise führen Sie keine Neuzeichnungen durch, lassen Sie die GPU-Seite die Rasterung durchführen und lassen Sie das Programm tatsächlich eine Weile schlafen, damit das Telefon nicht heiß wird oder die Akkulaufzeit erschöpft ist.
@ Joe Wreschnig ... ??? Ich sagte, dass es auf Abruf gezeichnet wird , wenn der Player den Bildschirm bewegt, andernfalls wird das Hintergrundbild für UIImageView nicht neu gezeichnet , wodurch Rechenleistung gespart wird. Dein Kommentar ergibt keinen Sinn.
Stephen Furlani
Ich mache keinen Anspruch auf die für Ihr Spiel erforderlichen FPS. Ich sage, OpenGL kann für so etwas trivialerweise 60 fps bereitstellen (man spricht bei statischen Szenen und OpenGL nicht einmal von "Redraws") - wenn Sie nur 10 fps benötigen, können Sie mit OpenGL keinen Akku für die verschwenden andere "50 Frames". Ihre Zeichenmethode ist in einer Welt mit GPU-Beschleunigung verschwenderisch. Auf einem PC ist das wahrscheinlich in Ordnung, aber nicht, wenn der Akku leer ist.
@ Joe, ich bin mir immer noch nicht sicher, was du sagst. Es zeichnet ein Bild. Dann bleibt das Bild allein, bis der Spieler eine Grenze erreicht, und zeichnet dann ein neues Bild. Wie verschwendet das die Batterielebensdauer? Es wird nur bei Bedarf "gezeichnet" und der Rest der Zeit wird die Ansicht mit dem nativen Zeichnungsalgorithmus von UIImageView gezeichnet.
Stephen Furlani