Création d'un système Sauvegarde/Chargement
Proposé par bestben

le lundi 31 mars 2008 à 22h 20mn 05s

5593 visualisations



Bonjours
Dans ce tuto je vais abordé les système de sauvegarde/chargement,
je sait que le temps est beaucoup au mmorpg/fps en ligne mais pouvoir sauvegarder des informations est toujours utile.
Un "gestionnaire" de fichier existe dans irrlicht mais j'utiliserai directement du c++ grâce à fstream qui pourra sur un long terme vous permettre de faire plus de choses je pense.
ATTENTION  je ne vais pas vous montrer un système ultra perfectionné qui vous sauvegarde tout votre jeux mais des bases pouvant vous aider :

Système de sauvegarde :
bon il va se composer des 2 fichiers Sauvegarde.cpp et Sauvegarde.h

Code:

//Sauvegarde.h

#ifndef DEF_SAVE
#define DEF_SAVE

#include <iostream>
#include <irrlicht.h>
#include <fstream>

class Sauvegarde
{
    public:
    Sauvegarde(char* fichier, irr::scene::ICameraSceneNode* camerafps, std::string Nom, int Vie);
    ~Sauvegarde();
    void Save();

    private:
    irr::scene::ICameraSceneNode* m_camerafps;
    char* m_fichier;
    irr::core::vector3df posCam;
    int m_Vie;
    std::string m_Nom;
};

#endif

bon pour l'instant rien de très difficile

Code:

//Sauvegarde.cpp
#include "Sauvegarde.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std;

Sauvegarde::Sauvegarde(char* fichier, irr::scene::ICameraSceneNode* camerafps, std::string Nom, int Vie)
{
    m_fichier = fichier;
    m_camerafps = camerafps;
    m_Nom = Nom;
    m_Vie = Vie;
}

Sauvegarde::~Sauvegarde();

void Sauvegarde::Save()
{
        if(m_fichier && m_camerafps)
        {
        posCam = m_camerafps->getPosition();
        ofstream sauvegarde(fichier, ios::out | ios::trunc);
        if(sauvegarde)
        {
           sauvegarde << "Pos X,Y,Z" << "\n" << posCam.X << "\n" << posCam.Y << "\n" << posCam.Z << "\n" << endl;
           sauvegarde << "Perso" << "\n" << m_vie << "\n" << m_nom  << endl;
        }
        sauvegarde.close();
        }
}

voilà le système de sauvegarde est fini il ne vous reste plus qu'à déclarer votre objet dans votre main() et d'appeler
Sauvegarde(char* fichier, irr::scene::ICameraSceneNode* camerafps, std::string Nom, int Vie)

si vous voyez des erreurs ou des améliorations n'hésitez pas à les faire partager lol

Prochaines étapes le chargement =>


#1 

31-03-2008 22:52:51

bestben
Abonné
Date d'inscription: 20-10-2007
Messages: 133

Bon le plus dur reste à faire : le chargement
tout comme la sauvegarde, 2 fichiers -> Chargement.cpp et Chargement.h

Code:

//Chargement.h
#include <iostream>
#include <Irrlicht.h>
#include <string>
#include <sstream>
#include <fstream>

class Chargement
{
  public:
  Chargement(char* Fichier, irr::scene::ICameraSceneNode* camerafps, int Vie, std::string Nom);
  ~Chargement();
  void ChargePos();
  void ChargePerso();

  private:
  void ChargeNumb(int num, int *Coord);
  irr::scene::ICameraSceneNode* m_camerafps;
  char* m_Fichier;
  long nombreLignes, numX, numY, numZ, numNom, numVie;
  int caractereLu;
  std::string StringNumb;
  std::string m_Nom;
  char caractere;
  int x, y, z, Coo;
  int m_Vie;
};

Bon je pense que le code n'à pour le moment pas besoin d'être expliquer, vous comprendrez toutes les variables dans Chargement.cpp qui arrive.

Code:

//chargement.cpp

#include "Chargement.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std;

Chargement::Chargement(char* Fichier, irr::scene::ICameraSceneNode* camerafps, int Vie, std::string Nom)
{
    m_Fichier = Fichier;
    m_camerafps = camerafps;
    m_Vie = Vie;
    m_Nom = Nom;
    int caractereLu = 0;
    char caractere; 
};

Chargement::~Chargement();

void Chargement::ChargePos()
{
    x = 0; y = 0; z = 0;
    m_Fichier = "Save/Player.irrSave";
    nombreLignes = 0;
    numX = 1; numY = 2; numZ = 3;
    ChargeNumb(numX, &x);
    ChargeNumb(numY, &y);
    ChargeNumb(numZ, &z);
    m_camerafps->setPosition(vector3df(x,y,z));
};

void ChargeNumb(int num, int *Coord)
{
ifstream FFichier(m_Fichier, ios::in | ios::binary);
if(FFichier)
{
FFichier.seekg(0, ios::beg);
while (num > 0)
{
    FFichier.get(caractere);
    caractereLu = caractere;
    if (caractereLu == '\n')
        num--;
}
getline(Fichier, StringNumb);
    
std::istringstream streamNumb(StringNumb);
streamNumb >> Coo;
*Coord = Coo;
if (streamNumb.fail()==true)
{
 std::cout << "fail" << std::endl;
};
streamNumb.clear();
StringNumb.clear();
FFichier.close();
}
};

void Chargement::ChargePerso()
{
    nombreLignes = 0; numNom = 6; numVie = 7;
    LoadNumb(numVie, &m_Vie);
    ifstream FichierPerso(m_Fichier, ios::in | ios::binary);
    if(Fichier)
    {
    FichierPerso.seekg(0, ios::beg);
    while (numNom > 0)
    {
        FichierPerso.get(caractere);
        caractereLu = caractere;
        if (caractereLu == '\n')
            numNom--;
    }
    getline(FichierPerso, m_Nom);
    Fichier.close();
    };
    
};

Bon quand vous voyez ça vous vous dîtes beaucoup de lignes pour juste récupérer 3 nombres, mais la difficulté est qu'avec fstream on ne peut récupérer que des string donc 
il faut ensuite convertir ses string en int pour pouvoir les envoyer à la Cam

Code:

    FFichier.seekg(0, ios::beg);
    while (num > 0)
    {
        FFichier.get(caractere);
        caractereLu = caractere;
        if (caractereLu == '\n')
            num--;
    }
    getline(Fichier, StringNumb);

donc là on ce place au début du fichier grâce à seekg puis on met une boucle qui s'applique tant que num > à 0       
FFichier.get(caractere); et caractereLu = caractere; servent à se déplacer d'un caractère  à chaque passage de la boucle et si le caractère est = à \n num est diminuer de 1
puis on récupère la ligne entière grâce à getline 
voilà on a récupéré 1 string contenant notre nombre

Code:

std::istringstream streamNumb(StringNumb);
streamNumb >> Coo;
if (streamNumb.fail()==true)
{
 std::cout << "fail" << std::endl;
};

Là je ne peut pas vous expliquer vraiment le fonctionnement de ceci mais en gros on déclare streamNumb puis grâce aux flux on convertit la string en int
streamNumb.fail() sert à nous avertir si la string n'est pas composée de nombres

Enfin on donne les coordonnées à notre Cam
m_camerafps->setPosition(vector3df(x,y,z));

Si vous trouvez des erreurs n'oubliez pas de me le signaler

Dernière modification par bestben (22-02-2009 01:47:59)

Hors ligne


#2 

11-05-2008 12:46:55

hardcpp
Abonné
Date d'inscription: 26-04-2008
Messages: 229

merci beaucou

Hors ligne


#3 

11-05-2008 14:36:50

bestben
Abonné
Date d'inscription: 20-10-2007
Messages: 133

ya pas de quoi si sa peut servir

Hors ligne


#4 

24-06-2008 11:25:29

BooBs
Petit nouveau
Date d'inscription: 24-06-2008
Messages: 8

Merci beaucoup c'est tres utile !!

Hors ligne


#5 

18-11-2012 19:12:21

OzVessalius
Petit nouveau
Date d'inscription: 18-11-2012
Messages: 8

Je veux pas troller, mais, ça existe Boost.Serialization, et c'est 1000x plus simple que ça.

Hors ligne


#6 

18-11-2012 20:38:22

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

c'est toujours intéressant sur la plan du code déjà, voir instructif pour certains.
De plus, cela a quand même plus de ...4 ans....


Force et sagesse...

Hors ligne


#7 

18-11-2012 20:40:33

OzVessalius
Petit nouveau
Date d'inscription: 18-11-2012
Messages: 8

Ça peut être toujours utile pour certains.
Sur le plan du code, je suis d'accord, mais dans ce cas autant montrer la sérialisation binaire et tout.
Désolé, pour le remontage ^^

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
Analysé par
872 membres
1422 sujets
11104 messages
Dernier membre inscrit: Glider
17 invités en ligne
Aucun membre connecté
RSS Feed