unsigned int CCSpriteBatchNode::atlasIndexForChild(CCSprite *pobSprite, int nZ) { NSMutableArray<CCNode*> *pBrothers = pobSprite->getParent()->getChildren(); unsigned int uChildIndex = pBrothers->getIndexOfObject(pobSprite); // ignore parent Z if parent is spriteSheet bool bIgnoreParent = (CCSpriteBatchNode*)(pobSprite->getParent()) == this; CCSprite *pPrevious = NULL; if (uChildIndex > 0) { pPrevious = (CCSprite*)(pBrothers->getObjectAtIndex(uChildIndex - 1)); } // first child of the sprite sheet if (bIgnoreParent) { if (uChildIndex == 0) { return 0; } return highestAtlasIndexInChild(pPrevious) + 1; } // parent is a CCSprite, so, it must be taken into account // first child of an CCSprite ? if (uChildIndex == 0) { CCSprite *p = (CCSprite*)(pobSprite->getParent()); // less than parent and brothers if (nZ < 0) { return p->getAtlasIndex(); } else { return p->getAtlasIndex() + 1; } } else { // previous & sprite belong to the same branch if ((pPrevious->getZOrder() < 0 && nZ < 0) || (pPrevious->getZOrder() >= 0 && nZ >= 0)) { return highestAtlasIndexInChild(pPrevious) + 1; } // else (previous < 0 and sprite >= 0 ) CCSprite *p = (CCSprite*)(pobSprite->getParent()); return p->getAtlasIndex() + 1; } // Should not happen. Error calculating Z on SpriteSheet assert(0); return 0; }
// CCTMXLayer - adding helper methods CCSprite * CCTMXLayer::insertTileForGID(unsigned int gid, const CCPoint& pos) { CCRect rect = m_pTileSet->rectForGID(gid); rect = CCRectMake(rect.origin.x / m_fContentScaleFactor, rect.origin.y / m_fContentScaleFactor, rect.size.width/ m_fContentScaleFactor, rect.size.height/ m_fContentScaleFactor); int z = (int)(pos.x + pos.y * m_tLayerSize.width); if( ! m_pReusedTile ) { m_pReusedTile = new CCSprite(); m_pReusedTile->initWithBatchNode(this, rect); } else { m_pReusedTile->initWithBatchNode(this, rect); } m_pReusedTile->setPositionInPixels(positionAt(pos)); m_pReusedTile->setVertexZ((float)vertexZForPos(pos)); m_pReusedTile->setAnchorPoint(CCPointZero); m_pReusedTile->setOpacity(m_cOpacity); // get atlas index unsigned int indexForZ = atlasIndexForNewZ(z); // Optimization: add the quad without adding a child this->addQuadFromSprite(m_pReusedTile, indexForZ); // insert it into the local atlasindex array ccCArrayInsertValueAtIndex(m_pAtlasIndexArray, (void*)z, indexForZ); // update possible children if (m_pChildren && m_pChildren->count()>0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCSprite* pChild = (CCSprite*) pObject; if (pChild) { unsigned int ai = pChild->getAtlasIndex(); if ( ai >= indexForZ ) { pChild->setAtlasIndex(ai+1); } } }
void CCSpriteBatchNode::removeSpriteFromAtlas(CCSprite *pobSprite) { // remove from TextureAtlas m_pobTextureAtlas->removeQuadAtIndex(pobSprite->getAtlasIndex()); // Cleanup sprite. It might be reused (issue #569) pobSprite->useSelfRender(); unsigned int uIndex = m_pobDescendants->getIndexOfObject(pobSprite); if (uIndex != -1) { m_pobDescendants->removeObjectAtIndex(uIndex); // update all sprites beyond this one unsigned int count = m_pobDescendants->count(); for(; uIndex < count; ++uIndex) { CCSprite* s = (CCSprite*)(m_pobDescendants->getObjectAtIndex(uIndex)); s->setAtlasIndex( s->getAtlasIndex() - 1 ); } } // remove children recursively NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren(); if (pChildren && pChildren->count() > 0) { CCSprite *pSprite; NSMutableArray<CCNode*>::NSMutableArrayIterator iter; for (iter = pChildren->begin(); iter != pChildren->end(); ++iter) { pSprite = (CCSprite*)(*iter); if (! pSprite) { break; } removeSpriteFromAtlas(pSprite); } } }
// CCTMXLayer - adding helper methods CCSprite * CCTMXLayer::insertTileForGID(unsigned int gid, const CCPoint& pos) { CCRect rect = m_pTileSet->rectForGID(gid); rect = CC_RECT_PIXELS_TO_POINTS(rect); intptr_t z = (intptr_t)(pos.x + pos.y * m_tLayerSize.width); // if quad optimization is used CCSprite *tile; if(m_pAtlasIndexArray) { tile = reusedTileWithRect(rect); setupTileSprite(tile, pos, gid); // get atlas index unsigned int indexForZ = atlasIndexForNewZ(z); // Optimization: add the quad without adding a child this->insertQuadFromSprite(tile, indexForZ); // insert it into the local atlasindex array ccCArrayInsertValueAtIndex(m_pAtlasIndexArray, (void*)z, indexForZ); // update possible children if (m_pChildren && m_pChildren->count()>0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCSprite* pChild = (CCSprite*) pObject; if (pChild) { unsigned int ai = pChild->getAtlasIndex(); if ( ai >= indexForZ ) { pChild->setAtlasIndex(ai+1); } } } }