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

时间:2012-03-31 16:41:28

标签: cocos2d-iphone isometric

经过几次头痛我发现使用CCSpriteBatchNode与cocos2d olny允许z-order精灵作为孩子添加到它(这很明显,现在我看到..)

    [[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];

我有点坚持......有没有办法实现这一点,有不同的精灵bacth节点?或者可以以编程方式合并两个batchnodes? (或类似的东西)

我找到了KnightFight,这是一个非常有趣的开放项目,由LozArcher在github上开发..他使用了CCSpriteFrameCCSprite的{​​{1}}方法,而不是批处理节点。但我无法运行它,因为它似乎是cocos2d的旧版本(显然不适用于xcode 4)

3 个答案:

答案 0 :(得分:0)

我发现更改vertexZ的{​​{1}}属性(如CCNode)它实际上会更改其Z位置(因此它会稍微更大/更小,并且还会翻译)

所以,为了安排z-index CCSprites与不同的spriteSheet我必须使用CCSprite方法(只是改变渲染顺序),而且大多数情况下我不需要使用reorderChild .. < / p>

在对上面的例子进行了一些重构之后,我应该:

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]; 然后在for循环中(在NSMutableArray预定方法内):

update

希望这可以帮助某人:)

答案 1 :(得分:0)

我仍然认为这不是更好的解决方案, 如果地图上的对象动态移动,您仍然可能会遇到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];

答案 2 :(得分:0)

将Sprite Z顺序设置为地图上的Y位置。在更新循环中重新排序动态精灵。使用Sprites当前Y位置和地图的可见高度计算Z顺序。

void LocalGameController::SetZOrderForObject(cocos2d::Sprite *object){
  int objectZOrder = visibleSize.height - object->getPositionY();
  context->reorderChild(object, objectZOrder);
}