编辑: 得到了答案,我将播放器中的列表 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. 添加到您的Item类 int领域 Id或类似的东西,并为每个唯一项目分配适当的唯一值。
2. 在初始加载期间,为游戏中的所有独特项目创建一个全局缓存。对于这个问题,我建议使用 Dictionary<int, Item>关键是Id项目和值(value)将是项目本身。
3. 在你的Player你应该只存储类 Id的项目,因此在加载期间您可以获得 Item 的实例来自前面提到的全局缓存。
此外,您可能想阅读有关 flyweight 的内容模式,这几乎与共享实例有关。
关于c# - 如何在 XML 中保存对象实例的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20198497/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg