I am currently investigating this issue as well. With the latest github pull from master my code would crash on an assertion upon inserting a new sprite into SpriteBatch.
In insertQuad():
CCAssert( index < m_uCapacity, “insertQuadWithTexture: Invalid index”);
Using Ben & Sergey Buravtsov code allowed me to run my game without having it hit this assertion, however there were artifacts with some tiles being replaced by others, and tiles being removed at a random tile position instead of the tile the code was supposed to remove.
Just for information: In my case my m_pobDecendants were actually ordered in the ccArray in descending order: 152,151,150…
I noticed that the goal of removeSpriteFromAtlas seems to be to remove the tile with an AtlasIndex of uIndex and then decrement every sprite’s atlas index which is greater than uIndex.
So here’s currently the code I’m using that seems to so far not cause any artifacts or crashes. It would appear that Sergey’s code should work if they descendants are indeed ordered correctly at all times in the array, but I’ve noticed they’re ordered both in descending, ascending, and if enough inserts are done in one frame they can even be out of order (10,11,12,13,14,0,1,2,3).
* I will report back if I find it still produces a crash or artifacts
<pre>
void CCSpriteBatchNode::removeSpriteFromAtlas
{
// remove from TextureAtlas
unsigned int atlasIndex = pobSprite~~>getAtlasIndex;
auto descendantsData = m_pobDescendants~~>data;
unsigned int uIndex = ccArrayGetIndexOfObject;
CCLOGERROR (“spriteAtlasIndex = %d, uIndex = %d”, atlasIndex, uIndex);
m_pobTextureAtlas~~>removeQuadAtIndex);
// Cleanup sprite. It might be reused
pobSprite~~>setBatchNode;
if
{
CCObject obj = NULL;
CCARRAY_FOREACH(m_pobDescendants,obj)
{
CCSprite* child = static_cast<CCSprite*>(obj);
if(child)
printf(“removeSpriteFromAtlas: BEFORE: child p - atlasIndex:d\n”, child, child~~>getAtlasIndex);
}
ccArrayRemoveObjectAtIndex;
// update all sprites beyond this one
unsigned int count = descendantsData~~>num;
for(uIndex = 0; uIndex < count; uIndex++)
{
CCSprite s = descendantsData~~>arr[uIndex];
if
{
unsigned int ai = s~~>getAtlasIndex;
if
{
//CCLog;
s->setAtlasIndex;
}
}
}
}
// remove children recursively
CCArraypChildren = pobSprite->getChildren();
if (pChildren && pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(pChildren, pObject)
{
CCSprite* pChild = (CCSprite*) pObject;
if (pChild)
{
removeSpriteFromAtlas(pChild);
}
}
}
}