拯救和在级别选择屏幕,XML,XNA上加载数据

时间:2014-06-24 16:34:23

标签: c# xml xna save

我正在做一个基本的平台游戏,这是我的第一部游戏。我遇到了一些问题。到目前为止,游戏只有一个级别,它是从.txt文件加载的。但是,我想要一个愤怒的Birdish世界/关卡选择屏幕。

计划是每个级别都有一个可见的图标,但只有到目前为止完成的级别和下一个级别可访问。此外,对于完成的级别,分数(星号,等等)将显示在图标下方。

我不希望从XML加载级别,至少现在还没有。只有需要读取和写入的持久性世界数据。我假设最简单的方法是从XML加载级别选择屏幕的格式,而不是使用我当前使用的方法(文本文件)。

我想,我可以用文本文件来做这件事,但我真的不喜欢编写和整理文件的想法。然后我发现XML文件在这方面应该没有问题。然而,由于我之前从未使用过XML文件这一事实引发了其他问题。

有人可能会指出我这方面的教程方向,或者你可能会遇到的一些样本,至少可以完成相对类似的结果。我不希望任何人为我做编码,但如果你有指示或时间和耐心提供样本,我会非常感激。

经过一些进一步挖掘和摸索旧版XNA版本的教程后,我设法生成了以下保存/加载类:

namespace SaveLoadXML
{
    class SaveLoad
    {
        public LevelInfo Load (int id)
        {
            LevelInfo level;

            // Get the path of the save game
            string fullpath = "World.xml";

            // Open the file
            FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate,
            FileAccess.Read);
            try
            {

                // Read the data from the file
                XmlSerializer serializer = new XmlSerializer(typeof(LevelInfo));
                level = (LevelInfo)serializer.Deserialize(stream);
            }
            finally
            {
                // Close the file
                stream.Close();
            }

            return (level);
        }

        public void Save (LevelInfo level, int id)
        {
            // Get the path of the save game
            string fullpath = "World.xml";

            // Open the file, creating it if necessary
            FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate);
            try
            {
                // Convert the object to XML data and put it in the stream
                XmlSerializer serializer = new XmlSerializer(typeof(LevelInfo));
                serializer.Serialize(stream, level);
            }
            finally
            {
                // Close the file
                stream.Close();
            }
        }
    }
}

现在我开始思考,有没有办法定位XML文件的特定部分,还是从一开始就写作?我看到的几乎所有例子都有一个条件:如果文件存在,删除它然后写。

我假设我可以(甚至应该?)创建LevelInfo对象列表并立即加载它们,因为无论如何都不需要加载单个LevelInfo。但是,在保存时,是否需要加载以前的状态(旧列表),然后操作有关所涉及的某些索引的列表,然后删除te文件,并再次保存。

如果在保存或电源故障中出现问题,这可能会为系统打开一个简单的方法。整个文件将丢失或损坏。我想这可以通过使用备份文件然后检查主文件的完整性来应对,但是现在它开始觉得像我这样的初学者会爬上相当高的山峰。

在GameDev上尝试过这个问题之后,我将在这里澄清一下主要问题:

1)我是否只能保存包含所有级别信息的XML文件中的一个或两个级别的信息?即。我可以使用一些索引来将写操作指向特定部分,然后将被覆盖/替换。

2)如果没有,有没有办法安全地加载文件中的所有信息,删除文件,在需要的地方修改后保存所有信息。


在研究了这些Json之后,我成功地成功地序列化了测试级别信息。但是,反序列化失败,因为我有一个矩形作为对象的一部分。错误如下:

转换值时出错" {X:1 Y:1宽度:1高度:1}"输入' Microsoft.Xna.Framework.Rectangle'。路径' [0] .Rectangle',第6行,第46位。

class LevelInfo
{
    public int ID { get; set; }
    public Vector2 Dimensions { get; set; }
    public Vector2 Position { get; set; }
    public Rectangle Rectangle { get; set; }
    public int Stars { get; set; }
    public string Text { get; set; }
}


class SaveLoadJSON
{
    public static List<LevelInfo> Load()
    {
        List<LevelInfo> levels = new List<LevelInfo>();

        using (StreamReader file = File.OpenText("World.json"))
        {
            JsonSerializer serializer = new JsonSerializer();
            levels = (List<LevelInfo>)serializer.Deserialize(file, typeof(List<LevelInfo>));
        }  

        return levels;
    }

    public static void Save(List<LevelInfo> levels)
    { 
        if (File.Exists("World.json"))
        {
            File.Delete("World.json");
        }

        using (FileStream fs = File.Open("World.json", FileMode.CreateNew))
        using (StreamWriter sw = new StreamWriter(fs))
        using (JsonWriter jw = new JsonTextWriter(sw))
        {
            jw.Formatting = Formatting.Indented;

            JsonSerializer serializer = new JsonSerializer();
            serializer.Serialize(jw, levels);
        }
    }
}

有办法解决这个问题吗?对于像我这样的简单初学者来说,这是一种相对简单的方法。

或者,有没有办法省略矩形信息,可能会在以后添加?如果我没有向矩形输入任何内容,它仍然会添加到具有0值的Json文件中。我确实需要绘图的矩形信息。

1 个答案:

答案 0 :(得分:0)

所以这是承诺的答案。

我个人更喜欢使用JSon来存储数据,因为它比XML更容易使用,并且占用的存储空间更少。你想要做的是制作你的玩家,敌人,物品,场景物品等的数据模型。

然后,你想要JsonConvert.SerializeObject()一个父数据模型,它将包含所有这些东西。

将其保存在任何文件中,并在加载时再次反序列化,并从头开始重建所有对象。

或者,只需拥有您已经使用的课程中的所有属性,即公开。这样,JsonConvert将能够实际序列化整个模型。请记住,如果您执行此运行时,它将更多地创建Levels当前状态的完整快照。阿卡。敌人所处的位置,剩余的健康状况以及你可能拥有的其他任何东西。

我希望这能回答你的问题。