本人在使用精灵表单创建动画的过程中突然遇到了一些个问题,下面进行一下分析总结。
根据在Cocos2d-iphone中的经验,我写出了如下的代码:
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("my.plist"); CCSpriteBatchNode *batchNode = CCSpriteBatchNode::create("my.png"); this->addChild(batchNode); CCArray *frameArray = CCArray::create(); for (int i=1; i<=4; i++) { CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("switch_off_1_%d.png",i)->getCString()); frameArray->addObject(frame); } CCAnimation *animation = CCAnimation::create(frameArray, 0.4); CCAnimate *animate = CCAnimate::create(animation); CCSprite *iconSprite = CCSprite::createWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("switch_off_1_4.png")); iconSprite->setPosition(ccp(100,100)); this->addChild(iconSprite); iconSprite->runAction(CCRepeatForever::create(animate));
但是程序出错:
Cocos2d: Assert failed: element type is wrong! Assertion failed: (dynamic_cast<CCAnimationFrame*>(*__arr__)), function initWithAnimationFrames, file /Users/ios/Desktop/demo/demo/libs/cocos2dx/sprite_nodes/CCAnimation.cpp, line 144.
原来是
CCAnimation *animation = CCAnimation::create(frameArray, 0.4); 出了问题!
直接用create方法,会进入initWithAnimationFrames方法,里面会检查传入的CCArray是否是CCAnimationFrame*类型,而显然,我代码中CCArray中的元素是CCSpriteFrame*,所以出现了问题。
那么解决方法是:改用
CCAnimation *animation =CCAnimation::createWithSpriteFrames(frameArray,0.4); 这个方法就可以了。
注意:在xcode中代码提示 createWithSpriteFrames 这个方法只有一个参数,
但是,实际上进入这个函数就回发现,它是有两个参数的。
/* Creates an animation with an array of CCSpriteFrame and a delay between frames in seconds. The frames will be added with one "delay unit". @since v0.99.5 */ static CCAnimation* createWithSpriteFrames(CCArray* arrayOfSpriteFrameNames, float delay = 0.0f);
注意其中的注释: Creates an animation with an array of CCSpriteFrame and a delay between frames in seconds
对比create方法中的注释:
Creates an animation with an array of CCAnimationFrame, the delay per units in seconds and and how many times it should be executed.
/* Creates an animation with an array of CCAnimationFrame, the delay per units in seconds and and how many times it should be executed. @since v2.0 */ static CCAnimation* create(CCArray *arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops); static CCAnimation* create(CCArray *arrayOfAnimationFrameNames, float delayPerUnit) { return CCAnimation::create(arrayOfAnimationFrameNames, delayPerUnit, 1); }
这样就知道出错的原因了吧!
下面给出另一种方法创建动画的方式:
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("my.plist"); CCSpriteBatchNode *batchNode = CCSpriteBatchNode::create("my.png"); this->addChild(batchNode); CCAnimation *animation = CCAnimation::create(); for (int i=1; i<=4; i++) { CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("switch_off_1_%d.png",i)->getCString()); animation->addSpriteFrame(frame); } animation->setDelayPerUnit(0.4); CCAnimate *animate = CCAnimate::create(animation); CCSprite *iconSprite = CCSprite::createWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("switch_off_1_4.png")); // CCSize size = CCDirector::sharedDirector()->getWinSize(); iconSprite->setPosition(ccp(100,100)); this->addChild(iconSprite); iconSprite->runAction(CCRepeatForever::create(animate));
参考文章:http://blog.csdn.net/rabbitlbj/article/details/8765575