В Cocos2d возможно ли использовать несколько тегов для одного объекта? - PullRequest
0 голосов
/ 15 сентября 2011

Я хочу иметь возможность идентифицировать группу объектов для CCSpriteBatchNode, но также идентифицировать подгруппу этой группы.Чтобы сделать что-то похожее на это

CCArray *listOfGameObjects = [sceneSpriteBatchNode children]; 

for (GameObject *tempObject in listOfGameObjects) { 

    if ([tempObject tag] == kBottleTagValue) {

          //make bottle yellow

          if ([tempObject tag] == kBrokenBottleTagValue) {
               //also make bottle smaller
          }
     }
}

В этом примере все бутылки станут желтыми, а если бутылка будет помечена как разбитая, она будет уменьшена.Таким образом, разбитая бутылка должна быть помечена с помощью kBottleTagValue и kBrokenBottleTagValue.Есть ли способ сделать это?потому что, когда я пытаюсь просто добавить два тега, это не получается.

Ответы [ 3 ]

5 голосов
/ 15 сентября 2011

Да, вы можете сделать это с помощью битовой маскировки.Например, определите свой тег следующим образом:

enum
{
   kBottleTagValue = 1 << 0;
   kBrokenBottleTagValue = 1 << 1;
};

Затем отметьте свой спрайт:

[yoursprite setTag:kBottleTagValue|kBrokenBottleTagValue];

Чтобы закончить, проверьте, не разбит ли ваш спрайт бутылки, выполнив что-то подобное:

CCArray *listOfGameObjects = [sceneSpriteBatchNode children]; 
for (GameObject *tempObject in listOfGameObjects)
{ 
    if ([tempObject tag] & kBottleTagValue)
    {
          //make bottle yellow
          if ([tempObject tag] & kBrokenBottleTagValue)
          {
               //also make bottle smaller
          }
     }
}

Надеюсь, это вам поможет.

2 голосов
/ 16 сентября 2011

Использование битовой маскировки является излишним, и нет необходимости злоупотреблять свойством тега.

Кстати о свойствах : вы можете добавить логическое свойство в свой класс и использовать if ([tempObject isClass:[BottleClass class]]) для первого логического элемента.

1 голос
/ 15 сентября 2011

Я на самом деле не знаю Cocos2d, но, исходя из краткого прочтения, я думаю, вы спустились GameObject по какому-либо окольному маршруту с CCNode? В этом случае поле tag является целым числом. Вы не можете сохранить несколько значений, но вы можете использовать его как битовое поле. Например:

#define kTagValueBottle           0x0001
#define kTagValueBroken           0x0002
#define kTagValueAnotherAttribute 0x0004
#define kTagValueAThirdAttribute  0x0008
#define kTagValueAFourthAttribute 0x0010
/* etc */

Затем вы назначаете тип как, например:

object.tag = kTagValueBottle | kTagValueBroken;

Таким образом, он вычисляет побитовое ИЛИ kTagValueBottle и kTagValueBroken и сохраняет его как новый тег. Вы также можете добавить свойство в любое время, используя побитовое ИЛИ:

object.tag |= kTagValueBroken;

Или удалить с помощью побитового И с обратной маской:

object.tag &= ~kTagValueBroken;

Вы бы заменили свои тесты прямого сравнения на тестирование отдельных битов с помощью побитового И:

// if ([tempObject tag] == kBottleTagValue) // old test
if ([tempObject tag] & kBottleTagValue) // new test

Это такая же система, которую Apple использует для таких свойств, как autoresizingFlags на UIView.

Если вы можете справиться с чтением примера кода на PHP, а не с Objective-C, эта показалась самой полезной статьей, которую я мог быстро найти через Google, хотя и по общему признанию из-за тонких выборок.

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