继承不按预期工作

时间:2016-05-25 14:03:46

标签: c# class inheritance typeof

EnemyOreEntity类的子级。班级AsteroidEnemy的孩子。当我的船接触任何实体时,会触发下面的代码。

一句话中的代码是:当船舶接触矿石时,将矿石添加到船舶的库存中并从筛网中移除该矿石。当船接触敌人时,检查它是什么敌人。如果是小行星,请向后推船,降低它的健康状况并删除该小行星。

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);
    }
}

注意我看到在一次更新或框架中可以触发的问题,两次碰撞都在发生(发货与小行星和船舶与矿石),我将解决这个问题。此外,这是整个代码,而不仅仅是所有情况的一部分。现在,我在屏幕上只有矿石和小行星(和一艘船)。

船舶与矿石碰撞发生问题。我的船被推回去了。但我只在船上与小行星上做到这一点。这意味着该计划将矿石视为小行星,而不是。我多次检查了所有这些东西。是的,他们都有同一个父母,但是如果我问一个实例是否是小行星,他怎么能说'是的,而且它也是一个原因"当它是不。

如果我要求一个Asteroid实例,如果它是Entity,Enemy和Asteroid类,我会得到答案,我总会得到一个答案"是",但是Ore怎么可能成为小行星?

问题是:这背后的逻辑是什么,如何以正确的方式检查?还要注意,增加力量的线将为所有敌人射击,而不仅仅是小行星,这是现在的情况。

4 个答案:

答案 0 :(得分:7)

您正在处理entities数组中的两个不同元素。因为从数组中删除了条目,所以第二个if适用于不同的元素。

使用else 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);
    }
}

答案 1 :(得分:4)

删除索引" j"上的对象,然后重新检查实体[j]。因此,如果有8的矿石和9的Astroid,那么在第2个if之前将Astroid放在8处除去矿石。

答案 2 :(得分:4)

您可能想要将第二个if更改为else if。现在发生的事情是,如果你的船与矿石碰撞,它会将矿石添加到库存中(按预期),然后将索引减少到你的实体数组中。

减少之后,你会检查当前索引处的实体是否是敌人,所以你基本上就像以前一样看待一个完全不同的实体。

将第二张支票更改为

else if (entities[j] is Enemy)

应该阻止它。

希望这有帮助,

Frauke

答案 3 :(得分:3)

好吧,假设你有这种情况:

j = 8是你与之相撞的矿石 j = 7是你不与

发生碰撞的星号

因为你在处理矿石之后做了j--所以实体[j]现在将指向一个Asteriod ,即使没有碰撞。然后惠普被减去等等。

你没有继承问题,你在循环过程中遇到“搞乱循环变量”的问题。

你可以这样做:

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]);