我正在尝试通过XNA MSDN文档来保存和阅读游戏数据,我没有太多运气。
本质上,我有一个管理器类,它跟踪基类的多个实例。
我希望能够保存管理员跟踪的整个对象列表的状态,然后在下次加载游戏时加载它们。基本上拯救了世界的状况。
答案 0 :(得分:16)
如果您使用XNA 4.0帮助中所示的XmlSerializer,基类需要为每个可以序列化的具体类型指定[XmlInclude(Type)]属性。
以下是如何在XNA 4.0中保存游戏数据的示例。一旦游戏运行,请按F1保存。数据将保存到类似于C:\ Users \ {username} \ Documents \ SavedGames \ WindowsGame \ Game1StorageContainer \ Player1的位置。
再次加载数据是一个非常相似的过程。
为了使这个工作在XBox上添加对Microsoft.Xna.Framework.GamerServices&的引用。的System.Xml.Serialization。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
namespace WindowsGame
{
[XmlInclude(typeof(Soldier)), XmlInclude(typeof(Grenade))]
public class BaseGameObject
{
public Vector3 Position { get; set; }
}
public class Soldier : BaseGameObject
{
public float Health { get; set; }
}
public class Grenade : BaseGameObject
{
public float TimeToDetonate { get; set; }
}
public struct SaveGameData
{
public string PlayerName;
public Vector2 AvatarPosition;
public int Level;
public int Score;
public List<BaseGameObject> GameObjects;
}
public class Game1 : Microsoft.Xna.Framework.Game
{
enum SavingState
{
NotSaving,
ReadyToSelectStorageDevice,
SelectingStorageDevice,
ReadyToOpenStorageContainer, // once we have a storage device start here
OpeningStorageContainer,
ReadyToSave
}
GraphicsDeviceManager graphics;
KeyboardState oldKeyboardState;
KeyboardState currentKeyboardState;
StorageDevice storageDevice;
SavingState savingState = SavingState.NotSaving;
IAsyncResult asyncResult;
PlayerIndex playerIndex = PlayerIndex.One;
StorageContainer storageContainer;
string filename = "savegame.sav";
SaveGameData saveGameData = new SaveGameData()
{
PlayerName = "Grunt",
AvatarPosition = new Vector2(10, 15),
Level = 3,
Score = 99424,
GameObjects = new List<BaseGameObject>()
{
new Soldier { Health = 10.0f, Position = new Vector3(0.0f, 10.0f, 0.0f) },
new Grenade { TimeToDetonate = 3.0f, Position = new Vector3(4.0f, 3.0f, 0.0f) }
}
};
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
#if XBOX
Components.Add(new GamerServicesComponent(this));
#endif
currentKeyboardState = Keyboard.GetState();
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
oldKeyboardState = currentKeyboardState;
currentKeyboardState = Keyboard.GetState();
UpdateSaveKey(Keys.F1);
UpdateSaving();
base.Update(gameTime);
}
private void UpdateSaveKey(Keys saveKey)
{
if (!oldKeyboardState.IsKeyDown(saveKey) && currentKeyboardState.IsKeyDown(saveKey))
{
if (savingState == SavingState.NotSaving)
{
savingState = SavingState.ReadyToOpenStorageContainer;
}
}
}
private void UpdateSaving()
{
switch (savingState)
{
case SavingState.ReadyToSelectStorageDevice:
#if XBOX
if (!Guide.IsVisible)
#endif
{
asyncResult = StorageDevice.BeginShowSelector(playerIndex, null, null);
savingState = SavingState.SelectingStorageDevice;
}
break;
case SavingState.SelectingStorageDevice:
if (asyncResult.IsCompleted)
{
storageDevice = StorageDevice.EndShowSelector(asyncResult);
savingState = SavingState.ReadyToOpenStorageContainer;
}
break;
case SavingState.ReadyToOpenStorageContainer:
if (storageDevice == null || !storageDevice.IsConnected)
{
savingState = SavingState.ReadyToSelectStorageDevice;
}
else
{
asyncResult = storageDevice.BeginOpenContainer("Game1StorageContainer", null, null);
savingState = SavingState.OpeningStorageContainer;
}
break;
case SavingState.OpeningStorageContainer:
if (asyncResult.IsCompleted)
{
storageContainer = storageDevice.EndOpenContainer(asyncResult);
savingState = SavingState.ReadyToSave;
}
break;
case SavingState.ReadyToSave:
if (storageContainer == null)
{
savingState = SavingState.ReadyToOpenStorageContainer;
}
else
{
try
{
DeleteExisting();
Save();
}
catch (IOException e)
{
// Replace with in game dialog notifying user of error
Debug.WriteLine(e.Message);
}
finally
{
storageContainer.Dispose();
storageContainer = null;
savingState = SavingState.NotSaving;
}
}
break;
}
}
private void DeleteExisting()
{
if (storageContainer.FileExists(filename))
{
storageContainer.DeleteFile(filename);
}
}
private void Save()
{
using (Stream stream = storageContainer.CreateFile(filename))
{
XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));
serializer.Serialize(stream, saveGameData);
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
}
}