[英]C# Updating a value in a list of objects is updating other values too
我当时正在研究一个简单的回合制RPG游戏。 我当时在战斗系统上工作。 我让它与1个敌人一起使用,并想对其进行更新以在多个敌人上使用。 我产生了多个敌人,但针对他们却遇到了问题。
基本上,敌人存储在一个称为“实际敌人”的列表中。 敌人是在运行时生成的,并且可能在1-3之间。 生成一个标签来显示敌人的名字,并通过双击敌人来选择它。
问题似乎在于敌人的名字。 他们有一个名为characterName的属性来识别敌人。 问题是,可能有2个或更多相同类型的字符(例如3x妖精)。 因此,在生成敌人的代码中,如果列表中已经存在一个,我想在characterName上添加1。 这个想法是给每个敌人一个唯一的名字。
问题是,当我尝试执行此操作时,它会更改所有同名敌人的值,并且这一切都搞砸了。 这是代码的相关部分:
if (EnemyExists(e)) {
e.characterName += c.ToString();
}
c只是一个正在使用的计数器,让我知道它是敌人1、2还是3。
EnemyExists函数如下:
public bool EnemyExists(Enemy e) {
bool exists = false;
int eCount = 0;
foreach (Enemy en in actualEnemies) {
if (en.characterName == e.characterName) {
eCount++;
}
}
if (eCount > 1) {
exists = true;
}
return exists;
}
请注意,所有敌人都以默认名称开始。 对于我正在研究的这个示例,只有两种敌人。 游戏选择1-3之间的随机数,以确定有多少个敌人。 每个敌人将是2个预先定义的敌人之一,并再次随机选择。 这就是为什么我只想在已经存在的名称的末尾添加一个数字。
我怀疑这与我创建敌人列表有关:
public void CreateActualEnemies() {
int r;
int potEnemyNum = potentialEnemies.Count;
int numEnemies;
Random rand = new Random();
numEnemies = rand.Next(1, 4 );
for (int i = 0; i < numEnemies; i++) {
r = rand.Next(0,potEnemyNum);
Enemy ene = new Enemy();
ene = potentialEnemies.ElementAt(r);
actualEnemies.Add(ene);
}
DisplayEnemyDetails();
}
当我添加实际敌人时,是否只是在指向潜在敌人中的地址,所以即使我实例化了一个新的敌人,如果每个敌人都具有相同的名称,它都指向同一位置吗? 我需要正确复制对象吗?
已经很晚了,我很累,但是我觉得我越来越近了,任何帮助都会很大,谢谢。
编辑:
敌人等级:
public class Enemy:Character {
public int xpGiven { get; set; }
public LootTable lootTable { get; set; }
public int goldDropped { get; set; }
public bool alive { get; set; }
public NamedTimer timer { get; set; }
public Enemy() {
alive = true;
xpGiven = 10;
lootTable = new LootTable();
goldDropped = 10;
timer = new NamedTimer();
}
}
分解您的问题:
当我添加实际敌人时,是否只是在指向潜在敌人中的地址,所以即使我实例化了一个新的敌人,如果每个敌人都具有相同的名称,它都指向同一位置吗?
通过做
Enemy ene = new Enemy();
您必须在内存中使用“空白”值引用创建新的指针。 但是,既然你做了
ene = potentialEnemies.ElementAt(r);
您使用对列表中元素的引用来覆盖它。 因此,您对ene
对象所做的任何更改都将反映列表中的项目。
如果要隔离所说的更改,请尝试使用MemberwiseClone
。
从MSDN给出的示例中:
public class Person
{
public int Age;
public string Name;
public IdInfo IdInfo;
public Person ShallowCopy()
{
return (Person) this.MemberwiseClone();
}
public Person DeepCopy()
{
Person other = (Person) this.MemberwiseClone();
other.IdInfo = new IdInfo(IdInfo.IdNumber);
other.Name = String.Copy(Name);
return other;
}
}
1:属性名称应以C#中的大写字母开头。 即public int xpGiven { get; set; }
public int xpGiven { get; set; }
public int xpGiven { get; set; }
应该是public int XpGiven { get; set; }
public int XpGiven { get; set; }
public int XpGiven { get; set; }
。 如果它是一个类变量(未定义get或set),则以小写字母开头。 为了更容易地从局部变量中识别类变量,程序员通常以_开头,尽管这不是强制性的。
2:做==
,请注意enemyA == enemya
将返回false。 使用enemyA.Equals(enemya, StringComparison.OrdinalIgnoreCase)
忽略资本差异。
3:
public void CreateActualEnemies()
{
int r;
int potEnemyNum = potentialEnemies.Count;
int numEnemies;
Random rand = new Random();
numEnemies = rand.Next(1, 4 );
for (int i = 0; i < numEnemies; i++)
{
r = rand.Next(0,potEnemyNum);
Enemy ene = new Enemy();
ene = potentialEnemies.ElementAt(r);
actualEnemies.Add(ene);
}
DisplayEnemyDetails();
}
应该:
public void CreateActualEnemies()
{
Random rand = new Random();
int numEnemies = rand.Next(1, 4 );
for (int i = 0; i < numEnemies; i++)
{
Enemy ene = new Enemy();
ene.characterName = "" + ene.GetType().Name + " " + i; // or something similar to give the ene a unique name.
actualEnemies.Add(ene);
}
DisplayEnemyDetails();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.