开发者

In Cocos2d is it possible to use multiple tags for a single object?

开发者 https://www.devze.com 2023-04-05 07:33 出处:网络
I want to be able to identify a group of objects for a CCSpriteBatchNode, but also identify a sub group of that group. To do something similar to this

I want to be able to identify a group of objects for a CCSpriteBatchNode, but also identify a sub group of that group. To do something similar to this

CCArray *listOfGameObjects = 开发者_如何学C[sceneSpriteBatchNode children]; 

for (GameObject *tempObject in listOfGameObjects) { 

    if ([tempObject tag] == kBottleTagValue) {

          //make bottle yellow

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

In the example all bottles would be turned yellow, and if the bottle was also tagged as broken it would be made smaller. So the broken bottle would need to be tagged with kBottleTagValue and kBrokenBottleTagValue. Is there away to do this? cause when I try to just add two tags it fails.


Yes you can do that using bit masking. For example define your tag like that:

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

Then tag your sprite:

[yoursprite setTag:kBottleTagValue|kBrokenBottleTagValue];

To finish you can check if your sprite is a broken bottles by doing something like that:

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

I hope it'll help you.


Using bitmasking is overkill and there's no need to abuse the tag property.

Speaking of properties: You can add a boolean property to your class and use if ([tempObject isClass:[BottleClass class]]) for the first logic gate.


I don't actually know Cocos2d but based on a quick reading, I guess you've descended GameObject, by whatever roundabout route, from CCNode? In that case the tag field is an integer. You can't store multiple values to it, but you could use it as a bit field. For example:

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

You'd then assign the type as, for example:

object.tag = kTagValueBottle | kTagValueBroken;

So that computes the bitwise OR of kTagValueBottle and kTagValueBroken, and stores it as the new tag. You could also add a property at any time using a bitwise OR:

object.tag |= kTagValueBroken;

Or remove by using a bitwise AND with the inverse mask:

object.tag &= ~kTagValueBroken;

You'd replace your direct comparison tests with testing individual bits via a bitwise AND:

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

This is the same sort of system that Apple use for properties like autoresizingFlags on UIView.

If you can handle reading example code in PHP rather than Objective-C, this seemed to be the most helpful article that I could find quickly through Google, though admittedly from slender pickings.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号