Использование операторов if/if else/else для обнаружения столкновений. Как улучшить?
В настоящее время я разрабатываю игру в 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);
}
}
Спасибо!!
1 ответ
Вы должны использовать фабричный шаблон или стратегический шаблон, чтобы удалить if if else.
Пожалуйста, смотрите ссылку ниже, чтобы взять ссылку.
http://www.cumps.be/nl/blog/read/design-patterns-strategy-pattern
или шаблон стратегии без "переключателей"?
РЕДАКТИРОВАТЬ:
Основываясь на вашем коде, шаблон стратегии должен реализовывать следующий псевдокод ниже. Я сделал некоторые предположения, основываясь на вашем коде, уже опубликованном выше.
Вы создадите словарь, содержащий логику и соответствующие действия, как показано ниже:
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);
После этого вы просто просматриваете каждый ключ executeList, как показано ниже.
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. Вы можете легко расширить его в будущем.