[英]Saving & loading data on level selection screen, XML, XNA
我正在做一個基本的平台游戲,這是我的第一個游戲。 我遇到了一個問題。 到目前為止,游戲只有一個級別,並且是從.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。 但是,在保存時,我是否需要加載先前的狀態(舊列表),然后對涉及的某些索引操作列表,然后刪除te文件,然后再次保存。
例如,如果在保存過程中出現問題或電源出現故障,這可能為系統故障提供了一種簡便的方法。 整個文件將丟失或損壞。 我想可以通過使用備份文件然后檢查主文件的完整性來解決這個問題,但是現在對於像我這樣的初學者來說,它開始像是一座大山。
在GameDev上試過這個問題之后,我將在這里澄清主要問題:
1)我可以只在包含所有級別信息的XML文件中僅保存有關一兩個級別的信息嗎? 即。 我可以使用一些索引將寫入操作指向一個特定的節,然后將其覆蓋/替換。
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文件中。 我確實需要繪圖的矩形信息。
因此,承諾的答案就在這里。
我個人更喜歡使用JSon來存儲數據,因為它比XML易於使用,並且占用的存儲空間更少。 您要做的是為玩家,敵人,物品,場景對象等創建數據模型。
然后,您需要JsonConvert.SerializeObject()一個父數據模型,它將包含所有這些內容。
將其保存在任何文件中,並在加載時再次反序列化,然后從頭開始重建所有對象。
另外,只要將您正在使用的類中的所有屬性都公開即可。 這樣,JsonConvert將能夠實際序列化整個模型。 請記住,如果執行此運行時,它將更多地構成Levels當前狀態的完整快照。 ka 敵人所在的位置,剩余的生命值以及您可能擁有的其他一切。
我希望這回答了你的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.