-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
366 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#region Using Statements | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Content; | ||
using Microsoft.Xna.Framework.Graphics; | ||
using Microsoft.Xna.Framework.Input; | ||
using Microsoft.Xna.Framework.Storage; | ||
using Microsoft.Xna.Framework.GamerServices; | ||
using System.Diagnostics; | ||
#endregion | ||
|
||
namespace MonoGameSaveManager | ||
{ | ||
/// <summary> | ||
/// A basic game to test out the SaveManager functionality. | ||
/// Just follow along with the comments. | ||
/// </summary> | ||
public class Game1 : Game | ||
{ | ||
GraphicsDeviceManager graphics; | ||
SpriteBatch spriteBatch; | ||
|
||
SaveManager save; | ||
bool saved = false; | ||
|
||
public Game1() | ||
: base() | ||
{ | ||
graphics = new GraphicsDeviceManager(this); | ||
Content.RootDirectory = "Content"; | ||
|
||
string saveFolder = "SaveManagerTest"; // put your save folder name here | ||
string saveFile = "test.sav"; // put your save file name here | ||
|
||
// Pick one: | ||
|
||
// - this will use the XNA StorageDevice method. | ||
save = new StorageDeviceSaveManager(saveFolder, saveFile, PlayerIndex.One); | ||
|
||
// - this will use the .NET IsolatedStorage method. | ||
//save = new IsolatedStorageSaveManager(saveFolder, saveFile); | ||
} | ||
|
||
/// <summary> | ||
/// Allows the game to perform any initialization it needs to before starting to run. | ||
/// This is where it can query for any required services and load any non-graphic | ||
/// related content. Calling base.Initialize will enumerate through any components | ||
/// and initialize them as well. | ||
/// </summary> | ||
protected override void Initialize() | ||
{ | ||
// TODO: Add your initialization logic here | ||
|
||
base.Initialize(); | ||
} | ||
|
||
/// <summary> | ||
/// LoadContent will be called once per game and is the place to load | ||
/// all of your content. | ||
/// </summary> | ||
protected override void LoadContent() | ||
{ | ||
// Create a new SpriteBatch, which can be used to draw textures. | ||
spriteBatch = new SpriteBatch(GraphicsDevice); | ||
|
||
// TODO: use this.Content to load your game content here | ||
} | ||
|
||
/// <summary> | ||
/// UnloadContent will be called once per game and is the place to unload | ||
/// all content. | ||
/// </summary> | ||
protected override void UnloadContent() | ||
{ | ||
// TODO: Unload any non ContentManager content here | ||
} | ||
|
||
/// <summary> | ||
/// Allows the game to run logic such as updating the world, | ||
/// checking for collisions, gathering input, and playing audio. | ||
/// </summary> | ||
/// <param name="gameTime">Provides a snapshot of timing values.</param> | ||
protected override void Update(GameTime gameTime) | ||
{ | ||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) | ||
Exit(); | ||
|
||
// test save stuff | ||
// since this is Update, i don't want it to keep saving every tick | ||
if (!saved) | ||
{ | ||
saved = true; | ||
|
||
// let's make up some save data | ||
save.Data.testInt = 434; | ||
save.Data.testBool = false; | ||
save.Data.testString = "wow a test"; | ||
|
||
// save it | ||
save.Save(); | ||
|
||
// erase data so we can check if loading works | ||
save.Data = new SaveData(); | ||
|
||
// load it back | ||
save.Load(); | ||
|
||
// did it work? let's hope so! | ||
// this will show up in Visual Studio's Output window when running. | ||
// you can also just use a Breakpoint or whatever. | ||
Debug.WriteLine("final save data:"); | ||
Debug.WriteLine("testInt = " + save.Data.testInt); | ||
Debug.WriteLine("testBool = " + save.Data.testBool); | ||
Debug.WriteLine("testString = " + save.Data.testString); | ||
} | ||
|
||
base.Update(gameTime); | ||
} | ||
|
||
/// <summary> | ||
/// This is called when the game should draw itself. | ||
/// </summary> | ||
/// <param name="gameTime">Provides a snapshot of timing values.</param> | ||
protected override void Draw(GameTime gameTime) | ||
{ | ||
GraphicsDevice.Clear(Color.CornflowerBlue); | ||
|
||
// TODO: Add your drawing code here | ||
|
||
base.Draw(gameTime); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.IsolatedStorage; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Xml.Serialization; | ||
|
||
namespace MonoGameSaveManager | ||
{ | ||
/// <summary> | ||
/// Uses the .NET IsolatedStorage to load/save game data. | ||
/// Saves end up on "C:\Users\...\AppData\Local\IsolatedStorage\..." on Windows. | ||
/// </summary> | ||
public class IsolatedStorageSaveManager : SaveManager | ||
{ | ||
/// <summary> | ||
/// /// <summary> | ||
/// Creates a new save game manager based on .NET IsolatedStorage. | ||
/// </summary> | ||
/// <param name="folderName">Name of the folder containing the save.</param> | ||
/// <param name="fileName">Name of the save file.</param> | ||
public IsolatedStorageSaveManager(string folderName, string fileName) | ||
: base(folderName, fileName) | ||
{ } | ||
|
||
public override void Load() | ||
{ | ||
using (IsolatedStorageFile isf = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null)) | ||
{ | ||
// Ignore if directory doesn't exist. | ||
if (!isf.DirectoryExists(folderName)) | ||
return; | ||
|
||
string filePath = Path.Combine(folderName, fileName); | ||
|
||
// Ignore if save doesn't exist. | ||
if (!isf.FileExists(filePath)) | ||
return; | ||
|
||
// Open the save file. | ||
using (IsolatedStorageFileStream stream = isf.OpenFile(filePath, FileMode.Open)) | ||
{ | ||
// Get the XML data from the stream and convert it to object. | ||
XmlSerializer serializer = new XmlSerializer(typeof(SaveData)); | ||
Data = (SaveData)serializer.Deserialize(stream); | ||
} | ||
} | ||
} | ||
|
||
public override void Save() | ||
{ | ||
using (IsolatedStorageFile isf = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null)) | ||
{ | ||
// Create directory if it doesn't exist. | ||
if (!isf.DirectoryExists(folderName)) | ||
isf.CreateDirectory(folderName); | ||
|
||
string filePath = Path.Combine(folderName, fileName); | ||
|
||
// Create new save file. | ||
using (IsolatedStorageFileStream stream = isf.CreateFile(filePath)) | ||
{ | ||
// Convert the object to XML data and put it in the stream. | ||
XmlSerializer serializer = new XmlSerializer(typeof(SaveData)); | ||
serializer.Serialize(stream, Data); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace MonoGameSaveManager | ||
{ | ||
/// <summary> | ||
/// Container for your save game data. | ||
/// Put the variables you need here, as long as it's serializable. | ||
/// </summary> | ||
[Serializable] | ||
public class SaveData | ||
{ | ||
public int testInt; | ||
public bool testBool; | ||
public string testString; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace MonoGameSaveManager | ||
{ | ||
/// <summary> | ||
/// Manages a save file for you. | ||
/// </summary> | ||
public abstract class SaveManager | ||
{ | ||
protected string folderName, fileName; | ||
|
||
/// <summary> | ||
/// Access save game data. | ||
/// </summary> | ||
public SaveData Data { get; set; } | ||
|
||
/// <summary> | ||
/// Creates a new save game manager. | ||
/// </summary> | ||
/// <param name="folderName">Name of the folder containing the save.</param> | ||
/// <param name="fileName">Name of the save file.</param> | ||
public SaveManager(string folderName, string fileName) | ||
{ | ||
this.folderName = folderName; | ||
this.fileName = fileName; | ||
this.Data = new SaveData(); | ||
} | ||
|
||
/// <summary> | ||
/// Loads the data from disk to memory. | ||
/// </summary> | ||
public abstract void Load(); | ||
|
||
/// <summary> | ||
/// Saves the data in memory to disk. | ||
/// </summary> | ||
public abstract void Save(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Storage; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Xml.Serialization; | ||
|
||
namespace MonoGameSaveManager | ||
{ | ||
/// <summary> | ||
/// Uses the XNA StorageDevice to load/save game data. | ||
/// Saves end up on "C:\Users\...\Documents\SavedGames\..." on Windows. | ||
/// </summary> | ||
public class StorageDeviceSaveManager : SaveManager | ||
{ | ||
private PlayerIndex? player; | ||
|
||
/// <summary> | ||
/// Creates a new save game manager based on XNA StorageDevice. | ||
/// </summary> | ||
/// <param name="folderName">Name of the folder containing the save.</param> | ||
/// <param name="fileName">Name of the save file.</param> | ||
/// <param name="player">Player the save belongs to, or null for a global save.</param> | ||
public StorageDeviceSaveManager(string folderName, string fileName, PlayerIndex? player) | ||
: base(folderName, fileName) | ||
{ | ||
this.player = player; | ||
} | ||
|
||
private StorageDevice getStorageDevice() | ||
{ | ||
IAsyncResult result; | ||
// Get a global folder. | ||
if (player == null) | ||
result = StorageDevice.BeginShowSelector(null, null); | ||
// Get a player-specific subfolder. | ||
else | ||
result = StorageDevice.BeginShowSelector((PlayerIndex)player, null, null); | ||
|
||
result.AsyncWaitHandle.WaitOne(); | ||
StorageDevice device = StorageDevice.EndShowSelector(result); | ||
result.AsyncWaitHandle.Close(); | ||
return device; | ||
} | ||
|
||
public override void Load() | ||
{ | ||
// Open a storage device. | ||
StorageDevice device = getStorageDevice(); | ||
|
||
// Open a storage container. | ||
IAsyncResult result = device.BeginOpenContainer(folderName, null, null); | ||
result.AsyncWaitHandle.WaitOne(); | ||
using (StorageContainer container = device.EndOpenContainer(result)) | ||
{ | ||
result.AsyncWaitHandle.Close(); | ||
|
||
// Ignore if save doesn't exist. | ||
if (!container.FileExists(fileName)) | ||
return; | ||
|
||
// Open the save file. | ||
using (Stream stream = container.OpenFile(fileName, FileMode.Open)) | ||
{ | ||
// Get the XML data from the stream and convert it to object. | ||
XmlSerializer serializer = new XmlSerializer(typeof(SaveData)); | ||
Data = (SaveData)serializer.Deserialize(stream); | ||
} | ||
} | ||
} | ||
|
||
public override void Save() | ||
{ | ||
// Open a storage device. | ||
StorageDevice device = getStorageDevice(); | ||
|
||
// Open a storage container. | ||
IAsyncResult resultStorage = device.BeginOpenContainer(folderName, null, null); | ||
resultStorage.AsyncWaitHandle.WaitOne(); | ||
using (StorageContainer container = device.EndOpenContainer(resultStorage)) | ||
{ | ||
resultStorage.AsyncWaitHandle.Close(); | ||
|
||
// Delete old save file. | ||
if (container.FileExists(fileName)) | ||
container.DeleteFile(fileName); | ||
|
||
// Create new save file. | ||
using (Stream stream = container.CreateFile(fileName)) | ||
{ | ||
// Convert the object to XML data and put it in the stream. | ||
XmlSerializer serializer = new XmlSerializer(typeof(SaveData)); | ||
serializer.Serialize(stream, Data); | ||
} | ||
} | ||
} | ||
} | ||
} |