Comment enregistrez-vous l'état du jeu?

27

Quelle est la procédure suivie par les programmeurs de jeux pour enregistrer et reprendre l'état du jeu? comme les fichiers / mappages. Je veux l'enregistrer pour le jeu de tower defense et j'utilise le moteur de jeu Unity3D.

Syed
la source

Réponses:

16

En général, je ne pense pas en termes d'instantané de mémoire, mais je fais plutôt une liste des valeurs qui doivent être enregistrées entre les sessions et enregistrez ces valeurs dans un fichier externe.

Cela dépend bien sûr des besoins de votre jeu spécifique, mais généralement, je sauvegarde simplement l'état du niveau actuel (c'est-à-dire où se trouvent tous les ennemis, quelle est leur santé, etc.), puis des éléments de niveau supérieur comme les niveaux du joueur est déjà terminée.

jhocking
la source
3
+1 C'est comme ça que je le fais. J'écris ce dont j'ai besoin dans un fichier binaire. Et, si j'ai besoin d'ajouter quelque chose de nouveau, je l'ajoute à la fin pour ne pas casser les anciens fichiers de sauvegarde.
chaosTechnician
C'est une bonne astuce pour ne pas casser les anciens fichiers de sauvegarde, bien que l'ajout de données à la fin ne soit pas pertinent pour la façon dont j'enregistre les données. Je le fais en sérialisant / désérialisant un dictionnaire, et l'ordre n'est pas pertinent dans cette structure de données.
jhocking
(en gros, le code dans la réponse de
Jonas
10

Cette réponse est spécifique à Unity3d .
Dans Unity, la plupart des classes sont sérialisables, ce qui signifie que vous pouvez diffuser des objets Unity complets sur le disque. Le code UnityScript suivant est un moyen de sérialiser un objet, de l'enregistrer sur le disque et de le charger à nouveau (après le chargement, vous devez convertir l'objet):

import System;
import System.IO;
import System.IO.Stream;
import System.Runtime.Serialization;
import System.Runtime.Serialization.Formatters.Binary;

class SaveLoad {
        public static function SaveFile(filename:String, obj:Object):void {
                try {
                        Debug.Log("Writing Stream to Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Create);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        formatter.Serialize(fileStream, obj);
                        fileStream.Close();
                } catch(e:Exception) {
                        Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.ToString() + ")");
                }
        }

        public static function LoadFile(filename:String):Object {
                try {
                        Debug.Log("Reading Stream from Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Open, FileAccess.Read);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        var obj:Object= formatter.Deserialize(fileStream);
                        fileStream.Close();
                        return obj;
                } catch(e:Exception) {
                        Debug.LogWarning("SaveLoad.LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.ToString() + ")");
                        return null;
                }       
        }
}
Jonas
la source
2
Outre l'utilisation de C #, vous souhaitez également utiliser PlayerPrefs. Ils sont multi-plateformes, vous ne pouvez pas faire d'E / S sur le Web / iOS / Android. Unity3d.com/support/documentation/ScriptReference/… (bel échantillon cependant!)
TJHeuvel
PlayerPrefs sont beaucoup moins flexibles, ils sont en effet multiplateformes et ils sont parfaits pour stocker des valeurs uniques ou non liées. Mais sur Windows PlayerPrefs sont stockés dans le registre, en clair.
jonas
7
Si vous sérialisez déjà, pourquoi ne pas le sérialiser dans une chaîne et le stocker dans PlayerPrefs. Bien sûr, il est moins flexible, mais c'est à peu près la seule solution pour un jeu multiplateforme.
TJHeuvel
2
PlayerPrefs est idéal pour stocker de petites données comme les paramètres, mais pour des sauvegardes entières, vous devez utiliser Application.persistentDataPath docs.unity3d.com/ScriptReference/…
jhocking
2
@TJHeuvel: "vous ne pouvez pas faire d'E / S sur le Web / iOS / Android" Vous pouvez certainement faire des E / S sur mobile
Przemysław Wrzesiński
2

Pour un TD, j'économiserais probablement exclusivement entre les vagues. De cette façon, vous n'avez qu'à penser aux tours. Mettez des points de sauvegarde automatique dans les niveaux, pas plus de 10 minutes entre, mais moins est probablement préférable.

Bien sûr, si vos niveaux sont suffisamment courts, vous ne pouvez tout simplement enregistrer que le statut de la campagne.

aaaaaaaaaaaa
la source
1

Lorsque je fais référence à l'état actuel du jeu, je fais référence à l'instantané de la mémoire au moment de la sauvegarde. Vous devez être en mesure de recréer cela à partir des données que vous allez stocker sur votre disque dur.

Il est plus simple de sérialiser toutes vos classes qui ont des données qui doivent être persistantes et de les vider sur le disque dur, en effectuant essentiellement un vidage de la mémoire. Le problème est que la modification de vos classes changera le nombre / types de valeurs sérialisées et rompra les anciennes sauvegardes. De plus, parce que vous enregistrez tout, cela augmente les temps de chargement. Il est plus efficace de marquer les champs individuels qui sont réellement nécessaires pour reconstruire l '"instantané de mémoire" actuel avec le système d'attributs utilisé par votre sérialiseur / IDE. Reconstruisez ensuite l '"instantané de mémoire" à partir de ces données enregistrées.

De plus, je n'ai jamais utilisé Unity auparavant, il peut donc y avoir quelque chose de intégré. Cependant, c'est l'approche typique.

ClassicThunder
la source
tu veux dire que je dois stocker mes états dans un fichier?
Syed
1
@Syed oui, à la fin de la journée, il doit être écrit dans un fichier, car l'état de l'application ne sera pas enregistré en mémoire. Avec Unity en particulier, vous pouvez utiliser la classe PlayerPrefs (qui, je pense, stocke en fait des choses dans le registre sous Windows) si vous voulez éviter tout le fichier en lecture / écriture.
Tetrad