Ich programmiere gerade mein Finale für einen Videospiel-Programmierkurs und möchte wissen, wie ich eine Speicherdatei für mein Spiel erstelle, damit ein Benutzer spielen und später wiederkommen kann. Jede Idee, wie das gemacht wird, alles, was ich vorher gemacht habe, waren Single-Run-Programme.
c++
savegame
serialization
Tucker Morgan
quelle
quelle
Antworten:
Sie müssen die Serialisierung verwenden , um Ihre Variablen im Speicher auf Ihrer Festplatte zu speichern. Es gibt viele Arten der Serialisierung. In .NET ist XML ein verbreitetes Format, obwohl Binär- und JSON-Serialisierer verfügbar sind. Ich bin kein großer C ++ - Programmierer, aber eine schnelle Suche ergab ein Beispiel für die Serialisierung in C ++:
Es gibt Bibliotheken, die Serialisierungsfunktionen anbieten. Einige werden in anderen Antworten erwähnt.
Die Variablen, die Sie interessieren werden, werden wahrscheinlich mit dem Spielstatus zusammenhängen. Beispielsweise möchten Sie wahrscheinlich diese Art von Informationen kennen
Es ist dir egal, welche Texturen verwendet werden (es sei denn, dein Player kann sein Aussehen ändern, das ist ein Sonderfall), da sie normalerweise gleich sind. Sie müssen sich darauf konzentrieren, wichtige Gamestate-Daten zu speichern.
Wenn Sie Ihr Spiel starten, starten Sie wie gewohnt für ein "neues" Spiel (dies lädt Ihre Texturen, Modelle usw.), aber zu gegebener Zeit laden Sie die Werte aus Ihrer Speicherdatei zurück in das Spielstatusobjekt und ersetzen das "Standard" -Neu Spielstatus. Dann erlauben Sie dem Spieler, das Spiel fortzusetzen.
Ich habe es hier stark vereinfacht, aber Sie sollten sich einen Überblick verschaffen. Wenn Sie eine spezifischere Frage haben, stellen Sie hier eine neue Frage, und wir können versuchen, Ihnen dabei zu helfen.
quelle
Normalerweise ist dies für Ihr Spiel spezifisch. Ich bin sicher, Sie haben bisher in Ihren Klassen gelernt, in Dateien zu schreiben und daraus zu lesen. Die Grundidee ist:
Was du schreibst, liegt bei dir, es hängt von deinem Spiel ab. Eine Möglichkeit zum Schreiben besteht darin, die gewünschten Variablen in einer bestimmten Reihenfolge als Byte-Stream zu schreiben. Lesen Sie sie dann beim Laden in der gleichen Reihenfolge in Ihr Programm ein.
Zum Beispiel (in schnellem Pseudocode):
quelle
Es gibt wahrscheinlich eine Vielzahl von Möglichkeiten, dies zu tun, aber das Einfachste, was ich persönlich und beruflich immer gefunden und angewendet habe, ist, eine Struktur zu erstellen, die alle Werte enthält, die ich speichern möchte.
Ich schreibe / verteile dann einfach die Daten in und aus einer Datei unter Verwendung der grundlegenden Datei-E / A-Werte. Die Inventaranzahl ist die Anzahl der Artikelstrukturen, die nach der SaveGameData-Hauptstruktur in der Datei gespeichert werden, sodass ich weiß, wie viele davon nach dem Abrufen dieser Daten gelesen werden müssen. Der Schlüssel hier ist, dass wenn ich etwas Neues speichern möchte, es sei denn, es handelt sich um eine Liste von Elementen oder dergleichen, alles, was ich jemals tun musste, ist, der Struktur irgendwo einen Wert hinzuzufügen. Wenn es sich um eine Liste von Elementen handelt, muss ich einen Lesezugriff hinzufügen, wie ich es bereits für die Elementobjekte impliziert habe, einen Zähler im Hauptkopf und dann die Einträge.
Dies hat den Nachteil, dass verschiedene Versionen einer Sicherungsdatei ohne besondere Behandlung inkompatibel sind (auch wenn es sich nur um Standardwerte für jeden Eintrag in der Hauptstruktur handelt). Insgesamt lässt sich das System jedoch problemlos erweitern, indem lediglich ein neuer Datenwert hinzugefügt und bei Bedarf ein Wert hinzugefügt wird.
Auch hier gibt es einige Möglichkeiten, um dies zu tun, und dies könnte mehr zu C als zu C ++ führen, aber es hat die Arbeit erledigt!
quelle
Zuerst müssen Sie entscheiden, welche Daten gespeichert werden sollen. Dies kann zum Beispiel die Position des Charakters, seine Punktzahl und die Anzahl der Münzen sein. Natürlich wird Ihr Spiel wahrscheinlich viel komplexer und Sie müssen zusätzliche Daten wie die Levelnummer und die Feindliste speichern.
Als nächstes schreiben Sie Code, um dies in eine Datei zu speichern (Verwendung von Stream). Ein relativ einfaches Format, das Sie verwenden können, lautet wie folgt:
Und so würde die Datei aussehen:
Das würde bedeuten, dass er mit einer Punktzahl von 4200 und 100 Münzen auf Position (14, 96) war.
Sie müssen auch Code schreiben, um diese Datei zu laden (verwenden Sie ifstream).
Das Speichern von Feinden kann durch Einfügen ihrer Position in die Datei erfolgen. Wir können dieses Format verwenden:
Zuerst
number_of_enemies
wird gelesen und dann wird jede Position mit einer einfachen Schleife gelesen.quelle
Ein Zusatz / Vorschlag wäre, Ihrer Serialisierung eine Verschlüsselungsstufe hinzuzufügen, damit Benutzer ihre Werte nicht in "99999999999999999" als Text bearbeiten können. Ein guter Grund, dies zu tun, wäre, beispielsweise Ganzzahlüberläufe zu verhindern.
quelle
Ich denke, Ihre beste Wahl ist boost :: serialization, weil es einfach ist, sich in Ihrer Hierarchie zu verbreiten. Sie müssen nur die Speicher- / Ladefunktion des obersten Objekts aufrufen, und alle Ihre Klassen können problemlos erstellt werden.
Siehe: http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html
quelle
Der Vollständigkeit halber möchte ich eine c ++ - Serialisierungsbibliothek erwähnen, die ich persönlich benutze und die noch nicht erwähnt wurde: Getreide .
Es ist einfach zu bedienen und hat eine schöne, saubere Syntax für die Serialisierung. Es bietet auch mehrere Arten von Formaten, die Sie speichern können (XML, Json, Binary (einschließlich einer portablen Version mit Respekt vor Endianess)). Es unterstützt die Vererbung und ist nur für den Header bestimmt.
quelle
Ihr Spiel wird Datenstrukturen gefährden (hoffentlich?), Die Sie in Bytes umwandeln müssen (serialisieren), damit Sie sie speichern können. In Zukunft können Sie diese Bytes wieder laden und in Ihre ursprüngliche Struktur zurückverwandeln (Deserialisierung). In C ++ ist es nicht so schwierig, da die Reflektion sehr begrenzt ist. Dennoch können Ihnen einige Bibliotheken hier weiterhelfen. Ich habe einen Artikel darüber geschrieben: https://rubentorresbonet.wordpress.com/2014/08/25/an-overview-of-data-serialization-techniques-in-c/ Grundsätzlich empfehle ich Ihnen einen Blick darauf zu werfen Getreidebibliothek, wenn Sie C ++ 11-Compiler als Ziel haben. Es müssen keine Zwischendateien wie mit protobuf erstellt werden, sodass Sie dort Zeit sparen, wenn Sie schnelle Ergebnisse erzielen möchten. Sie können auch zwischen Binär- und JSON-Dateien wählen, um hier das Debuggen zu vereinfachen.
Wenn die Sicherheit ein Problem darstellt, möchten Sie möglicherweise die gespeicherten Daten verschlüsseln / entschlüsseln, insbesondere wenn Sie für Menschen lesbare Formate wie JSON verwenden. Algorithmen wie AES sind hier hilfreich.
quelle
Sie müssen
fstream
für Ein- / Ausgabedateien verwenden. Die Syntax ist einfach EX:Oder
Andere Aktionen sind für Ihre Datei möglich: Anhängen , Binär , Abschneiden usw. Sie würden die gleiche Syntax wie oben verwenden, stattdessen setzen wir std :: ios: :( Flags), zum Beispiel:
ios::out
für den Ausgabebetriebios::in
für den Eingabebetriebios::binary
für binären (Rohbyte-) E / A-Betrieb statt zeichenbasiertios::app
um mit dem Schreiben am Ende der Datei zu beginnenios::trunc
Wenn die Datei bereits vorhanden ist, ersetzen Sie den alten Inhalt und ersetzen Sie ihn durch neuenios::ate
- Positionieren Sie den Dateizeiger "am Ende" für die Ein- / AusgabeEx:
Hier ist ein vollständigeres, aber einfaches Beispiel.
quelle
goto
s verwenden, werden Sie auf dem öffentlichen Platz gelyncht. Verwenden Sie nichtgoto
s.