为什么从CCSpriteFrameCache创建的sprite能添加到CCSpriteBatchNode

在《如何使用动画和精灵表单 Cocos2d-x 2.1.4 》中介绍了如何使用plist文件创建精灵和动画,
使用方法直接参考如下代码:

bool HelloWorld::init()
{
bool bRet = false;
do
{
CC_BREAK_IF(!CCLayer::init());

    //1) Cache the sprite frames and texture
    CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("AnimBear.plist");

    //2) Create a sprite batch node
    CCSpriteBatchNode *spriteSheet = CCSpriteBatchNode::create("AnimBear.png");
    this->addChild(spriteSheet);

    //3) Gather the list of frames
    CCArray *walkAnimFrames = CCArray::create();
    for (int i = 1; i <= 8; ++i)         {             walkAnimFrames->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(
            CCString::createWithFormat("bear%d.png", i)->getCString()));
    }

    //4) Create the animation object
    CCAnimation *walkAnim = CCAnimation::createWithSpriteFrames(walkAnimFrames, 0.1f);

    //5) Create the sprite and run the animation action
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    this->setBear(CCSprite::createWithSpriteFrameName("bear1.png"));
    this->getBear()->setPosition(ccp(winSize.width / 2, winSize.height / 2));
    this->setWalkAction(CCRepeatForever::create(CCAnimate::create(walkAnim)));
    this->getBear()->runAction(this->getWalkAction());
    spriteSheet->addChild(this->getBear());

    bRet = true;
} while (0);
return bRet;

}
有个疑问就是,CCSprite::createWithSpriteFrameName(“bear1.png”)通过SpriteFrameCache中缓存的frame创建出sprite,然后加入到spriteSheet这个CCSpriteBatchNode中去,那么CCSpriteBatchNode是如何知道新添加的这个sprite使用的就是CCSpriteBatchNode::create(“AnimBear.png”)在创建时使用的同一纹理文件呢?(如果不相同在添加时CCSpriteBatchNode会报错的)

可以看看addSpriteFramesWithFile()和initWithFile()的实现方式:

bool CCSpriteBatchNode::initWithFile(const char fileImage, unsigned int capacity)
{
CCTexture2D
pTexture2D = CCTextureCache::sharedTextureCache()->addImage(fileImage);
return initWithTexture(pTexture2D, capacity);
}

void CCSpriteFrameCache::addSpriteFramesWithFile(const char pszPlist)
{

CCTexture2D
pTexture = CCTextureCache::sharedTextureCache()->addImage(texturePath.c_str());

}
可以看到两个函数实际上都是调用CCTextureCache::sharedTextureCache()获取纹理的,同样的文件名会使用同样的纹理,initWithFile参数直接就是纹理图片AnimBear.png,addSpriteFramesWithFile参数是plist文件,plist文件中的metadata部分记录了纹理图片的文件名AnimBear.png,两者是同一张图片。

因此通过CCSpriteFrameCache中的frame创建出的sprite,可以正常添加到CCSpriteBatchNode中。