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.
quelle
Antworten:
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).
quelle
Persönlich würde ich die Karte mit einem bestimmten Kachel-Editor wie TileEd erstellen . Dieser Ansatz bietet mehrere Vorteile:
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
Sprite
Klasse ansehen oder dieCopy
Funktion derImage
Klasse verwenden.Update: Ich habe gerade einige der SFML-Dokumente gelesen und Sie sollten auf jeden Fall
Drawable
oder 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.quelle
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.
quelle
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/
quelle
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.
quelle