C# 继承未按预期工作
类C# 继承未按预期工作,c#,class,inheritance,typeof,C#,Class,Inheritance,Typeof,类敌人和矿石是实体类的孩子。类小行星是敌人的后代。当我的飞船碰到任何实体时,下面的代码被触发 两句话中的代码是:当船接触到矿石时,将矿石添加到船的库存中,并将矿石从屏幕上移除。当船碰到敌人时,检查它是什么敌人。如果是小行星,将飞船推回,降低其生命值并删除该小行星 if (entities[j] is Ore) { pilots[i].Ship.InventoryAdd(entities[j]); entities.RemoveAt(j--); } if (entities[j] is Enem
敌人
和矿石
是实体
类的孩子。类小行星
是敌人
的后代。当我的飞船碰到任何实体时,下面的代码被触发
两句话中的代码是:当船接触到矿石时,将矿石添加到船的库存中,并将矿石从屏幕上移除。当船碰到敌人时,检查它是什么敌人。如果是小行星,将飞船推回,降低其生命值并删除该小行星
if (entities[j] is Ore)
{ pilots[i].Ship.InventoryAdd(entities[j]); entities.RemoveAt(j--); }
if (entities[j] is Enemy)
{
if(entities[j] is Asteroid)
{
pilots[i].Ship.AddForce(entities[j].Force * (entities[j] as Enemy).Damage);
pilots[i].Ship.HP -= (entities[j] as Enemy).Damage;
entities.RemoveAt(j);
}
}
注意我看到在一个更新或帧中,两次碰撞都在发生(飞船与小行星和飞船与矿石)时可能会触发的问题,我会解决这个问题。此外,这是整个代码,而不仅仅是所有案例的一部分。现在,我的屏幕上只有矿石和小行星(还有一艘船)
船舶和矿石碰撞的问题正在发生。我的船被推回了。但我只在飞船对小行星的比赛中这么做。这意味着该计划将矿石视为小行星,而事实并非如此。这些东西我都检查了好几次。是的,它们都有相同的父代,但如果我问一个实例是否是小行星,他怎么能说“是的,而且也是矿石”,而事实并非如此
我知道,如果我问一个小行星的例子,如果它是类实体,敌人和小行星,我总是会得到一个答案“是”,但矿石怎么可能是小行星呢
问题是:这背后的逻辑是什么?我如何正确地检查这一点?另外请注意,用于增加力量的线将向所有敌人开火,而不仅仅是小行星,目前的情况就是如此。您正在处理
实体
阵列中的两个不同元素。因为从数组中删除了条目,所以第二个if
在不同的元素上工作
如果
if (entities[j] is Ore)
{
pilots[i].Ship.InventoryAdd(entities[j]); entities.RemoveAt(j--);
}
else if (entities[j] is Enemy)
{
if(entities[j] is Asteroid)
{
pilots[i].Ship.AddForce(entities[j].Force * (entities[j] as Enemy).Damage);
pilots[i].Ship.HP -= (entities[j] as Enemy).Damage;
entities.RemoveAt(j);
}
}
删除索引“j”处的对象,然后重新检查实体[j]。因此,如果8处有矿石,9处有星象,则移除矿石,将星象放在第二个if之前的8处。您可能需要将第二个if更改为else if。现在发生的情况是,如果你的飞船与矿石发生碰撞,它会将矿石添加到库存中(如预期的那样),然后将实体数组中的索引减少1 在减少之后,您检查当前索引中的实体是否是敌人,因此您基本上看到的是与以前完全不同的实体 将第二个检查更改为
else if (entities[j] is Enemy)
应该防止这种情况
希望这有帮助
弗劳克好吧,假设您遇到这种情况: j=8是您正在碰撞的矿石
j=7是一个你没有碰撞到的星号 因为你做了j——在处理一个矿石之后,实体[j]现在将指向一个星号,即使没有与星号发生碰撞。然后HP被减去,等等 您没有继承问题,您有一个“在循环期间弄乱循环变量”的问题 你可以这样做:
if (entities[j] is Ore)
{
pilots[i].Ship.InventoryAdd(entities[j]);
entityIndexesToRemove.add(j);
}
if (entities[j] is Enemy)
{
if(entities[j] is Asteroid)
{
pilots[i].Ship.AddForce(entities[j].Force * (entities[j] as Enemy).Damage);
pilots[i].Ship.HP -= (entities[j] as Enemy).Damage;
entityIndexesToRemove.add(j);
}
}
// then rest of that loop on j ...
// then later when loop has finished we do removals....
for (int r=entitiesToRemove.Count; r>0;r--)
entities.RemoveAt(entitiesToRemove[r]);
这是什么逻辑?逻辑只属于您:-)在
Ore
的情况下,您会更改实体
,这样索引j
很可能不会指向Ore
更长的时间。您为什么会假设继承以某种方式被破坏?你试过调试代码吗?为什么您认为egentitiers.RemoveAt
将使实体[j]
指向同一实例?如果您使用is
关键字,在大多数情况下,您的代码都有设计问题。如果您在基类上定义一个Collision
事件,并让每个类型都实现处理程序,那会好得多。@Monset而且正如大家所指出的,您有一个索引问题。这既不是最小的,也不是强制性的。它不会编译。但如果它真的出现了,它就不会出现问题,即使您是对的,并且存在继承错误,我们也无法复制它。PS我没有投反对票,但几乎其他人都投了。或者干脆避免到处使用实体[j]
。只需将内容分配给一个临时变量即可。此操作非常有效。谢谢请看我写的大屁股便条wrote@Monset请阅读并理解这些评论和建议answers@MonsetMaarten是对的,你需要理解他在说什么检查我批准的答案,你就会看到它是如何在不改变我的方式的情况下解决我的问题的entities@Monset是的Nineberry的回答很好,但是你知道为什么它会起作用,以及最初的问题是什么吗?