保存游戏数据的XML序列化 [英] xml serializing of saved game data

查看:242
本文介绍了保存游戏数据的XML序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个方法来节省一些筑底的数据游戏。目前,我正在试图将数据保存在 XML 与父格式<数据> 包含数组元素< leveldata> 这对索引字段元素,完成和尝试。这是我第一次尝试将序列号 C# 所以我所遇到的一些问题,此刻,它是在下跌与出现InvalidOperationException 当我尝试反序列化文件(底部异常细节)。



下面是代码。

 公共无效保存数据()
{
常量字符串文件名=data.vision;

#如果WINDOWS_PHONE
IsolatedStorageFile数据文件= IsolatedStorageFile.GetUserStoreForApplication();
的#else
IsolatedStorageFile数据文件= IsolatedStorageFile.GetUserStoreForDomain();
#ENDIF

{
//创建一个独立的存储流,初始化为空。
IsolatedStorageFileStream isolatedFileStream = NULL;

//打开独立存储流,并写入保存数据文件。
如果(dataFile.FileExists(文件名))
{使用(isolatedFileStream = dataFile.OpenFile(文件名,FileMode.Open,FileAccess.ReadWrite))
{

//从文件中读取的数据。
XmlSerializer的序列化=新的XmlSerializer(typeof运算(数据));
//每个列表中的反序列化的数据对象的存储。
数据savedData =(数据)serializer.Deserialize(isolatedFileStream);


//循环所保存的数据对象。
的for(int i = 0; I< savedData.Levels.Count;我++)
{
//获取相关数据对象。
LevelData levelData = savedData.Levels [I]

//检查是否该数据对象的索引对应的有效电平指数。
如果(levelData.Index == mLevelIndex)
{
//检查已保存的企图较少。
如果(levelData.Attempts< mLevel.AttemptCounter)
levelData.Attempts = mLevel.AttemptCounter;

//检查
如果(levelData.PercentComplete< 50)
levelData.PercentComplete = 50;
}
}
serializer.Serialize(isolatedFileStream,savedData);
}
}
,否则
{
//如果没有数据文件,创建一个新的。
使用(isolatedFileStream = dataFile.CreateFile(文件名))
{
//检查文件流已初始化。
如果(isolatedFileStream!= NULL)
{
//创建一个新的数据对象来存储元数据的当前水平。
数据数据=新的Data();
//创建一个列表来存储已保存的数据。
data.Levels =新的List< LevelData>();

//初始化新的数据值。
LevelData levelData =新LevelData();
levelData.Index = mLevelIndex;
levelData.Attempts = mLevel.AttemptCounter;
levelData.PercentComplete = 50;

//添加级别的数据。
data.Levels.Add(levelData);

//将对象转换为XML数据,并把它流。
XmlSerializer的序列化=新的XmlSerializer(typeof运算(数据));
// Seriaize的数据。
serializer.Serialize(isolatedFileStream,数据);
}
}
}
}
终于
{
//处置的存储文件,以提交更改。
dataFile.Dispose();
}
}



数据:

 公共结构数据
{
///<总结>
///水平的数据对象。
///< /总结>
[XmlArray(的ElementName =级别)]
公开名单< LevelData>水平;
}



级数据

 公共结构LevelData 
{
///<总结>
///水平的指标。
///< /总结>
[的XmlElement(的ElementName =指数)]
公众诠释指数;

///<总结>
///尝试玩家已经针对特定级别进行的数量。
///< /总结>
[的XmlElement(的ElementName =尝试)]
公众诠释的尝试;

///<总结>
///描述玩家曾经的水平之内得到了最远的值。
///< /总结>
[的XmlElement(的ElementName =PERCENTCOMPLETE)]
公众诠释PERCENTCOMPLETE;
}



异常详细信息:

  {System.InvalidOperationException:有是XML文档(10,10)错误。 ---> System.Xml.XmlException:意外的XML声明。 XML声明必须是文件中的第一个节点,也没有空格字符被允许在它之前出现。 10号线,在System.Xml.XmlTextReaderImpl.Throw位10 
(例外五)
在System.Xml.XmlTextReaderImpl.Throw(字符串资源,字符串ARG)
在的System.Xml。 XmlTextReaderImpl.ParsePI(BufferBuilder piInDtdStringBuilder)
在System.Xml.XmlTextReaderImpl.ParseDocumentContent()
在System.Xml.XmlTextReaderImpl.Read()
在System.Xml.XmlReader.ReadEndElement()$在System.Xml.Serialization.XmlSerializationReader.ReadEndElement b $ b()
在Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderData.Read3_Data(布尔checkType)
在Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderData。 Read4_Data()
---内部异常堆栈跟踪---
结束在System.Xml.Serialization.XmlSerializer.Deserialize(的XmlReader XmlReader中,字符串encodingStyle的,对象事件)
的系统。 Xml.Serialization.XmlSerializer.Deserialize(流流)
在Vision.GameplayScreen.SaveData()
在Vision.GameplayScreen.HandleInput(InputState输入)
在Vision.ScreenManager.Update(GameTime gameTime )
在Microsoft.Xna.Framework.Game< .cctor> b__19(IUpdateable更新,GameTime gameTime在Microsoft.Xna.Framework.Game.SortingFilteringCollection`1.ForEachFilteredItem)
[TUserData](动作`在Vision.Game.Update 2的动作,在Microsoft.Xna.Framework.Game.Update TUserData USERDATA)
(gameTime gameTime)
(gameTime gameTime)
在Microsoft.Xna.Framework。 Game.DoUpdate(gameTime gameTime)
在Microsoft.Xna.Framework.Game.Tick()在MonoGame.Framework.WindowsPhone.SurfaceUpdateHandler.Draw
(设备装置,DeviceContext背景下,renderTargetView renderTargetView)
。在MonoGame.Framework.WindowsPhone.DrawingSurfaceUpdateHandler.DrawingSurfaceContentProvider.GetTexture(Size2F surfaceSize,DrawingSurfaceSynchronizedTexture&安培; synchronizedTexture,的RectangleF&安培; textureSubRectangle)
在SharpDX.Direct3D11.DrawingSurfaceContentProviderShadow.DrawingSurfaceContentProviderVtbl.GetTexture(IntPtr的thisPtr,IntPtr的surfaceSize,IntPtr的synchronizedTexture,IntPtr的textureSubRectangle)}


解决方案

实现此读取文件后,与反序列化前:

  isolatedFileStream.Position = 0; 


I am trying to write a method to save some basing data for a game. At the moment I am trying to save data in an format with a parent <data> element containing an array of <leveldata> elements which have fields for index, completion and attempts. This is the first time I have tried to serialize anything in so I have run into a few issues, at the moment, it is falling over with an invalidoperationexception when I try to deserialize the file (detail of exception at bottom).

Here is the code.

public void SaveData()
{
    const string filename = "data.vision";

#if WINDOWS_PHONE
    IsolatedStorageFile dataFile = IsolatedStorageFile.GetUserStoreForApplication();
#else
    IsolatedStorageFile dataFile = IsolatedStorageFile.GetUserStoreForDomain();
#endif
    try
    {
        // Create an isolated storage stream and initialize it as null.
        IsolatedStorageFileStream isolatedFileStream = null;

        // Open the isolated storage stream, and write the save data file.
        if (dataFile.FileExists(filename))
        {
            using (isolatedFileStream = dataFile.OpenFile(filename, FileMode.Open,  FileAccess.ReadWrite))
            {
                // Read the data from the file.
                XmlSerializer serializer = new XmlSerializer(typeof(Data));
                // Store each of the deserialized data objects in the list.
                Data savedData = (Data)serializer.Deserialize(isolatedFileStream);


                // Loop through the saved data objects.
                for(int i = 0; i < savedData.Levels.Count; i++)
                {
                    // Get the data object in question.
                    LevelData levelData = savedData.Levels[i];

                    // Check to see if the index of the data object corresponds to the active level index.
                    if (levelData.Index == mLevelIndex)
                    {
                        // Check that the attempts already saved is less.
                        if (levelData.Attempts < mLevel.AttemptCounter)
                            levelData.Attempts = mLevel.AttemptCounter;

                        // Check that the 
                        if (levelData.PercentComplete < 50)
                            levelData.PercentComplete = 50;
                    }
                }
                serializer.Serialize(isolatedFileStream, savedData);
            }  
        }
        else
        {
            // If there is no data file, create a new one.
            using (isolatedFileStream = dataFile.CreateFile(filename))
            {
                // Check the file stream has been initialized.
                if (isolatedFileStream != null)
                {
                    // Create a new data object to store the meta data for the current level.
                    Data data = new Data();
                    // Create a list to store the data already saved.
                    data.Levels = new List<LevelData>();

                    // Initialize the new data values.
                    LevelData levelData = new LevelData();
                    levelData.Index = mLevelIndex;
                    levelData.Attempts = mLevel.AttemptCounter;
                    levelData.PercentComplete = 50;

                    // Add the level data.
                    data.Levels.Add(levelData);

                    // Convert the object to XML data and put it in the stream.
                    XmlSerializer serializer = new XmlSerializer(typeof(Data));
                    // Seriaize the data.
                    serializer.Serialize(isolatedFileStream, data);
                }
            }
        }
    }
    finally
    {
        // Dispose the storage file, in order to commit changes.
        dataFile.Dispose();
    }
}

DATA:

public struct Data
{
    /// <summary>
    /// The Level data object.
    /// </summary>
    [XmlArray(ElementName = "Levels")]
    public List<LevelData> Levels;
}

Level Data

public struct LevelData
{
    /// <summary>
    /// The index of the level.
    /// </summary>
    [XmlElement(ElementName = "Index")]
    public int Index;

    /// <summary>
    /// The number of attempts the player has made for a particular level.
    /// </summary>
    [XmlElement(ElementName = "Attempts")]
    public int Attempts;

    /// <summary>
    /// A value describing the furthest the player has ever got within the level.
    /// </summary>
    [XmlElement(ElementName = "PercentComplete")]
    public int PercentComplete;
}

Exception Detail:

{System.InvalidOperationException: There is an error in XML document (10, 10). ---> System.Xml.XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 10, position 10.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
   at System.Xml.XmlTextReaderImpl.ParsePI(BufferBuilder piInDtdStringBuilder)
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlReader.ReadEndElement()
   at System.Xml.Serialization.XmlSerializationReader.ReadEndElement()
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderData.Read3_Data(Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderData.Read4_Data()
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, Object events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
   at Vision.GameplayScreen.SaveData()
   at Vision.GameplayScreen.HandleInput(InputState input)
   at Vision.ScreenManager.Update(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.<.cctor>b__19(IUpdateable updateable, GameTime gameTime)
   at Microsoft.Xna.Framework.Game.SortingFilteringCollection`1.ForEachFilteredItem[TUserData](Action`2 action, TUserData userData)
   at Microsoft.Xna.Framework.Game.Update(GameTime gameTime)
   at Vision.Game.Update(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.DoUpdate(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.Tick()
   at MonoGame.Framework.WindowsPhone.SurfaceUpdateHandler.Draw(Device device, DeviceContext context, RenderTargetView renderTargetView)
   at MonoGame.Framework.WindowsPhone.DrawingSurfaceUpdateHandler.DrawingSurfaceContentProvider.GetTexture(Size2F surfaceSize, DrawingSurfaceSynchronizedTexture& synchronizedTexture, RectangleF& textureSubRectangle)
   at SharpDX.Direct3D11.DrawingSurfaceContentProviderShadow.DrawingSurfaceContentProviderVtbl.GetTexture(IntPtr thisPtr, IntPtr surfaceSize, IntPtr synchronizedTexture, IntPtr textureSubRectangle)}

解决方案

Implement this after reading the file, and before deserialization:

isolatedFileStream.Position = 0;

这篇关于保存游戏数据的XML序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆