Лучший способ для z-упорядочивания спрайтов на изометрической карте с cocos2d - PullRequest
0 голосов
/ 31 марта 2012

после нескольких головных болей я понял, что использование 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];

Я немного застрял в этом ...... есть ли способ достичь этого, имея разные спакт-бакт-узлы? или можно программно объединить два батчода? (или что-то в этом роде)

я нашел KnightFight , действительно интересный открытый проект на github от LozArcher .. он использовал CCSpriteFrame и CCSprite метод setDisplayFrame вместо пакетных узлов ... но я могу не запускайте его, так как он кажется более старой версией cocos2d (очевидно, не работает с xcode 4)

Ответы [ 3 ]

0 голосов
/ 12 февраля 2014

Я все еще думаю, что это не лучшее решение, если ваши объекты на карте движутся динамически, вы все равно можете застрять в проблемах с z-порядком.

Я знаю его очень старый пост, и люди продолжают приходить сюда через Googleпоиск, поэтому я выкладываю решение здесь.

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];
0 голосов
/ 05 июня 2017

Установите порядок спрайтов Z в положение Y на карте. Изменение порядка динамических спрайтов в цикле обновления. Рассчитайте Z-порядок, используя текущее положение спрайтов Y и видимую высоту карты.

void LocalGameController::SetZOrderForObject(cocos2d::Sprite *object){
  int objectZOrder = visibleSize.height - object->getPositionY();
  context->reorderChild(object, objectZOrder);
}
0 голосов
/ 03 апреля 2012

я обнаружил, что при изменении свойства vertexZ для CCNode (например, CCSprite) он фактически меняет свою позицию Z (поэтому он будет немного больше / меньше, а также переведен)

так, чтобы упорядочить CCSprites по z-index с различными spriteSheet, мне пришлось использовать метод 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)];

надеюсь, это кому-нибудь поможет:)

...