修改: 得到了答案,我将播放器中的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); }
}
希望这可以帮助其他人!
原始问题:
所以,我正在制作一个愚蠢的小型RPG游戏,用Windows窗体来测试我的技能,而且我正在整理保存。目前它保存到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的ItemEquipment)都在WeaponItem.aid文件中,这是以XML格式,并加载到List
有什么方法可以通过引用保存和加载来自播放器保存文件的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);
}
}
提前感谢您的帮助!
答案 0 :(得分:2)
有什么方法可以通过引用保存和加载来自播放器保存文件的Inv内容,这样我可以让它们在初始加载时使用现有的实例设置吗?
以下是解决此问题的一种方法:
1.添加到您的Item
课程int
字段Id
或类似内容,并为每个唯一项目指定适当的唯一值。
2.在初始加载期间,创建游戏中所有唯一项目的全局缓存。对于这个问题,我建议使用Dictionary<int, Item>
,其中项的关键字为Id
,值为项目本身。
3.在Player
类中,您应该只存储Id
个项目,因此在加载期间,您可以从前面提到的全局缓存中获取Item
的实例。
此外,您可能希望了解flyweight模式,这几乎与共享实例有关。