Je suis en train de coder ma finale pour un cours de programmation de jeux vidéo et je veux savoir comment créer un fichier de sauvegarde pour mon jeu afin qu'un utilisateur puisse y jouer, puis y revenir plus tard. Toute idée de la façon dont cela est fait, tout ce que j'ai fait auparavant a été des programmes à exécution unique.
c++
savegame
serialization
Tucker Morgan
la source
la source
Réponses:
Vous devez utiliser la sérialisation pour enregistrer vos variables en mémoire sur votre disque dur. Il existe de nombreux types de sérialisation. Le format .NET XML est un format courant, bien que des sérialiseurs binaires et JSON soient disponibles. Je ne suis pas un grand programmeur C ++, mais une recherche rapide a donné un exemple de sérialisation en C ++:
Il existe des bibliothèques offrant des fonctionnalités de sérialisation. Certains sont mentionnés dans d'autres réponses.
Les variables qui vous intéresseront vont probablement être liées à l’état du jeu. Par exemple, vous voudrez probablement connaître ce type d’information
Vous ne vous soucierez pas vraiment des textures utilisées (sauf si votre joueur peut changer leur apparence, c'est un cas particulier), car elles sont généralement les mêmes. Vous devez vous concentrer sur la sauvegarde des données de jeu importantes.
Lorsque vous démarrez votre jeu, vous commencez normalement pour un "nouveau" jeu (cela charge vos textures, modèles, etc.), mais au moment opportun, vous chargez les valeurs de votre fichier de sauvegarde dans l'objet d'état du jeu en remplaçant le "par défaut" nouveau état du jeu. Ensuite, vous autorisez le joueur à reprendre la lecture.
Je l'ai grandement simplifié ici, mais vous devriez avoir une idée générale. Si vous avez une question plus spécifique, posez-en une nouvelle ici et nous pouvons essayer de vous aider.
la source
En règle générale, cela est spécifique à votre jeu. Je suis sûr que vous avez appris à écrire et à lire des fichiers dans vos classes jusqu'à présent. L'idée de base est:
Ce que vous écrivez dépend de vous, cela dépend de votre jeu. Une façon d'écrire consiste à écrire les variables souhaitées dans un ordre spécifique sous forme de flux d'octets. Puis, lors du chargement, lisez-les dans votre programme dans le même ordre.
Par exemple (en pseudo code rapide):
la source
Il existe probablement de nombreuses façons de le faire, mais le plus simple que j'ai toujours trouvé et utilisé personnellement et professionnellement consiste à créer une structure contenant toutes les valeurs que je souhaite sauvegarder.
Je viens alors de fwrite / fread les données vers et depuis un fichier en utilisant les valeurs de base File IO. InventoryCount est le nombre de structures Item qui sont enregistrées après la structure SaveGameData principale dans le fichier. Par conséquent, je sais combien de celles-ci doivent être lues après l'extraction de ces données. La clé ici est que lorsque je veux enregistrer quelque chose de nouveau, à moins que ce ne soit une liste d’articles ou tout autre objet similaire, tout ce que j’ai à faire est d’ajouter une valeur à la structure quelque part. Si c'est une liste d'éléments, je devrai ajouter une lecture, comme je l'ai déjà indiqué pour les objets Article, un compteur dans l'en-tête principal, puis les entrées.
Cela présente l'inconvénient de rendre différentes versions d'un fichier de sauvegarde incompatibles les unes des autres sans traitement spécial (même s'il ne s'agit que de valeurs par défaut pour chaque entrée de la structure principale). Mais dans l’ensemble, cela rend le système facile à étendre en ajoutant simplement une nouvelle valeur de données et en y ajoutant une valeur en cas de besoin.
Encore une fois, de nombreuses façons de faire ceci et cela pourraient mener davantage au C que au C ++, mais le travail est fait!
la source
Vous devez d’abord décider quelles données doivent être sauvegardées. Par exemple, cela pourrait être l'emplacement du personnage, son score et le nombre de pièces. Bien entendu, votre jeu sera probablement beaucoup plus complexe et vous devrez donc sauvegarder des données supplémentaires telles que le numéro de niveau et la liste des ennemis.
Ensuite, écrivez le code pour enregistrer cela dans un fichier (utilisation destream). Un format relativement simple que vous pouvez utiliser est le suivant:
Et le fichier ressemblerait à ceci:
Ce qui voudrait dire qu'il était à la position (14, 96) avec un score de 4200 et 100 pièces.
Vous devez également écrire du code pour charger ce fichier (utilisez ifstream).
La sauvegarde des ennemis peut se faire en incluant leur position dans le fichier. Nous pouvons utiliser ce format:
Tout d'abord,
number_of_enemies
on lit et ensuite chaque position est lue avec une simple boucle.la source
Une addition / suggestion serait d’ajouter un niveau de cryptage à votre sérialisation afin que les utilisateurs ne puissent pas éditer leur valeur au format texte en "9999999999999999999". Une bonne raison de le faire serait d'éviter les débordements d'entiers (par exemple).
la source
Je pense que votre meilleur pari est boost :: serialization car il est facile de se propager dans votre hiérarchie. Il vous suffit d'appeler la fonction de sauvegarde / chargement de l'objet supérieur et toutes vos classes sont facilement créées.
Voir: http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html
la source
Par souci d'exhaustivité, je veux mentionner une bibliothèque de sérialisation c ++, que j'utilise personnellement et qui n'a pas encore été mentionnée: céréales .
Il est facile à utiliser et possède une syntaxe propre et élégante pour la sérialisation. Il propose également plusieurs types de formats dans lesquels vous pouvez enregistrer (XML, Json, Binary (y compris une version portable respectueuse de l'environnement)). Il supporte l'héritage et est seulement en-tête,
la source
Votre jeu va compromettre les structures de données (espérons-le?) Que vous devez transformer en octets (sérialiser) afin que vous puissiez les stocker. Dans le futur, vous pourrez ré-charger ces octets et les reconvertir dans votre structure d'origine (désérialisation). En C ++, ce n’est pas si compliqué, car la réflexion est très limitée. Mais encore, certaines bibliothèques peuvent vous aider ici. J'ai écrit un article à ce sujet: https://rubentorresbonet.wordpress.com/2014/08/25/an-overview-of-data-serialization-techniques-in-c/ En gros, je vous suggère de jeter un coup d'œil à bibliothèque de céréales si vous pouvez cibler les compilateurs C ++ 11. Pas besoin de créer des fichiers intermédiaires comme avec protobuf, vous gagnerez du temps si vous voulez des résultats rapides. Vous pouvez également choisir entre binaire et JSON, cela peut donc aider au débogage ici.
De plus, si la sécurité vous préoccupe, vous souhaiterez peut-être chiffrer / déchiffrer les données que vous stockez, en particulier si vous utilisez des formats lisibles par l'homme tels que JSON. Des algorithmes comme AES sont utiles ici.
la source
Vous devez utiliser
fstream
pour les fichiers d'entrée / sortie. La syntaxe est simple EX:Ou
D'autres actions sont possibles sur votre fichier: append , binary , trunc , etc. Vous utiliseriez la même syntaxe que celle décrite ci-dessus à la place de std :: ios: :( flags), par exemple:
ios::out
pour l'opération de sortieios::in
pour l'opération d'entréeios::binary
pour opération IO binaire (octet brut), au lieu de caractèresios::app
pour commencer à écrire à la fin du fichierios::trunc
car si le fichier existe déjà, remplacez l'ancien contenu et remplacez par nouveauios::ate
- positionne le pointeur de fichier "à la fin" pour les entrées / sortiesEx:
Voici un exemple plus complet mais simple.
la source
goto
s, vous serez lynché sur la place publique. Ne pas utilisergoto
s.