储蓄,在关卡选择屏幕上加载数据,XML, XNA

本文关键字:加载 数据 XNA XML 选择 储蓄 屏幕 | 更新日期: 2023-09-27 18:10:10

我正在制作一款基础平台游戏,这是我的第一款游戏。我遇到了点小麻烦。到目前为止,这款游戏只有一个关卡,并且是从。txt文件中加载的。但是我想要一个类似《愤怒的小鸟》的世界/关卡选择界面。

我们的计划是让每个关卡都有一个可见的图标,但只有到目前为止完成的关卡和下一个可以访问。此外,对于已完成的关卡,分数(星星等)将显示在图标下。

我不希望从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。然而,在保存时,我是否需要加载以前的状态(旧列表),然后根据所涉及的某些索引操作列表,然后删除文件,并再次保存它。

如果在保存或电源故障中出现错误,这可能会为系统打开一个容易失败的方法。整个文件将丢失或损坏。我想这可以通过使用备份文件,然后检查主文件的完整性来解决,但是现在对于像我这样的初学者来说,这开始感觉像爬了一座山。

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

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

2)如果没有,是否有任何方法可以安全地从文件中加载所有信息,删除文件,在需要修改后保存所有信息


经过一些研究这个Json的东西,我已经成功地序列化测试级别的信息。然而,反序列化失败,因为我有一个矩形作为对象的一部分。错误如下:

将值"{X:1 Y:1宽:1高:1}"转换为类型" Microsoft.Xna.Framework.Rectangle "时出错。路[0]。矩形',第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文件中。我确实需要矩形信息来绘制。

储蓄,在关卡选择屏幕上加载数据,XML, XNA

承诺的答案来了。

我个人更喜欢使用JSon来存储数据,因为它比XML更容易使用,占用的存储空间更少。你要做的是为玩家、敌人、道具、场景对象等创建数据模型。

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

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

或者,在你已经使用的类中拥有所有属性,是公共的。这样,JsonConvert将能够序列化整个模型。请记住,如果您执行此运行时,它将生成更多的关卡当前状态的完整快照。又名。敌人的位置,剩余的生命值以及你可能拥有的任何东西。

我希望这能回答你的问题