Как совместить эти 2 оператора Cocos2D if? - PullRequest
2 голосов
/ 28 января 2012

Я ищу простой способ объединить эти 2 оператора if в моем приложении Cocos2D.Однако мои попытки пока не сработали.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 28 января 2012

Я полагаю, что ваша попытка объединить утверждения if в одну из ваших проблем связана с пониманием этого утверждения. Как программист, ваша первая и главная обязанность - писать читаемый код, даже если вы единственный человек, который когда-либо его читал. Другая причина, по которой я могу подумать, почему вам нужен только один вариант, если вы утверждаете, что каким-то образом вы думаете, что это будет быстрее.

Итак, сначала я бы переместил все вычисления из предложений if. Это не только повторяющееся, но и подверженное ошибкам и очень трудное для чтения. Я также позволил себе заменить деление на два умножением на 0,5f, потому что процессоры ARM не имеют инструкций деления, поэтому деления выполняются программным обеспечением и в любом случае переписываются как умножение. Возможно, компилятор уже оптимизирует это, но, тем не менее, рекомендуется избегать операций деления, если вы можете.

Итак, вот как бы я написал заявление. Дополнительные локальные переменные не приводят к снижению производительности. Обычно компилятор все равно делает что-то подобное. Аналогично, если spriteA.tag не равен 1, условие не оценивает остаток первого условия if и переходит прямо к проверке части else if. Это называется «ранним выходом»: при первом тесте, который приведет к сбою всего условия, программа прекратит оценку оставшихся тестов, потому что в этом нет никакого смысла. Поэтому рекомендуется начинать оператор if (или вложенный if) с условием, которое чаще всего не выполняется.

float spriteAHalfWidth = spriteA.boundingBox.size.height * 0.5f;
float spriteBHalfWidth = spriteB.boundingBox.size.height * 0.5f;

float spriteALeftSide = spriteA.position.x - spriteAHalfWidth;
float spriteARightSide = spriteA.position.x + spriteAHalfWidth;
float spriteBLeftSide = spriteB.position.x - spriteBHalfWidth;
float spriteBRightSide = spriteB.position.x + spriteBHalfWidth;

if (died == NO)
{
    if (spriteA.tag == 1 && spriteB.tag == 4 && 
        spriteALeftSide <= spriteBRightSide)
    {
        float y = spriteB.position.y + spriteBHalfWidth +
                  sprite.boundingBox.size.height * 0.5f;
        sprite.position = ccp(pos.x, y);
    } 
    else if (spriteA.tag == 4 && spriteB.tag == 1 && 
             spriteBLeftSide <= spriteARightSide) 
    {
        float y = spriteA.position.y + spriteAHalfWidth +
                  sprite.boundingBox.size.height * 0.5f;
        sprite.position = ccp(pos.x, y);
    }
}

Излишне говорить, что вы не можете объединить это в одном операторе if. В конце вы выполняете две разные функции (обновите позицию на основе позиции y spriteA или spriteB). Поэтому вам необходимо иметь две ветви.

Если вы хотите, вы можете добавить died == NO в качестве первого теста в обоих вложенных выражениях if, если вы действительно хотите избежать самого внешнего предложения if. Однако при этом ваша программа будет всегда тестировать на died == NO дважды, даже если переменная скончалась. С другой стороны, возможно, что компилятор также распознает и оптимизирует эту ситуацию.

2 голосов
/ 28 января 2012

Вам не нужны вложенные условия IF, потому что они могут быть перемещены во внешние условные проверки следующим образом:

    if ((!died)
            && (spriteA.tag == 1)
            && (spriteB.tag == 4)
            && (spriteA.position.x - spriteA.boundingBox.size.height / 2 <= spriteB.position.x + spriteB.boundingBox.size.height / 2)) {
        sprite.position = ccp(pos.x, spriteB.position.y + spriteB.boundingBox.size.height / 2 + sprite.boundingBox.size.height / 2);
    } else if ((!died)
            && (spriteA.tag == 4)
            && (spriteB.tag == 1)
            && (spriteB.position.x - spriteB.boundingBox.size.height / 2 <= spriteA.position.x + spriteA.boundingBox.size.height / 2)) {
        sprite.position = ccp(pos.x, spriteA.position.y + spriteA.boundingBox.size.height / 2 + sprite.boundingBox.size.height / 2);
    }
1 голос
/ 28 января 2012

Вы можете сделать это:

if ((spriteA.tag == 1 && spriteB.tag == 4) || (spriteA.tag == 4 && spriteB.tag == 1)) {
    if ((spriteA.position.x - spriteA.boundingBox.size.height / 2 <= spriteB.position.x + spriteB.boundingBox.size.height / 2) && !died) {
        sprite.position = ccp(pos.x, spriteB.position.y + spriteB.boundingBox.size.height / 2 + sprite.boundingBox.size.height / 2);
    }
}

или если это действительно просто один оператор if по какой-то причине, то вы можете сделать это:

if (((spriteA.tag == 1 && spriteB.tag == 4) || (spriteA.tag == 4 && spriteB.tag == 1))
    && ((spriteA.position.x - spriteA.boundingBox.size.height / 2 <= spriteB.position.x + spriteB.boundingBox.size.height / 2) && !died)) {
        sprite.position = ccp(pos.x, spriteB.position.y + spriteB.boundingBox.size.height / 2 + sprite.boundingBox.size.height / 2);
}

В любом случае это довольно некрасиво.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...