【发布时间】:2014-06-24 16:34:23
【问题描述】:
我正在制作一个基本的平台游戏,这是我的第一款游戏。我遇到了一些问题。到目前为止,游戏只有一个关卡,它是从 .txt 文件加载的。不过我想要一个 Angry 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 文件中只保存一个或两个级别的信息吗? IE。我可以使用一些索引来将写入操作指向一个特定的部分,然后该部分将被覆盖/替换。
2)如果没有,有什么方法可以安全地从文件中加载所有信息,删除文件,在需要的地方修改后保存所有信息。
在研究了这个 Json 的东西之后,我成功地序列化了测试级别的信息。但是,反序列化失败,因为我有一个矩形作为对象的一部分。错误如下:
将值“{X:1 Y:1 Width:1 Height: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 文件中。我确实需要绘图的矩形信息。
【问题讨论】: