Использование операторов 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. Вы можете легко расширить его в будущем.

Другие вопросы по тегам