CCMenu is not safe when the selecting menu item is deleted (touched, then deleted MenuItem when finger still touching). In function CCMenu::ccTouchEnded and ccTouchCancelled, it uses m_pSelectedItem inited from ccTouchBegan. The menu item node can be deleted without notifying CCMenu. Therefore to use m_pSelectedItem directly is not safe. I don’t know why cocos2dx keeps that pointer, the current selected item can be get through itemForTouch function.
Another suggestion is, except for using texture filename for functions like initWithFile, it is more useful to provide static functions like initWithTexture. Especially for those base nodes such as CCAtlasNode.
I think it is better to use initWithTexture since we can load and free the texture manually.
I added these functions:
static CCAtlasNode * atlasWithTileTexture(CCTexture2D* texture,int tileWidth, int tileHeight, int itemsToRender);
bool initWithTileTexture(CCTexture2D* texture, int tileWidth, int tileHeight, int itemsToRender);
CCAtlasNode * CCAtlasNode::atlasWithTileTexture(CCTexture2D *texture, int tileWidth, int tileHeight, int itemsToRender)
{
CCAtlasNode * pRet = new CCAtlasNode();
if (pRet->initWithTileTexture(texture, tileWidth, tileHeight, itemsToRender))
{
pRet->autorelease();
return pRet;
}
CC_SAFE_DELETE(pRet);
return NULL;
}
bool CCAtlasNode::initWithTileTexture(CCTexture2D *texture, int tileWidth, int tileHeight, int itemsToRender)
{
assert(texture != NULL);
m_nItemWidth = (int) (tileWidth * CC_CONTENT_SCALE_FACTOR());
m_nItemHeight = (int) (tileHeight * CC_CONTENT_SCALE_FACTOR());
m_cOpacity = 255;
m_tColor = m_tColorUnmodified = ccWHITE;
m_bIsOpacityModifyRGB = true;
m_tBlendFunc.src = CC_BLEND_SRC;
m_tBlendFunc.dst = CC_BLEND_DST;
// double retain to avoid the autorelease pool
// also, using: self.textureAtlas supports re-initialization without leaking
this->m_pTextureAtlas = new CCTextureAtlas();
m_pTextureAtlas->initWithTexture(texture, itemsToRender);
if (! m_pTextureAtlas)
{
CCLOG("cocos2d: Could not initialize CCAtlasNode. Invalid Texture.");
delete this;
return false;
}
this->updateBlendFunc();
this->updateOpacityModifyRGB();
this->calculateMaxItems();
return true;
}
Well I know it is not good since initWithTileTexture is almost the copy of initWithTileFile.