我正在做一个基本的平台游戏,这是我的第一部游戏。我遇到了一些问题。到目前为止,游戏只有一个级别,它是从.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文件中。我确实需要绘图的矩形信息。
答案 0 :(得分:0)
所以这是承诺的答案。
我个人更喜欢使用JSon来存储数据,因为它比XML更容易使用,并且占用的存储空间更少。你想要做的是制作你的玩家,敌人,物品,场景物品等的数据模型。
然后,你想要JsonConvert.SerializeObject()一个父数据模型,它将包含所有这些东西。
将其保存在任何文件中,并在加载时再次反序列化,并从头开始重建所有对象。
或者,只需拥有您已经使用的课程中的所有属性,即公开。这样,JsonConvert将能够实际序列化整个模型。请记住,如果您执行此运行时,它将更多地创建Levels当前状态的完整快照。阿卡。敌人所处的位置,剩余的健康状况以及你可能拥有的其他任何东西。
我希望这能回答你的问题。