gpt4 book ai didi

c# - 如何在 XML 中保存对象实例的引用

转载 作者:数据小太阳 更新时间:2023-10-29 02:35:37 29 4
gpt4 key购买 nike

编辑:得到了答案,我将播放器中的列表 Inv 更改为一个 int 列表,并将游戏初始加载时的项目导入字典中,如下所示:

public static class InitLoad
{
static List<ItemEquipmentWeapon> weapons;

public static Dictionary<int, Item> ItemIDList = new Dictionary<int, Item>();

public static void PreLoading()
{

string path, filePath,
weaponFile = @"\WeaponsItem.aid";
XmlSerializer SerializerObj;
FileStream ReadFileStream;

path = string.Format(@"{0}\AwesomeRPG\Data\Items",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
filePath = string.Format(@"{0}\{1}", path, weaponFile);
SerializerObj = new XmlSerializer(typeof(ItemEquipmentWeapon));
ReadFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
weapons = (List<ItemEquipmentWeapon>)SerializerObj.Deserialize(ReadFileStream);
foreach (Item item in weapons)
{
ItemIDList.Add(item.ID, item);
}
}
}

这意味着我可以用我的播放器类来做到这一点:

[Serializable()]
public class Player : Entity
{
public string Name { get; set; }
public int MaxHP { get; set; }
public int Level { get; set; }
public int XP { get; set; }
public int Str { get; set; }
public int End { get; set; }
public int Dex { get; set; }
public int Agi { get; set; }
public int Wis { get; set; }
public int Int { get; set; }
//Create a list of Item Id's for inventory
public List<int> Inv { get; set; }

private int lHand;
private int rHand;

public int LHand
{
get
{ return lHand; }
set
{
if (!value.THand)
{
lHand = value;
}
else lHand = null;
}
}
public int RHand
{
get
{ return rHand; }
set
{ rHand = value; }
}

internal Player() { }
public Player(string name, int maxhp, int hp, int lvl, int exp, int str, int end, int dex, int agi, int wis, int inte)
: base(true, hp)
{
Name = name;
MaxHP = maxhp;
Level = lvl;
XP = exp;
Str = str;
End = end;
Dex = dex;
Agi = agi;
Wis = wis;
Int = inte;

Inv = new List<int>();
}

public List<string> GetInv()
{
List<string> val = new List<string>();
Item item;
foreach (int i in Inv)
{
InitLoad.ItemIDList.TryGetValue(i, out item);
val.Add(item.Name);
}

return val;
}

public void AddItem(Item i, int amt)
{
for (int j = 0; j < amt; j++)
{
Inv.Add(i.ID);
}
}
public void AddItem(Item i){
AddItem(i, 1); }

public void RemoveItem(Item i, int amt)
{
int count = 0;

foreach (int item in Inv)
{
if (item == i.ID)
{
Inv.Remove(item);
count++;
}
if (count == amt)
{
break;
}
}
}
public void RemoveItem(Item i){
RemoveItem(i, 1); }

public bool HasItem(Item i, int amt)
{
int count = 0;

foreach (int item in Inv)
{
if (item == i.ID)
{
count++;
}
}

return count >= amt;
}
public bool HasItem(Item i){
return HasItem(i, 1); }
}

希望这对其他人有帮助!

原始问题:

因此,我正在制作一个带有 Windows 窗体的愚蠢的小型 RPG 游戏来测试我的技能,并且我正在整理保存。目前它保存到一个 XML 文件,该文件是一个自定义扩展名 (.asd)这是我的保存/加载代码:

public static class SaveGame
{
public static void Save(Player player)
{
string myfile = string.Format(@"{1}\AwesomeRPG\Saves\{0}Save.asd", player.Name, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
//Delete file if it already exists
if (File.Exists(myfile)) System.IO.File.Delete(myfile);
//Create/Write to the file
FileStream outFile = File.Create(myfile);
XmlSerializer Serializer = new XmlSerializer(typeof(Player));
Serializer.Serialize(outFile, player);
outFile.Close();
}

public static Player Load(string FileName)
{
string myfile = string.Format(@"{1}\AwesomeRPG\Saves\{0}Save.asd", FileName, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));

if (!File.Exists(myfile)) return null;
XmlSerializer Serializer = new XmlSerializer(typeof(Player));
FileStream ReadFileStream = new FileStream(myfile, FileMode.Open, FileAccess.Read, FileShare.Read);
return (Player)Serializer.Deserialize(ReadFileStream);
}
}

如您所想,这将保存 Inv 列表中任何项目的所有详细信息。但是,我希望在游戏开始时加载所有存在的项目(创建它们的实例),并且我需要一种方法让保存文件保存对这些实例的引用,而不是创建新实例。

游戏开始时加载的实例也保存在XML文件中,然后根据元素类型加载到单独的列表中,例如所有ItemEquipmentWeapon实例(继承Item的Inherits ItemEquipment)在一个WeaponItem.aid文件中,该文件是以 XML 格式,并加载到列表中

有什么方法可以通过引用将 Inv 内容保存到播放器保存文件或从播放器保存文件加载,这样我就可以让它们在初始加载期间使用现有实例设置?

编辑:我只是想,了解 Player 类的编码方式可能会对一些人有所帮助,所以这里是:

[Serializable()]
public class Player : Entity
{
public string Name { get; set; }
public int MaxHP { get; set; }
public int Level { get; set; }
public int XP { get; set; }
public int Str { get; set; }
public int End { get; set; }
public int Dex { get; set; }
public int Agi { get; set; }
public int Wis { get; set; }
public int Int { get; set; }

public List<Item> Inv { get; set; }

private ItemEquipmentWeapon lHand;
private ItemEquipmentWeapon rHand;

public ItemEquipmentWeapon LHand
{
get
{ return lHand; }
set
{
if (!value.THand)
{
lHand = value;
}
else lHand = null;
}
}
public ItemEquipmentWeapon RHand
{
get
{ return rHand; }
set
{ rHand = value; }
}

internal Player() { }
public Player(string name, int maxhp, int hp, int lvl, int exp, int str, int end, int dex, int agi, int wis, int inte)
: base(true, hp)
{
Name = name;
MaxHP = maxhp;
Level = lvl;
XP = exp;
Str = str;
End = end;
Dex = dex;
Agi = agi;
Wis = wis;
Int = inte;

Inv = new List<Item>();
}

public List<string> GetInv()
{
List<string> val = new List<string>();

foreach (Item item in Inv)
{
val.Add(item.Name);
}

return val;
}

public void AddItem(Item i, int amt)
{
for (int j = 0; j < amt; j++)
{
Inv.Add(i);
}
}
public void AddItem(Item i){
AddItem(i, 1); }

public void RemoveItem(Item i, int amt)
{
int count = 0;

foreach (Item item in Inv)
{
if (item == i)
{
Inv.Remove(item);
count++;
}
if (count == amt)
{
break;
}
}
}
public void RemoveItem(Item i){
RemoveItem(i, 1); }

public bool HasItem(Item i, int amt)
{
int count = 0;

foreach (Item item in Inv)
{
if (item == i)
{
count++;
}
}

return count >= amt;
}
public bool HasItem(Item i){
return HasItem(i, 1); }
}

显然,在游戏加载时从 XML 加载项目实例的代码也非常有用,但我还没有编写代码,我不是 100% 确定我将如何去做。不过到目前为止,我有这个:

public static class InitLoad
{
static List<ItemEquipmentWeapon> weapons;

public static void PreLoading()
{
string path, filePath,
weaponFile = @"\WeaponsItem.aid";
XmlSerializer SerializerObj;
FileStream ReadFileStream;

path = string.Format(@"{0}\AwesomeRPG\Data\Items",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));

filePath = string.Format(@"{0}\{1}", path, weaponFile);
SerializerObj = new XmlSerializer(typeof(ItemEquipmentWeapon));
ReadFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
weapons = (List<ItemEquipmentWeapon>)SerializerObj.Deserialize(ReadFileStream);
}
}

在此先感谢您的帮助!

最佳答案

Is there any way I can save and load the Inv contents to and from the player save file by reference so I can have them use the existing instances setup during initial loading?

这是解决这个问题的一种方法:
1. 添加到您的Itemint领域 Id或类似的东西,并为每个唯一项目分配适当的唯一值。
2. 在初始加载期间,为游戏中的所有独特项目创建一个全局缓存。对于这个问题,我建议使用 Dictionary<int, Item>关键是Id项目和值(value)将是项目本身。
3. 在你的Player你应该只存储类 Id的项目,因此在加载期间您可以获得 Item 的实例来自前面提到的全局缓存。

此外,您可能想阅读有关 flyweight 的内容模式,这几乎与共享实例有关。

关于c# - 如何在 XML 中保存对象实例的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20198497/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com