经过几次头疼之后,我发现将CCSpriteBatchNode
与cocos2d olny一起使用可以对添加到其中的精灵进行z排序(这很明显,现在我看到了…)
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"token_default.plist"];
CCSpriteBatchNode *tokenSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"token_default.png"];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"objects_default.plist"];
CCSpriteBatchNode *objectsSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"objects_default.png"];
CCSprite *token = [[[CCSprite alloc] initWithSpriteFrameName:@"token_SE.png"] autorelease];
[token setPosition:tokenSpawnPoint];
CCSprite *enemy = [[[CCSprite alloc] initWithSpriteFrameName:@"token_blak_SE.png"] autorelease];
[enemy setPosition:enemySpawnPoint];
CCSprite *houseA = [[[CCSprite alloc] initWithSpriteFrameName:@"house_small.png"] autorelease];
[houseA setPosition:[self randomHousePosition]];
CCSprite *houseB = [[[CCSprite alloc] initWithSpriteFrameName:@"house_big.png"] autorelease];
[houseB setPosition:[self randomHousePosition]];
[tokenSpriteSheet addChild:token];
[tokenSpriteSheet addChild:enemy];
[objectsSpriteSheet addChild:houseA];
[objectsSpriteSheet addChild:houseB];
由于我必须将它们添加到显示列表中,如下所示。。
[_isoMap addChild:objectsSpriteSheet];
[_isoMap addChild:tokenSpriteSheet];
我无法更改其他房屋之间单个代币的z顺序
它们将始终在房子上渲染,直到我更改这些批处理节点的顺序
顺便说一句,我可以将所有精灵的艺术"合并"在一个大的单批节点中。。。这样就可以使用精灵的坐标来订购精灵
[fullSpriteSheet reorderChild:token z:token.position.y];
我有点拘泥于此……有没有一种方法可以实现这一点,使用不同的sprite-bacth节点?或者可以通过编程方式合并两个批处理节点?
我发现了KnightFight,这是LozArcher在github上的一个非常有趣的开放项目。。他使用了CCSpriteFrame
和CCSprite
的setDisplayFrame
方法,而不是批量节点。。。但我不能运行它,因为它似乎是cocos2d的旧版本(显然不能与xcode 4一起工作)
我发现改变CCNode
的vertexZ
属性(就像CCSprite
一样)实际上会改变其Z位置(因此它会稍微大/小,也会被翻译)
因此,为了用不同的spriteSheet在z索引CCSprites上排列,我不得不使用reorderChild
方法(只是改变渲染顺序),而且大多数情况下我不需要使用CCSpriteBatchNode
。。
在对上面的例子进行了一点重构之后,我应该有:
CCSprite *token = [CCSprite spriteWithSpriteFrameName:@"token_SE.png"];
[token setPosition:tokenSpawnPoint];
CCSprite *enemy = [CCSprite spriteWithSpriteFrameName:@"token_blak_SE.png"];
[enemy setPosition:enemySpawnPoint];
CCSprite *houseA = [CCSprite spriteWithSpriteFrameName:@"house_small.png"];
[houseA setPosition:[self randomHousePosition]];
CCSprite *houseB = [CCSprite spriteWithSpriteFrameName:@"house_big.png"];
[houseB setPosition:[self randomHousePosition]];
[_isoMap addChild:token];
[_isoMap addChild:enemy];
[_isoMap addChild:houseA];
[_isoMap addChild:houseB];
我还将每个精灵添加到NSMutableArray
然后在for循环中(在update
调度方法内):
CCSprite *sprite = [mySpritesArray objectAtIndex:i];
[_isoMap reorderChild:sprite z:(_isoMap.mapSize.height - sprite.y)];
希望这能帮助到某人:)
我仍然认为这不是更好的解决方案,如果您在地图上的对象是动态移动的,您仍然可能陷入z顺序问题。
我知道它非常古老的帖子,人们不断通过谷歌搜索来这里,所以我在这里发布解决方案。
float lowestZ = tilemap.map.width +tilemap.map.height ;
float currentZ = self.gridLocation.x + self.gridLocation.y ;
int zOrderDecided = lowestZ + currentZ - 1 ;
[self.parent reorderChild:self z:zOrderDecided];
将精灵的Z顺序设置为其在地图上的Y位置。在更新循环中重新排列动态精灵。使用精灵当前的Y位置和贴图的可见高度计算Z顺序。
void LocalGameController::SetZOrderForObject(cocos2d::Sprite *object){
int objectZOrder = visibleSize.height - object->getPositionY();
context->reorderChild(object, objectZOrder);
}