2013-06-06 12:02:54 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2013 cocos2d-x.org
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "CCAnimation.h"
|
|
|
|
#include "../CCArmature.h"
|
|
|
|
#include "../CCBone.h"
|
|
|
|
#include "../utils/CCArmatureDefine.h"
|
|
|
|
#include "../utils/CCUtilMath.h"
|
|
|
|
#include "../utils/CCConstValue.h"
|
|
|
|
#include "../datas/CCDatas.h"
|
|
|
|
|
|
|
|
|
|
|
|
NS_CC_EXT_BEGIN
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
CCAnimation *CCAnimation::create(CCArmature *armature)
|
|
|
|
{
|
|
|
|
CCAnimation *pARmatureAnimation = new CCAnimation();
|
|
|
|
if (pARmatureAnimation && pARmatureAnimation->init(armature))
|
|
|
|
{
|
|
|
|
pARmatureAnimation->autorelease();
|
|
|
|
return pARmatureAnimation;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(pARmatureAnimation);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
CCAnimation::CCAnimation()
|
2013-06-07 16:13:08 +08:00
|
|
|
: m_pAnimationData(NULL)
|
|
|
|
, m_pArmature(NULL)
|
2013-06-07 10:52:32 +08:00
|
|
|
, m_strMovementID("")
|
|
|
|
, m_iToIndex(0)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
CCAnimation::~CCAnimation(void)
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CC_SAFE_RELEASE_NULL(m_pTweenList);
|
|
|
|
CC_SAFE_RELEASE_NULL(m_pAnimationData);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CCAnimation::init(CCArmature *armature)
|
|
|
|
{
|
|
|
|
bool bRet = false;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
m_pArmature = armature;
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
m_pTweenList = new CCArray();
|
|
|
|
m_pTweenList->init();
|
2013-06-06 12:02:54 +08:00
|
|
|
|
|
|
|
bRet = true;
|
|
|
|
}
|
|
|
|
while (0);
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CCAnimation:: pause()
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCObject *object = NULL;
|
|
|
|
CCARRAY_FOREACH(m_pTweenList, object)
|
|
|
|
{
|
|
|
|
((CCTween *)object)->pause();
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
CCProcessBase::pause();
|
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
void CCAnimation::resume()
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCObject *object = NULL;
|
|
|
|
CCARRAY_FOREACH(m_pTweenList, object)
|
|
|
|
{
|
|
|
|
((CCTween *)object)->resume();
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
CCProcessBase::resume();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCAnimation::stop()
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCObject *object = NULL;
|
|
|
|
CCARRAY_FOREACH(m_pTweenList, object)
|
|
|
|
{
|
|
|
|
((CCTween *)object)->stop();
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
m_pTweenList->removeAllObjects();
|
|
|
|
CCProcessBase::stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCAnimation::setAnimationScale(float animationScale )
|
|
|
|
{
|
|
|
|
if(animationScale == m_fAnimationScale)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
m_fAnimationScale = animationScale;
|
|
|
|
|
|
|
|
CCDictElement *element = NULL;
|
|
|
|
CCDictionary *dict = m_pArmature->getBoneDic();
|
|
|
|
CCDICT_FOREACH(dict, element)
|
|
|
|
{
|
|
|
|
CCBone *bone = (CCBone *)element->getObject();
|
|
|
|
bone->getTween()->setAnimationScale(m_fAnimationScale);
|
|
|
|
if (bone->getChildArmature())
|
|
|
|
{
|
|
|
|
bone->getChildArmature()->getAnimation()->setAnimationScale(m_fAnimationScale);
|
|
|
|
}
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CCAnimation::play(const char *animationName, int durationTo, int durationTween, int loop, int tweenEasing)
|
|
|
|
{
|
|
|
|
CCAssert(m_pAnimationData, "m_pAnimationData can not be null");
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
m_pMovementData = m_pAnimationData->getMovement(animationName);
|
2013-06-06 12:02:54 +08:00
|
|
|
CCAssert(m_pMovementData, "m_pMovementData can not be null");
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
//! Get key frame count
|
|
|
|
m_iRawDuration = m_pMovementData->duration;
|
2013-06-06 12:02:54 +08:00
|
|
|
|
|
|
|
m_strMovementID = animationName;
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
//! Further processing parameters
|
2013-06-06 12:02:54 +08:00
|
|
|
durationTo = (durationTo == -1) ? m_pMovementData->durationTo : durationTo;
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
durationTween = (durationTween == -1) ? m_pMovementData->durationTween : durationTween;
|
|
|
|
durationTween = (durationTween == 0) ? m_pMovementData->duration : durationTween;
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
tweenEasing = (tweenEasing == TWEEN_EASING_MAX) ? m_pMovementData->tweenEasing : tweenEasing;
|
|
|
|
loop = (loop < 0) ? m_pMovementData->loop : loop;
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
CCProcessBase::play((void *)animationName, durationTo, durationTween, loop, tweenEasing);
|
|
|
|
|
|
|
|
|
|
|
|
if (m_iRawDuration == 1)
|
|
|
|
{
|
|
|
|
m_eLoopType = SINGLE_FRAME;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (loop)
|
|
|
|
{
|
|
|
|
m_eLoopType = ANIMATION_TO_LOOP_FRONT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_eLoopType = ANIMATION_NO_LOOP;
|
|
|
|
m_iRawDuration --;
|
|
|
|
}
|
|
|
|
m_iDurationTween = durationTween;
|
|
|
|
}
|
|
|
|
|
2013-06-06 16:22:58 +08:00
|
|
|
CCMovementBoneData *movementBoneData = NULL;
|
2013-06-06 12:02:54 +08:00
|
|
|
m_pTweenList->removeAllObjects();
|
|
|
|
|
|
|
|
CCDictElement *element = NULL;
|
|
|
|
CCDictionary *dict = m_pArmature->getBoneDic();
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
CCDICT_FOREACH(dict, element)
|
|
|
|
{
|
|
|
|
CCBone *bone = (CCBone *)element->getObject();
|
|
|
|
movementBoneData = (CCMovementBoneData *)m_pMovementData->movBoneDataDic.objectForKey(bone->getName());
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
CCTween *tween = bone->getTween();
|
|
|
|
if(movementBoneData && movementBoneData->frameList.count() > 0)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
m_pTweenList->addObject(tween);
|
2013-06-06 12:02:54 +08:00
|
|
|
tween->play(movementBoneData, durationTo, durationTween, loop, tweenEasing);
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
tween->setAnimationScale(m_fAnimationScale);
|
|
|
|
if (bone->getChildArmature())
|
|
|
|
{
|
|
|
|
bone->getChildArmature()->getAnimation()->setAnimationScale(m_fAnimationScale);
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
if(!bone->getIgnoreMovementBoneData())
|
|
|
|
{
|
|
|
|
//! this bone is not include in this movement, so hide it
|
|
|
|
bone->getDisplayManager()->changeDisplayByIndex(-1, false);
|
|
|
|
tween->stop();
|
|
|
|
}
|
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
//m_pArmature->update(0);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CCAnimation::playByIndex(int animationIndex, int durationTo, int durationTween, int loop, int tweenEasing)
|
|
|
|
{
|
|
|
|
std::vector<std::string> &movName = m_pAnimationData->movementNames;
|
2013-06-07 17:10:53 +08:00
|
|
|
CC_ASSERT((animationIndex > -1) && ((unsigned int)animationIndex < movName.size()));
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
std::string animationName = movName.at(animationIndex);
|
|
|
|
play(animationName.c_str(), durationTo, durationTween, loop, tweenEasing);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int CCAnimation::getMovementCount()
|
|
|
|
{
|
|
|
|
return m_pAnimationData->getMovementCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCAnimation::update(float dt)
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCProcessBase::update(dt);
|
|
|
|
CCObject *object = NULL;
|
|
|
|
CCARRAY_FOREACH(m_pTweenList, object)
|
|
|
|
{
|
|
|
|
((CCTween *)object)->update(dt);
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
void CCAnimation::updateHandler()
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
if (m_fCurrentPercent >= 1)
|
|
|
|
{
|
|
|
|
switch(m_eLoopType)
|
|
|
|
{
|
|
|
|
case ANIMATION_NO_LOOP:
|
|
|
|
{
|
|
|
|
m_eLoopType = ANIMATION_MAX;
|
|
|
|
m_fCurrentFrame = (m_fCurrentPercent - 1) * m_iNextFrameIndex;
|
|
|
|
m_fCurrentPercent = m_fCurrentFrame / m_iDurationTween;
|
|
|
|
|
|
|
|
if (m_fCurrentPercent >= 1.0f)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_iNextFrameIndex = m_iDurationTween;
|
|
|
|
|
|
|
|
MovementEventSignal.emit(m_pArmature, START, m_strMovementID.c_str());
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMATION_MAX:
|
|
|
|
case SINGLE_FRAME:
|
|
|
|
{
|
|
|
|
m_fCurrentPercent = 1;
|
|
|
|
m_bIsComplete = true;
|
|
|
|
|
|
|
|
MovementEventSignal.emit(m_pArmature, COMPLETE, m_strMovementID.c_str());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMATION_TO_LOOP_FRONT:
|
|
|
|
{
|
|
|
|
m_eLoopType = ANIMATION_LOOP_FRONT;
|
|
|
|
m_fCurrentPercent = fmodf(m_fCurrentPercent, 1);
|
|
|
|
m_fCurrentFrame = fmodf(m_fCurrentFrame, m_iNextFrameIndex);
|
|
|
|
m_iNextFrameIndex = m_iDurationTween > 0 ? m_iDurationTween : 1;
|
|
|
|
|
|
|
|
MovementEventSignal.emit(m_pArmature, START, m_strMovementID.c_str());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
m_fCurrentPercent = fmodf(m_fCurrentPercent, 1);
|
|
|
|
m_fCurrentFrame = fmodf(m_fCurrentFrame, m_iNextFrameIndex);
|
|
|
|
m_iToIndex = 0;
|
|
|
|
|
|
|
|
MovementEventSignal.emit(m_pArmature, LOOP_COMPLETE, m_strMovementID.c_str());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_eLoopType == ANIMATION_LOOP_FRONT || m_eLoopType == ANIMATION_LOOP_BACK)
|
|
|
|
{
|
|
|
|
updateFrameData(m_fCurrentPercent);
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
void CCAnimation::updateFrameData(float currentPercent)
|
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
m_iPrevFrameIndex = m_iCurFrameIndex;
|
|
|
|
m_iCurFrameIndex = m_iRawDuration * currentPercent;
|
|
|
|
m_iCurFrameIndex = m_iCurFrameIndex % m_iRawDuration;
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
NS_CC_EXT_END
|