Sophie

Sophie

distrib > Mageia > 6 > armv5tl > media > core-updates > by-pkgid > 768f7d9f703884aa2562bf0a651086df > files > 743

qtbase5-doc-5.9.4-1.1.mga6.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- savegame.qdoc -->
  <title>JSON Save Game Example | Qt Core 5.9</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td >Qt 5.9</td><td ><a href="qtcore-index.html">Qt Core</a></td><td >JSON Save Game Example</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right">Qt 5.9.4 Reference Documentation</td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#the-character-class">The Character Class</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">JSON Save Game Example</h1>
<span class="subtitle"></span>
<!-- $$$json/savegame-description -->
<div class="descr"> <a name="details"></a>
<p>Many games provide save functionality, so that the player's progress through the game can be saved and loaded at a later time. The process of saving a game generally involves serializing each game object's member variables to a file. Many formats can be used for this purpose, one of which is JSON. With <a href="qjsondocument.html">QJsonDocument</a>, you also have the ability to serialize a document in a binary format, which is great if you don't want the save file to be readable, or if you need to keep the file size down.</p>
<p>In this example, we'll demonstrate how to save and load a simple game to and from JSON and binary formats.</p>
<a name="the-character-class"></a>
<h2 id="the-character-class">The Character Class</h2>
<p>The Character class represents a non-player character (NPC) in our game, and stores the player's name, level, and class type.</p>
<p>It provides read() and write() functions to serialise its member variables.</p>
<pre class="cpp">

  <span class="keyword">class</span> Character
  {
  <span class="keyword">public</span>:
      <span class="keyword">enum</span> ClassType {
          Warrior<span class="operator">,</span> Mage<span class="operator">,</span> Archer
      };

      Character();
      Character(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>name<span class="operator">,</span> <span class="type">int</span> level<span class="operator">,</span> ClassType classType);

      <span class="type"><a href="qstring.html">QString</a></span> name() <span class="keyword">const</span>;
      <span class="type">void</span> setName(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>name);

      <span class="type">int</span> level() <span class="keyword">const</span>;
      <span class="type">void</span> setLevel(<span class="type">int</span> level);

      ClassType classType() <span class="keyword">const</span>;
      <span class="type">void</span> setClassType(ClassType classType);

      <span class="type">void</span> read(<span class="keyword">const</span> <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json);
      <span class="type">void</span> write(<span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json) <span class="keyword">const</span>;
  <span class="keyword">private</span>:
      <span class="type"><a href="qstring.html">QString</a></span> mName;
      <span class="type">int</span> mLevel;
      ClassType mClassType;
  };

</pre>
<p>Of particular interest to us are the read and write function implementations:</p>
<pre class="cpp">

  <span class="type">void</span> Character<span class="operator">::</span>read(<span class="keyword">const</span> <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json)
  {
      mName <span class="operator">=</span> json<span class="operator">[</span><span class="string">&quot;name&quot;</span><span class="operator">]</span><span class="operator">.</span>toString();
      mLevel <span class="operator">=</span> json<span class="operator">[</span><span class="string">&quot;level&quot;</span><span class="operator">]</span><span class="operator">.</span>toDouble();
      mClassType <span class="operator">=</span> ClassType(<a href="qfloat16.html#qRound">qRound</a>(json<span class="operator">[</span><span class="string">&quot;classType&quot;</span><span class="operator">]</span><span class="operator">.</span>toDouble()));
  }

</pre>
<p>In the read() function, we assign Character's members values from the <a href="qjsonobject.html">QJsonObject</a> argument. You can use either <a href="qjsonobject.html#operator-5b-5d">QJsonObject::operator[]</a>() or <a href="qjsonobject.html#value">QJsonObject::value</a>() to access values within the JSON object; both are const functions and return <a href="qjsonvalue.html#Type-enum">QJsonValue::Undefined</a> if the key is invalid. We could check if the keys are valid before attempting to read them with <a href="qjsonobject.html#contains">QJsonObject::contains</a>(), but we assume that they are.</p>
<pre class="cpp">

  <span class="type">void</span> Character<span class="operator">::</span>write(<span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json) <span class="keyword">const</span>
  {
      json<span class="operator">[</span><span class="string">&quot;name&quot;</span><span class="operator">]</span> <span class="operator">=</span> mName;
      json<span class="operator">[</span><span class="string">&quot;level&quot;</span><span class="operator">]</span> <span class="operator">=</span> mLevel;
      json<span class="operator">[</span><span class="string">&quot;classType&quot;</span><span class="operator">]</span> <span class="operator">=</span> mClassType;
  }

</pre>
<p>In the write() function, we do the reverse of the read() function; assign values from the Character object to the JSON object. As with accessing values, there are two ways to set values on a <a href="qjsonobject.html">QJsonObject</a>: <a href="qjsonobject.html#operator-5b-5d">QJsonObject::operator[]</a>() and <a href="qjsonobject.html#insert">QJsonObject::insert</a>(). Both will override any existing value at the given key.</p>
<p>Next up is the Level class:</p>
<pre class="cpp">

  <span class="keyword">class</span> Level
  {
  <span class="keyword">public</span>:
      Level();

      <span class="keyword">const</span> <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Character<span class="operator">&gt;</span> <span class="operator">&amp;</span>npcs() <span class="keyword">const</span>;
      <span class="type">void</span> setNpcs(<span class="keyword">const</span> <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Character<span class="operator">&gt;</span> <span class="operator">&amp;</span>npcs);

      <span class="type">void</span> read(<span class="keyword">const</span> <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json);
      <span class="type">void</span> write(<span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json) <span class="keyword">const</span>;
  <span class="keyword">private</span>:
      <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Character<span class="operator">&gt;</span> mNpcs;
  };

</pre>
<p>We want to have several levels in our game, each with several NPCs, so we keep a <a href="qlist.html">QList</a> of Character objects. We also provide the familiar read() and write() functions.</p>
<pre class="cpp">

  <span class="type">void</span> Level<span class="operator">::</span>read(<span class="keyword">const</span> <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json)
  {
      mNpcs<span class="operator">.</span>clear();
      <span class="type"><a href="qjsonarray.html">QJsonArray</a></span> npcArray <span class="operator">=</span> json<span class="operator">[</span><span class="string">&quot;npcs&quot;</span><span class="operator">]</span><span class="operator">.</span>toArray();
      <span class="keyword">for</span> (<span class="type">int</span> npcIndex <span class="operator">=</span> <span class="number">0</span>; npcIndex <span class="operator">&lt;</span> npcArray<span class="operator">.</span>size(); <span class="operator">+</span><span class="operator">+</span>npcIndex) {
          <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> npcObject <span class="operator">=</span> npcArray<span class="operator">[</span>npcIndex<span class="operator">]</span><span class="operator">.</span>toObject();
          Character npc;
          npc<span class="operator">.</span>read(npcObject);
          mNpcs<span class="operator">.</span>append(npc);
      }
  }

</pre>
<p>Containers can be written and read to and from JSON using <a href="qjsonarray.html">QJsonArray</a>. In our case, we construct a <a href="qjsonarray.html">QJsonArray</a> from the value associated with the key <code>&quot;npcs&quot;</code>. Then, for each <a href="qjsonvalue.html">QJsonValue</a> element in the array, we call toObject() to get the Character's JSON object. The Character object can then read their JSON and be appended to our NPC list.</p>
<p><b>Note: </b><a href="containers.html">Associate containers</a> can be written by storing the key in each value object (if it's not already). With this approach, the container is stored as a regular array of objects, but the index of each element is used as the key to construct the container when reading it back in.</p><pre class="cpp">

  <span class="type">void</span> Level<span class="operator">::</span>write(<span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json) <span class="keyword">const</span>
  {
      <span class="type"><a href="qjsonarray.html">QJsonArray</a></span> npcArray;
      foreach (<span class="keyword">const</span> Character npc<span class="operator">,</span> mNpcs) {
          <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> npcObject;
          npc<span class="operator">.</span>write(npcObject);
          npcArray<span class="operator">.</span>append(npcObject);
      }
      json<span class="operator">[</span><span class="string">&quot;npcs&quot;</span><span class="operator">]</span> <span class="operator">=</span> npcArray;
  }

</pre>
<p>Again, the write() function is similar to the read() function, except reversed.</p>
<p>Having established the Character and Level classes, we can move on to the Game class:</p>
<pre class="cpp">

  <span class="keyword">class</span> Game
  {
  <span class="keyword">public</span>:
      Game();

      <span class="keyword">enum</span> SaveFormat {
          Json<span class="operator">,</span> Binary
      };

      <span class="keyword">const</span> Character <span class="operator">&amp;</span>player() <span class="keyword">const</span>;
      <span class="keyword">const</span> <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Level<span class="operator">&gt;</span> <span class="operator">&amp;</span>levels() <span class="keyword">const</span>;

      <span class="type">void</span> newGame();
      bool loadGame(SaveFormat saveFormat);
      bool saveGame(SaveFormat saveFormat) <span class="keyword">const</span>;

      <span class="type">void</span> read(<span class="keyword">const</span> <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json);
      <span class="type">void</span> write(<span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json) <span class="keyword">const</span>;
  <span class="keyword">private</span>:
      Character mPlayer;
      <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Level<span class="operator">&gt;</span> mLevels;
  };

</pre>
<p>First of all, we define the <code>SaveFormat</code> enum. This will allow us to specify the format in which the game should be saved: <code>Json</code> or <code>Binary</code>.</p>
<p>Next, we provide accessors for the player and levels. We then expose three functions: newGame(), saveGame() and loadGame().</p>
<p>The read() and write() functions are used by saveGame() and loadGame().</p>
<pre class="cpp">

  <span class="type">void</span> Game<span class="operator">::</span>newGame() {
      mPlayer <span class="operator">=</span> Character();
      mPlayer<span class="operator">.</span>setName(<span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;Hero&quot;</span>));
      mPlayer<span class="operator">.</span>setClassType(Character<span class="operator">::</span>Archer);
      mPlayer<span class="operator">.</span>setLevel(<span class="number">15</span>);

      mLevels<span class="operator">.</span>clear();

      Level village;
      <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Character<span class="operator">&gt;</span> villageNpcs;
      villageNpcs<span class="operator">.</span>append(Character(<span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;Barry the Blacksmith&quot;</span>)<span class="operator">,</span> <span class="number">10</span><span class="operator">,</span> Character<span class="operator">::</span>Warrior));
      villageNpcs<span class="operator">.</span>append(Character(<span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;Terry the Trader&quot;</span>)<span class="operator">,</span> <span class="number">10</span><span class="operator">,</span> Character<span class="operator">::</span>Warrior));
      village<span class="operator">.</span>setNpcs(villageNpcs);
      mLevels<span class="operator">.</span>append(village);

      Level dungeon;
      <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span>Character<span class="operator">&gt;</span> dungeonNpcs;
      dungeonNpcs<span class="operator">.</span>append(Character(<span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;Eric the Evil&quot;</span>)<span class="operator">,</span> <span class="number">20</span><span class="operator">,</span> Character<span class="operator">::</span>Mage));
      dungeonNpcs<span class="operator">.</span>append(Character(<span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;Eric's Sidekick #1&quot;</span>)<span class="operator">,</span> <span class="number">5</span><span class="operator">,</span> Character<span class="operator">::</span>Warrior));
      dungeonNpcs<span class="operator">.</span>append(Character(<span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;Eric's Sidekick #2&quot;</span>)<span class="operator">,</span> <span class="number">5</span><span class="operator">,</span> Character<span class="operator">::</span>Warrior));
      dungeon<span class="operator">.</span>setNpcs(dungeonNpcs);
      mLevels<span class="operator">.</span>append(dungeon);
  }

</pre>
<p>To setup a new game, we create the player and populate the levels and their NPCs.</p>
<pre class="cpp">

  <span class="type">void</span> Game<span class="operator">::</span>read(<span class="keyword">const</span> <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json)
  {
      mPlayer<span class="operator">.</span>read(json<span class="operator">[</span><span class="string">&quot;player&quot;</span><span class="operator">]</span><span class="operator">.</span>toObject());

      mLevels<span class="operator">.</span>clear();
      <span class="type"><a href="qjsonarray.html">QJsonArray</a></span> levelArray <span class="operator">=</span> json<span class="operator">[</span><span class="string">&quot;levels&quot;</span><span class="operator">]</span><span class="operator">.</span>toArray();
      <span class="keyword">for</span> (<span class="type">int</span> levelIndex <span class="operator">=</span> <span class="number">0</span>; levelIndex <span class="operator">&lt;</span> levelArray<span class="operator">.</span>size(); <span class="operator">+</span><span class="operator">+</span>levelIndex) {
          <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> levelObject <span class="operator">=</span> levelArray<span class="operator">[</span>levelIndex<span class="operator">]</span><span class="operator">.</span>toObject();
          Level level;
          level<span class="operator">.</span>read(levelObject);
          mLevels<span class="operator">.</span>append(level);
      }
  }

</pre>
<p>The first thing we do in the read() function is tell the player to read itself. We then clear the levels list so that calling loadGame() on the same Game object twice doesn't result in old levels hanging around.</p>
<p>We then populate the level list by reading each Level from a <a href="qjsonarray.html">QJsonArray</a>.</p>
<pre class="cpp">

  <span class="type">void</span> Game<span class="operator">::</span>write(<span class="type"><a href="qjsonobject.html">QJsonObject</a></span> <span class="operator">&amp;</span>json) <span class="keyword">const</span>
  {
      <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> playerObject;
      mPlayer<span class="operator">.</span>write(playerObject);
      json<span class="operator">[</span><span class="string">&quot;player&quot;</span><span class="operator">]</span> <span class="operator">=</span> playerObject;

      <span class="type"><a href="qjsonarray.html">QJsonArray</a></span> levelArray;
      foreach (<span class="keyword">const</span> Level level<span class="operator">,</span> mLevels) {
          <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> levelObject;
          level<span class="operator">.</span>write(levelObject);
          levelArray<span class="operator">.</span>append(levelObject);
      }
      json<span class="operator">[</span><span class="string">&quot;levels&quot;</span><span class="operator">]</span> <span class="operator">=</span> levelArray;
  }

</pre>
<p>We write the game to JSON similarly to how we write Level.</p>
<pre class="cpp">

  bool Game<span class="operator">::</span>loadGame(Game<span class="operator">::</span>SaveFormat saveFormat)
  {
      <span class="type"><a href="qfile.html">QFile</a></span> loadFile(saveFormat <span class="operator">=</span><span class="operator">=</span> Json
          <span class="operator">?</span> <span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;save.json&quot;</span>)
          : <span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;save.dat&quot;</span>));

      <span class="keyword">if</span> (<span class="operator">!</span>loadFile<span class="operator">.</span>open(<span class="type"><a href="qiodevice.html">QIODevice</a></span><span class="operator">::</span>ReadOnly)) {
          <a href="qtglobal.html#qWarning">qWarning</a>(<span class="string">&quot;Couldn't open save file.&quot;</span>);
          <span class="keyword">return</span> <span class="keyword">false</span>;
      }

      <span class="type"><a href="qbytearray.html">QByteArray</a></span> saveData <span class="operator">=</span> loadFile<span class="operator">.</span>readAll();

      <span class="type"><a href="qjsondocument.html">QJsonDocument</a></span> loadDoc(saveFormat <span class="operator">=</span><span class="operator">=</span> Json
          <span class="operator">?</span> <span class="type"><a href="qjsondocument.html">QJsonDocument</a></span><span class="operator">::</span>fromJson(saveData)
          : <span class="type"><a href="qjsondocument.html">QJsonDocument</a></span><span class="operator">::</span>fromBinaryData(saveData));

      read(loadDoc<span class="operator">.</span>object());

      <span class="keyword">return</span> <span class="keyword">true</span>;
  }

</pre>
<p>When loading a saved game in loadGame(), the first thing we do is open the save file based on which format it was saved to; <code>&quot;save.json&quot;</code> for JSON, and <code>&quot;save.dat&quot;</code> for binary. We print a warning and return <code>false</code> if the file couldn't be opened.</p>
<p>Since <a href="qjsondocument.html">QJsonDocument</a>'s <a href="qjsondocument.html#fromJson">fromJson()</a> and <a href="qjsondocument.html#fromBinaryData">fromBinaryData()</a> functions both take a <a href="qbytearray.html">QByteArray</a>, we can read the entire contents of the save file into one, regardless of the save format.</p>
<p>After constructing the <a href="qjsondocument.html">QJsonDocument</a>, we instruct the Game object to read itself and then return <code>true</code> to indicate success.</p>
<pre class="cpp">

  bool Game<span class="operator">::</span>saveGame(Game<span class="operator">::</span>SaveFormat saveFormat) <span class="keyword">const</span>
  {
      <span class="type"><a href="qfile.html">QFile</a></span> saveFile(saveFormat <span class="operator">=</span><span class="operator">=</span> Json
          <span class="operator">?</span> <span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;save.json&quot;</span>)
          : <span class="type"><a href="qstring.html#QStringLiteral">QStringLiteral</a></span>(<span class="string">&quot;save.dat&quot;</span>));

      <span class="keyword">if</span> (<span class="operator">!</span>saveFile<span class="operator">.</span>open(<span class="type"><a href="qiodevice.html">QIODevice</a></span><span class="operator">::</span>WriteOnly)) {
          <a href="qtglobal.html#qWarning">qWarning</a>(<span class="string">&quot;Couldn't open save file.&quot;</span>);
          <span class="keyword">return</span> <span class="keyword">false</span>;
      }

      <span class="type"><a href="qjsonobject.html">QJsonObject</a></span> gameObject;
      write(gameObject);
      <span class="type"><a href="qjsondocument.html">QJsonDocument</a></span> saveDoc(gameObject);
      saveFile<span class="operator">.</span>write(saveFormat <span class="operator">=</span><span class="operator">=</span> Json
          <span class="operator">?</span> saveDoc<span class="operator">.</span>toJson()
          : saveDoc<span class="operator">.</span>toBinaryData());

      <span class="keyword">return</span> <span class="keyword">true</span>;
  }

</pre>
<p>Not surprisingly, saveGame() looks very much like loadGame(). We determine the file extension based on the format, print a warning and return <code>false</code> if the opening of the file fails. We then write the Game object to a <a href="qjsondocument.html">QJsonDocument</a>, and call either <a href="qjsondocument.html#toJson">QJsonDocument::toJson</a>() or to <a href="qjsondocument.html#toBinaryData">QJsonDocument::toBinaryData</a>() to save the game, depending on which format was specified.</p>
<p>We are now ready to enter main():</p>
<pre class="cpp">

  <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
  {
      <span class="type"><a href="qcoreapplication.html">QCoreApplication</a></span> app(argc<span class="operator">,</span> argv);

      Game game;
      game<span class="operator">.</span>newGame();
      <span class="comment">// Game is played; changes are made...</span>

</pre>
<p>Since we're only interested in demonstrating <i>serialization</i> of a game with JSON, our game is not actually playable. Therefore, we only need <a href="qcoreapplication.html">QCoreApplication</a> and have no event loop. We create our game and assume that the player had a great time and made lots of progress, altering the internal state of our Character, Level and Game objects.</p>
<pre class="cpp">

      <span class="keyword">if</span> (<span class="operator">!</span>game<span class="operator">.</span>saveGame(Game<span class="operator">::</span>Json))
          <span class="keyword">return</span> <span class="number">1</span>;

      <span class="keyword">if</span> (<span class="operator">!</span>game<span class="operator">.</span>saveGame(Game<span class="operator">::</span>Binary))
          <span class="keyword">return</span> <span class="number">1</span>;

      Game fromJsonGame;
      <span class="keyword">if</span> (<span class="operator">!</span>fromJsonGame<span class="operator">.</span>loadGame(Game<span class="operator">::</span>Json))
          <span class="keyword">return</span> <span class="number">1</span>;

      Game fromBinaryGame;
      <span class="keyword">if</span> (<span class="operator">!</span>fromBinaryGame<span class="operator">.</span>loadGame(Game<span class="operator">::</span>Binary))
          <span class="keyword">return</span> <span class="number">1</span>;

      <span class="keyword">return</span> <span class="number">0</span>;
  }

</pre>
<p>When the player has finished, we save their game. For demonstration purposes, we serialize to both JSON and binary. You can examine the contents of the files in the same directory as the executable, although the binary save file will contain some garbage characters (which is normal).</p>
<p>To show that the saved files can be loaded again, we call loadGame() for each format, returning <code>1</code> on failure. Assuming everything went well, we return <code>0</code> to indicate success.</p>
<p>That concludes our example. As you can see, serialization with Qt's JSON classes is very simple and convenient. The advantages of using <a href="qjsondocument.html">QJsonDocument</a> and friends over <a href="qdatastream.html">QDataStream</a>, for example, is that you not only get human-readable JSON files, but you also have the option to use a binary format if it's required, <i>without</i> rewriting any code.</p>
<p>Files:</p>
<ul>
<li><a href="qtcore-json-savegame-character-cpp.html">json/savegame/character.cpp</a></li>
<li><a href="qtcore-json-savegame-character-h.html">json/savegame/character.h</a></li>
<li><a href="qtcore-json-savegame-game-cpp.html">json/savegame/game.cpp</a></li>
<li><a href="qtcore-json-savegame-game-h.html">json/savegame/game.h</a></li>
<li><a href="qtcore-json-savegame-level-cpp.html">json/savegame/level.cpp</a></li>
<li><a href="qtcore-json-savegame-level-h.html">json/savegame/level.h</a></li>
<li><a href="qtcore-json-savegame-main-cpp.html">json/savegame/main.cpp</a></li>
<li><a href="qtcore-json-savegame-savegame-pro.html">json/savegame/savegame.pro</a></li>
</ul>
</div>
<p><b>See also </b><a href="json.html">JSON Support in Qt</a> and Data Storage.</p>
<!-- @@@json/savegame -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2017 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>