使用cocos2d在等轴测地图上对精灵进行z排序的最佳方式



经过几次头疼之后,我发现将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上的一个非常有趣的开放项目。。他使用了CCSpriteFrameCCSpritesetDisplayFrame方法,而不是批量节点。。。但我不能运行它,因为它似乎是cocos2d的旧版本(显然不能与xcode 4一起工作)

我发现改变CCNodevertexZ属性(就像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);
}

相关内容

  • 没有找到相关文章

最新更新