关于Cocos2d-x中获取正在播放动画第几帧的问题

来源:互联网 发布:php网络工程师 编辑:程序博客网 时间:2024/06/10 04:38

一。问题描述

今天在写游戏的时候,为了统一动画和攻击的时间,我取消了原先依靠时间来同步的想法(太烂了,总是不协调)。所以就上网搜了下,看看cocos2d-x中有没有提供这样的方法(汗。。。初学当中ing......)。很快就搜到了一篇文章,说是使用CCSprite中的displayFrame方法返回正在播放的动画帧,然后调用CCAnimate中的getFrames方法来获取正在播放动画的所有的CCSpriteFrame*帧,之后就可以通过指针比较来进行了。这个方法,文章的作者也发现了有点问题,所以在后面给出了改进的地方,displayFrame返回的实际上是新建的一个CCSpriteFrame,而不是原来的CCSpriteFrame*,说的抽象,看代码:

CCSpriteFrame* CCSprite::displayFrame(void)
{
    return CCSpriteFrame::createWithTexture(m_pobTexture,
                                           CC_RECT_POINTS_TO_PIXELS(m_obRect),
                                           m_bRectRotated,
                                           CC_POINT_POINTS_TO_PIXELS(m_obUnflippedOffsetPositionFromCenter),
                                           CC_SIZE_POINTS_TO_PIXELS(m_obContentSize));
}

看出来了吧,直接是创建一个新的CCSpriteFrame对象,这么说两个对象完全不能够使用==来进行比较了。作者又想到使用CCSpriteFrame中的Texture的ID来进行比较,就算新建了一个精灵帧,用的还是自己原来的纹理m_pobTexture,看上面的代码就知道了。所以,应该能够实现,因为CCTexture里面有个getName()用来返回唯一的ID号,靠这个就应该能够进行正确的比较了,所以兴奋的去游戏中实现下。

结果,还是一样,不能同步,调试下发现,displayFrame返回的精灵帧中的纹理ID总是保持不变,这下悲催了,不知道怎么弄了。。。(不知道为什么纹理不变,难道播放动画的时候,不是将精灵的纹理替换掉,而是在原来的位置覆盖一下???不会这么烂吧??? 不明白。。。。)

二。解决问题

被逼无奈之下,我就看了下CCSprite的源码,无意之中,发现了下面的一个函数:

bool CCSprite::isFrameDisplayed(CCSpriteFrame *pFrame)
{
    CCRect r = pFrame->getRect();


    return (r.equals(m_obRect) &&
            pFrame->getTexture()->getName() == m_pobTexture->getName() &&
            pFrame->getOffset().equals(m_obUnflippedOffsetPositionFromCenter));
}

看上面的那个函数名,就知道是判断给定的精灵帧是否进行了播放。
而且这个的判断条件更加的多,不仅判断了纹理名字是否相同,还判断了矩形区域,偏移。
(:< 又不懂了,上面那个display返回的ID保持不变,这里使用纹理的ID来进行判断 ,不还是一样不能够解决吗???)

先不管这个,游戏要紧,直接拿进游戏中试一下,

oh,My god ,还真TMD的可以哎。完全同步了 ,没有一点滞留。

以下是这个解决方法的部分代码:

CCArray* spriteArray = m_pLocateSkillAction->getAnimation()->getFrames();     //其中的m_pLocateSkillAction是一个CCAnimate的对象指针
CCAnimationFrame*tempFrame = (CCAnimationFrame*)spriteArray->objectAtIndex(61) ;   //这里要注意了,返回的是CCAnimationFrame的指针,不是CCSpriteFrame*


if(m_Sprite->isFrameDisplayed(tempFrame->getSpriteFrame()))     //m_Sprite就是正在播放动画的那个精灵
{
........
}

三。遗留问题

上面的isFrameDisplayed中也使用到了纹理啊,而displayFrame也是用这个m_pobTexture属性的啊,为什么这里的可以,上面的displayFrame不可以,实在不明白。。。希望有高手解释下。。。(难道是所谓的动画播放搞的鬼???)
原创粉丝点击