2

我目前正在 AndEngine 中开发一个游戏,我已经通过检查每辆车与敌人数组的每个单独索引来设置我与敌人的碰撞检测,因为出于某种原因,for 循环不起作用。这非常不方便,因为它不仅使增加和减少敌人成为一件苦差事,而且看起来很糟糕!它看起来像这样:

if (rManager.getInstance().iceArray[0].getIceSprite().collidesWith(rManager.getInstance().carArray[r].getCarSprite()))
{
    rManager.getInstance().carArray[r].setCarSpeed(1f);
} else if (rManager.getInstance().iceArray[1].getIceSprite().collidesWith(rManager.getInstance().carArray[r].getCarSprite())) {
    rManager.getInstance().carArray[r].setCarSpeed(1f);
} else if (rManager.getInstance().iceBergArray[0].getIceBergSprite().collidesWith(rManager.getInstance().carArray[r].getCarSprite())) {
    rManager.getInstance().carArray[r].setCarSpeed(0f);
} else {
    rManager.getInstance().carArray[r].setCarSpeed(0.5f);
}   

我尝试的 for 循环是这样的, [r] 是汽车阵列的每一辆车,但它似乎没有做任何事情。

for (int h = 0; h < rManager.getInstance().snowArray.length; h++)
{
    if (rManager.getInstance().snowArray[h].getSnowSprite().collidesWith(rManager.getInstance().carArray[r].getCarSprite())) {
        String temp = rManager.getInstance().carArray[r].toString();
        Log.e("SNOW", "SNOWWWWW!" + rManager.getInstance().snowArray[h].toString());
        rManager.getInstance().carArray[r].setCarSpeed(0.2f);
    }
}

谢谢!!

4

1 回答 1

4

您应该使用工厂模式或策略模式来删除 if else。

请参阅下面的链接以供参考。

http://www.cumps.be/nl/blog/read/design-patterns-strategy-pattern

还是没有“switch”语句的策略模式?

编辑

根据您的代码,startegy 模式应该实现下面的伪代码。我根据您上面已经发布的代码做了一些假设。

您将创建一个包含逻辑和适当操作的字典,如下所示:

 Dictionary<Func<RManager, int, bool>, Action<Car>> 
 ruleUpdates = 
 new Dictionary<Func<RManager, int, bool>, Action<Car>>();

每个Func<Ice, Car, bool>你应该像这样实现

private bool ZeroElementEqualIcePrite(RManager rManager, int r)
    {
        return rManager.getInstance().iceArray[0].collidesWith(rManager.getInstance().carArray[r].getCarSprite());
    }

和行动应执行如下:

public static void DoUpdateOneLevel(Car car)
{
    car.setCarSpeed(1f);
}

从那里我们可以用相同的方式在您的代码之后实现类似的所有逻辑。您可以在下面初始化字典

ruleUpdates.Add(FirstElementEqualIcePrite, DoUpdateOneLevel);
ruleUpdates.Add(SecondElementEqualIcePrite, DoUpdateOneLevel);
ruleUpdates.Add(FirstElementEqualIceBergPrite, DoUpdateZeroSpeed);
ruleUpdates.Add(SecondElementEqualIceBergPrite, DoUpdateZeroSpeed);

之后,您只需循环遍历 executionList 的每个键,如下所示。

foreach (KeyValuePair<Func<RManager, int, bool>, Action<Car>> 
 ruleUpdate in ruleUpdates)
    {
       if (ruleUpdate.Key.Invoke(rManager, r))
       {
          ruleUpdate.Value.Invoke(rManager.getInstance().carArray[r]);
          break;
       }
    }

希望这有帮助。遵循该策略,您的代码将干净且易于更改,也不太关心 if / then / else 逻辑。您可以在将来轻松扩展它。

于 2013-04-25T18:46:35.203 回答