Как обнаружить прикосновение, кроме падающих тел сверху, в игре cocos2d-x ios с использованием С++

В моей игре есть определенные зомби, идущие сверху экрана. Я сохранил все спрайты зомби в CCArray. Затем, используя цикл foreach, я заставляю их падать. Я просто хочу выполнить комбо. Это означает, что всякий раз, когда я убиваю зомби при нажатии, счетчик комбо увеличивается. При убийстве двух последовательных зомби счетчик комбо становится равным 2, но если я коснусь любого другого места на экране, счетчик комбо должен стать равным 0.

Итак, моя проблема заключается в том, как определить, не коснулся ли я зомби и не коснулся ли я любого места на экране. Я также прилагаю свой код метода cctouchbegan.

зомби — это CCArray, в котором хранятся все спрайты зомби.

void Level1::ccTouchesBegan(cocos2d::CCSet *pTouch, cocos2d::CCEvent *pEvent)
{

CCTouch* touch = (CCTouch*)(pTouch->anyObject());
CCPoint location = touch->getLocationInView();
location = CCDirector::sharedDirector()->convertToGL(location);

CCObject* touchedzombie;

CCARRAY_FOREACH(zombies, touchedzombie)
{


    if(!((CCSprite*) touchedzombie)->isVisible())
        continue;
    //

    if(((CCSprite*)touchedzombie)==zombies->objectAtIndex(0))
    {

        //   if((CCSprite*(touchedzombie)==zombies-))
        if(touchedzombie!=NULL&&((CCSprite*)touchedzombie)->boundingBox().containsPoint(location))
        {

            this->setScoreonGame();
            combo_counter++;
            CCString *comboString=CCString::createWithFormat("comboX %d",combo_counter);

            zombies_left--;
            CCLOG("left = %d",zombies_left);
            CCSize tt=((CCSprite*)touchedzombie)->getContentSize();
            CCPoint pos_of_sprite=((CCSprite*)touchedzombie)->getPosition();
            int rand_die1=Level1::random1();
            CCString *str = CCString::createWithFormat("z2%d.png", rand_die1);
            changedSprite = CCSprite::create(str->getCString());
            CCLOG("Inside index 0");

            ((CCSprite*)touchedzombie)->setVisible(false);

            changedSprite->setPositionX(pos_of_sprite.x);
            changedSprite->setPositionY(pos_of_sprite.y);
            changedSprite->setScaleX(Utils::getScaleX());
            changedSprite->setScaleY(Utils::getScaleY());
            this->addChild(changedSprite);


            combo=CCLabelTTF::create(comboString->getCString(), "HoboStd", 50);
            combo->setColor(ccRED);
            combo->setPosition((ccp(changedSprite->getContentSize().width*0.50,changedSprite->getContentSize().height*1.05)));
            changedSprite->addChild(combo,40);



            this->runAction(CCSequence::create(delayAction,
                                               callSelectorAction,
                                               NULL));


            this->removeChild( ((CCSprite*)touchedzombie),true);
            this->Level1::reloadZombies();
            //  touchedzombie=NULL;

        }






    }





    if(((CCSprite*)touchedzombie)==zombies->objectAtIndex(3))
    {


        //   if((CCSprite*(touchedzombie)==zombies-))
        if(touchedzombie!=NULL&&((CCSprite*)touchedzombie)->boundingBox().containsPoint(location))
        {
         //    iftouched++;
            this->setScoreonGame();
            combo_counter++;
            CCString *comboString=CCString::createWithFormat("comboX %d",combo_counter);

            zombies_left--;
            CCLOG("left = %d",zombies_left);
            CCSize tt=((CCSprite*)touchedzombie)->getContentSize();
            CCPoint pos_of_sprite=((CCSprite*)touchedzombie)->getPosition();
            int rand_die1=Level1::random1();
            CCString *str = CCString::createWithFormat("z2%d.png", rand_die1);
            changedSprite3 = CCSprite::create(str->getCString());
            //  CCLOG("%s",str->getCString());


            //  CCLOG("Sprite Toucheddd");
            CCLOG("Inside index 4");
            // CCLog("width= %f  height =%f",tt.width,tt.height);
            // CCLog("x location =%f  y location =%f",location.x,location.y);
            //  CCLog("Positon of Sprite X=%f  Y=%f",pos_of_sprite.x,pos_of_sprite.y);

            ((CCSprite*)touchedzombie)->setVisible(false);

            changedSprite3->setPositionX(pos_of_sprite.x);
            changedSprite3->setPositionY(pos_of_sprite.y);
            changedSprite3->setScaleX(Utils::getScaleX());
            changedSprite3->setScaleY(Utils::getScaleY());
            this->addChild(changedSprite3);

            combo=CCLabelTTF::create(comboString->getCString(), "HoboStd", 50);
            combo->setColor(ccRED);
            combo->setPosition((ccp(changedSprite3->getContentSize().width*0.50,changedSprite3->getContentSize().height*1.05)));
            changedSprite3->addChild(combo,40);


            this->runAction(CCSequence::create(delayAction,
                                               callSelectorAction3,
                                               NULL));

            this->removeChild( ((CCSprite*)touchedzombie),true);
            this->Level1::reloadZombies();
            touchedzombie=NULL;
        }
        //..upto 9 indexes...      
    }
}

person Rajan Maheshwari    schedule 11.02.2014    source источник


Ответы (1)


Во-первых, нет необходимости делать эти проверки: if(((CCSprite*)touchedzombie)==zombies->objectAtIndex(0))

Как работает CCARRAY_FOREACH, он берет каждый объект из предоставленного CCArray и присваивает его вашей переменной touchedZombie - это означает, что если в массиве 10 элементов, этот код будет запущен 10 раз (точно!). Это значит, что при первом прогоне вы попадете в первую if проверку (тот, что с objectAtIndex(0), при втором попадете в if проверку с objectAtIndex(1). Удаление этого if's not не только ускорит вашу функцию, но и приведет в порядок это вверх.

Это сэкономит вам много места, плюс, если вы захотите что-то изменить, вам нужно будет сделать это только в одном месте, что безопаснее.

Хорошо, к проблеме:

Я вижу два решения этого:

  1. Оставьте свой код: вы должны переместить комбо-код из блоков if и заменить его флагом. Этот флаг должен быть установлен на false в начале ccToucheBegan, и если вы обнаружите прикосновение к зомби, установите его на true. Потом после блока CCARRAY_FOREACH этот флаг сообщит, был тап по зомби или нет. Соответственно измените комбо.

  2. Изменение вашего кода: вы также можете сделать зомби CCMenuItemImages - таким образом, у них будет другая функция обратного вызова, чем у остальной части экрана. Поэтому всякий раз, когда будет запущен метод ccTouchBegan, вы будете знать, что это не был затронут зомби.

Надеюсь все понятно, если нет - дайте знать.

person Losiowaty    schedule 12.02.2014