void CCTween::play(CCMovementBoneData *movementBoneData, int durationTo, int durationTween, int loop, int tweenEasing) { CCProcessBase::play(durationTo, durationTween, loop, tweenEasing); if (loop) { m_eLoopType = ANIMATION_TO_LOOP_FRONT; } else { m_eLoopType = ANIMATION_NO_LOOP; } m_iTotalDuration = 0; m_iBetweenDuration = 0; m_iFromIndex = m_iToIndex = 0; bool difMovement = movementBoneData != m_pMovementBoneData; setMovementBoneData(movementBoneData); m_iRawDuration = m_pMovementBoneData->duration; CCFrameData *nextKeyFrame = m_pMovementBoneData->getFrameData(0); m_pTweenData->displayIndex = nextKeyFrame->displayIndex; if (m_pBone->getArmature()->getArmatureData()->dataVersion >= VERSION_COMBINED) { CCTransformHelp::nodeSub(*m_pTweenData, *m_pBone->getBoneData()); m_pTweenData->scaleX += 1; m_pTweenData->scaleY += 1; } if (m_iRawDuration == 0 || m_pMovementBoneData->frameList.count() == 1) { m_eLoopType = SINGLE_FRAME; if(durationTo == 0) { setBetween(nextKeyFrame, nextKeyFrame); } else { setBetween(m_pTweenData, nextKeyFrame); } m_eFrameTweenEasing = Linear; } else if (m_pMovementBoneData->frameList.count() > 1) { m_iDurationTween = durationTween * m_pMovementBoneData->scale; if (loop && m_pMovementBoneData->delay != 0) { setBetween(m_pTweenData, tweenNodeTo(updateFrameData(1 - m_pMovementBoneData->delay), m_pBetween)); } else { if (!difMovement || durationTo == 0) { setBetween(nextKeyFrame, nextKeyFrame); } else { setBetween(m_pTweenData, nextKeyFrame); } } } tweenNodeTo(0); }
void Tween::play(MovementBoneData *movementBoneData, int durationTo, int durationTween, int loop, int tweenEasing) { ProcessBase::play(durationTo, durationTween, loop, tweenEasing); if (loop) { _loopType = ANIMATION_TO_LOOP_FRONT; } else { _loopType = ANIMATION_NO_LOOP; } _totalDuration = 0; _betweenDuration = 0; _fromIndex = _toIndex = 0; bool difMovement = movementBoneData != _movementBoneData; setMovementBoneData(movementBoneData); _rawDuration = _movementBoneData->duration; FrameData *nextKeyFrame = _movementBoneData->getFrameData(0); _tweenData->displayIndex = nextKeyFrame->displayIndex; if (_bone->getArmature()->getArmatureData()->dataVersion >= VERSION_COMBINED) { TransformHelp::nodeSub(*_tweenData, *_bone->getBoneData()); _tweenData->scaleX += 1; _tweenData->scaleY += 1; } if (_rawDuration == 0 ) { _loopType = SINGLE_FRAME; if(durationTo == 0) { setBetween(nextKeyFrame, nextKeyFrame); } else { setBetween(_tweenData, nextKeyFrame); } _frameTweenEasing = Linear; } else if (_movementBoneData->frameList.size() > 1) { _durationTween = durationTween * _movementBoneData->scale; if (loop && _movementBoneData->delay != 0) { setBetween(_tweenData, tweenNodeTo(updateFrameData(1 - _movementBoneData->delay), _between)); } else { if (!difMovement || durationTo == 0) { setBetween(nextKeyFrame, nextKeyFrame); } else { setBetween(_tweenData, nextKeyFrame); } } } tweenNodeTo(0); }
float CCTween::updateFrameData(float currentPercent) { if (currentPercent > 1 && m_pMovementBoneData->delay != 0) { currentPercent = fmodf(currentPercent, 1); } float playedTime = (float)(m_iRawDuration - 1) * currentPercent; //! If play to current frame's front or back, then find current frame again if (playedTime < m_iTotalDuration || playedTime >= m_iTotalDuration + m_iBetweenDuration) { /* * Get frame length, if m_iToIndex >= _length, then set m_iToIndex to 0, start anew. * m_iToIndex is next index will play */ int length = m_pMovementBoneData->frameList.count(); CCFrameData **frames = (CCFrameData **)m_pMovementBoneData->frameList.data->arr; CCFrameData *from = NULL; CCFrameData *to = NULL; if (playedTime < frames[0]->frameID) { from = to = frames[0]; setBetween(from, to); return m_fCurrentPercent; } if(playedTime >= frames[length - 1]->frameID) { if (m_bPassLastFrame) { from = to = frames[length - 1]; setBetween(from, to); return m_fCurrentPercent; } m_bPassLastFrame = true; } else { m_bPassLastFrame = false; } do { m_iFromIndex = m_iToIndex; from = frames[m_iFromIndex]; m_iTotalDuration = from->frameID; m_iToIndex = m_iFromIndex + 1; if (m_iToIndex >= length) { m_iToIndex= 0; } to = frames[m_iToIndex]; //! Guaranteed to trigger frame event if(from->strEvent.length() != 0 && !m_pAnimation->isIgnoreFrameEvent()) { m_pAnimation->frameEvent(m_pBone, from->strEvent.c_str(), from->frameID, playedTime); } if (playedTime == from->frameID || (m_bPassLastFrame && m_iFromIndex == length-1)) { break; } } while (playedTime < from->frameID || playedTime >= to->frameID); m_iBetweenDuration = to->frameID - from->frameID; m_eFrameTweenEasing = from->tweenEasing; setBetween(from, to, false); } currentPercent = m_iBetweenDuration == 0 ? 0 : (playedTime - m_iTotalDuration) / (float)m_iBetweenDuration; /* * If frame tween easing equal to TWEEN_EASING_MAX, then it will not do tween. */ CCTweenType tweenType = (m_eFrameTweenEasing != Linear) ? m_eFrameTweenEasing : m_eTweenEasing; if (tweenType != TWEEN_EASING_MAX && tweenType != Linear && !m_bPassLastFrame) { currentPercent = CCTweenFunction::tweenTo(currentPercent, tweenType, m_pFrom->easingParams); } return currentPercent; }
float Tween::updateFrameData(float currentPercent) { if (currentPercent > 1 && _movementBoneData->delay != 0) { currentPercent = fmodf(currentPercent, 1); } float playedTime = ((float)_rawDuration-1) * currentPercent; //! If play to current frame's front or back, then find current frame again if (playedTime < _totalDuration || playedTime >= _totalDuration + _betweenDuration) { /* * Get frame length, if _toIndex >= _length, then set _toIndex to 0, start anew. * _toIndex is next index will play */ long length = _movementBoneData->frameList.size(); cocos2d::Vector<FrameData *> &frames = _movementBoneData->frameList; FrameData *from = nullptr; FrameData *to = nullptr; if (playedTime < frames.at(0)->frameID) { from = to = frames.at(0); setBetween(from, to); return _currentPercent; } if(playedTime >= frames.at(length - 1)->frameID) { // If _passLastFrame is true and playedTime >= frames[length - 1]->frameID, then do not need to go on. if (_passLastFrame) { from = to = frames.at(length - 1); setBetween(from, to); return _currentPercent; } _passLastFrame = true; } else { _passLastFrame = false; } do { _fromIndex = _toIndex; from = frames.at(_fromIndex); _totalDuration = from->frameID; _toIndex = _fromIndex + 1; if (_toIndex >= length) { _toIndex = 0; } to = frames.at(_toIndex); //! Guaranteed to trigger frame event if(from->strEvent.length() != 0 && !_animation->isIgnoreFrameEvent()) { _animation->frameEvent(_bone, from->strEvent.c_str(), from->frameID, playedTime); } if (playedTime == from->frameID || (_passLastFrame && _fromIndex == length-1)) { break; } } while (playedTime < from->frameID || playedTime >= to->frameID); _betweenDuration = to->frameID - from->frameID; _frameTweenEasing = from->tweenEasing; setBetween(from, to, false); } currentPercent = _betweenDuration == 0 ? 0 : (playedTime - _totalDuration) / (float)_betweenDuration; /* * If frame tween easing equal to TWEEN_EASING_MAX, then it will not do tween. */ TweenType tweenType = (_frameTweenEasing != Linear) ? _frameTweenEasing : _tweenEasing; if (tweenType != TWEEN_EASING_MAX && tweenType != Linear && !_passLastFrame) { currentPercent = TweenFunction::tweenTo(currentPercent, tweenType, _from->easingParams); } return currentPercent; }