Storing Game data
by A.Nadif
I Check whether a file exists
Hi and welcome for this first tutorial ! The aim of this first part is simply to check whether a file exists or not.
First, be sure to have these two lines on top of your code :
using Microsoft.Xna.Framework.Storage;
using System.IO;
Then, you need to declare a few things :
IAsyncResult result;
StorageDevice device;
bool exists;
KeyboardState keyboardState;
Obviously the variable exists will be true if the file exists an false if not.
Add these two lines in the Initialize() method :
result = Guide.BeginStorageShowDeviceSelector(PlayerIndex.One, null, null);
device = Guide.EndShowStorageDeviceSelector(result);
Next, we'll create a new method called CheckWhetherExists() :
public bool CheckWhetherExists(bool fileExists, StorageDevice storageDevice)
{
StorageContainer myContainer = storageDevice.OpenContainer("YourGameName");
string nameOfFile = Path.Combine(myContainer.path, "fileName.sav");
if (File.Exists(nameOfFile)
{
fileExists = true;
}
else
{
fileExists = false;
}
myContainer.Dispose();
return fileExists;
}
Note that the file is searched should be in the Documents\SavedGames\GameName\Player1 folder.
Now, in the Update(GameTime gameTime) method, add the following :
keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.A))
{
CheckWhetherExists(exists, device);
}
II How to put game data into a file
OK, so let's get to something more interesting : let's save data in a file, so it is easy to read it later.
Now, open a new project. Be sure to have these lines on the top :
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml.Serialization;
Then, create a new structure, that you can call Saver. You could create a class, but a structure is faster. So here is the structure :
public struct DataToSave
{
// To Do : create one object for each data you want to save
// The code below is just an example, given that it entirely depends on what data you want to save.
public string playerModel;
public string playerName;
public Vector3 playerPosition;
}
Don't forget to add the Serializable attribute to it, by adding this before the structure :
[Serializable]
Now, add these declarations :
IAsyncResult result;
StorageDevice device;
KeyboardState keyboardState;
Then, add this inside the Initialize() method :
result = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One, null, null);
device = Guide.EndShowStorageDeviceSelector(result);
Next, create a new method (e.g.called Save()) :
private static void Save(StorageDevice storageDevice) {
// Pass the information into the data objects
DataToSave dataToSave = new DataToSave();
dataToSave.playerModel = "playerModelName";
dataToSave.playerName = "Player"; dataToSave.playerPosition = Vector3.Zero;
StorageContainer myContainer = storageDevice.OpenContainer("YourGameName"); // Here is the path to where you want to save your data
string nameOfFile = Path.Combine(myContainer.Path, "fileName.sav"); // If the file doesn't exist, it will be created, if it does, it will be replaced
FileStream fileStream = File.Open(nameOfFile, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(DataToSave)); serializer.Serialize(fileStream, dataToSave);
// Now, we can close this file
fileStream.Close();
myContainer.Dispose();
}
And now we have to take care about the Update(GameTime gameTime) method :
keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.A))
{
Save(device);
}
And here is the result :
III Now, let's read the data we just saved
We will make a simple project, that will read the data from the file we just created, and turn the background color to black if the player name stored inside the file is "Player", so we know the code works.
First, add these lines at the top of your programm :
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml.Serialization;
Then, add these declarations :
IAsyncResult result;
StorageDevice device;
KeyboardState keyboardState;
string player = null;
Then, create THE SAME STRUCTURE AS YOU DID WHEN YOU SAVED THE DATA INTO THE FILE. That means : the SAME name, order, etc.
For this example, here it is :
[Serializable]
public struct DataToSave
{
public string playerModel;
public string playerName;
public Vector3 playerPosition;
}
Then add these two lines in the Initialize() method :
result = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One, null, null);
device = Guide.EndShowStorageDeviceSelector(result);
Now is time to take care of our LoadData() method. It shouldn't be a problem for you if you've been trough the first two parts of this tutorial :
private void LoadData(StorageDevice storageDevice) {
StorageContainer myContainer = storageDevice.OpenContainer("YourGameName"); string filename = Path.Combine(myContainer.Path, "fileName.sav"); if (!File.Exists(filename)) return ;
FileStream fileStream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Read); XmlSerializer serializer = new XmlSerializer(typeof(DataToSave)); DataToSave dataToSave = (DataToSave)serializer.Deserialize(fileStream); fileStream.Close();
myContainer.Dispose();
player = dataToSave.playerName;
}
Finally, we want our background to turn to black if player = "Player", so let's do that in the Draw() method :
keyboardState = Keyboard.GetState(); if (keyboardState.IsKeyDown(Keys.A)) {
LoadData(device);
}
if (player == "Player") {
GraphicsDevice.Clear(Color.Black); }
else
{
GraphicsDevice.Clear(Color.CornflowerBlue); }
Download sample
I know this a lot of code here, with not much comments, but I will soon update it.
IV NEW SAMPLE
Hi, here is a second sample that sums up what you could read before.
Here is how it works :
First, we check in the Initialize() method, whether the player has already saved a game or not.
If yes, we load the level in which the player saved, from the text file which name is the level's name (either Level_1 or Level_2)
If no, by default, we load the level 1, from a text file called Level_1
To get to level 1, press NumPad1, to get to level 2, press NumPad2.
To save, press A.