之前做《核桃小宝》的时候,战斗场景里需要判断一个怪的动画跑到第几帧会触发攻击事件。马上就想起文野哥的如何在cocos2d-x中取得当前动画播放是第几帧,关键代码:
for(int i = 0; i < 4; i++) { } |
照着文野哥的思路写了判断代码,奇怪的是没有一帧判断是相同的,即使当前显示的帧就是第N帧也返回false,奇怪得很。我的代码是这样子的:
// h文件里声明一个CCSpriteFrame数组。 CCMutableArray<CCSpriteFrame*>* m_arrayCCSpriteFrame; // cpp文件中的实现。 for( int i = 0; { // 如果当前帧是攻击帧,进行攻击处理。 } } |
保存一个CCSpriteFrame数组作为BattleLayer的成员变量,不直接保存一个CCAnimation而保存CCMutableArray<CCSpriteFrame*>*这个类型是因为用后者可以生成不同播放速度的CCAnimation,重用性比较强,不过关于这点能不能这样用我也不太确定。生成不同速度的CCAnimation代码:
return CCAnimation::animationWithFrames( m_arrayCCSpriteFrame, return CCAnimation::animationWithFrames( m_arrayCCSpriteFrame, |
按照这种写法,当前帧不管怎么判断都是false,诡异死了。通过断点比较m_arrayCCSpriteFrame 和CCSprite对象里各自 CCSpriteFrame*的地址,发现两者地址在内存里是一样的,而调用pSprite->displayedFrame()返回的地址却不一样,所以每次判断都是false。然后看了一下cocos2d-x的源代码,发现displayedFrame的实现如下:
CCSpriteFrame* CCSprite::displayedFrame(void) { } |
创建一个CCSpriteFrame*对象返回,因为我比较的是CCSpriteFrame*的地址,所以每次比较都是false。关于这里我就感到很奇怪了,如果是这样的话,那么文野哥的代码也应该会失败才对吧,为什么文野哥的代码就没问题呢。如果有高手看到这文,希望能帮我找找原因,谢谢~~help!
如果文野哥的方法不行的话,那么可以怎么做呢,我自己想了一个方法,下面说说思路:因为每个CCSpriteFrame里都有一个CCTexture2D对象,我们判断当前帧是第几帧的时候可以比较两者的CCTexture2D对象是否相同,因为CCTexture2D对象是由CCTextureCache管理,所以每张图的CCTexture2D是唯一的,如果当前帧是第N帧,那么这两个CCTexture2D对象也应该相同,因此只要代码中能判断出这两个CCTexture2D是同一个对象,当前帧是第几帧这个问题就解决了。
查看CCTexture2D的源代码,发现有一个getName函数,我想,相同的CCTexture2D对象里面的Name应该是一样的(实际上我觉得叫做ID更合适,因为CCTexture2D的Name类型是GLuint),于是就写了以下代码:
int GameConfig::getCurrentFrameIndex(CCSpriteFrame* frame) { // 获取当前精灵displayedFrame()的Name,用于比较当前帧是第几帧。 // -1表示没找到。可能的原因是参数的CCSpriteFrame不是m_arrayCCSpriteFrame的. } |