int CCBAnimationManager::getSequenceId(const char* pSequenceName) { CCObject *pElement = NULL; string seqName(pSequenceName); CCARRAY_FOREACH(mSequences, pElement) { CCBSequence *seq = (CCBSequence*)pElement; if (seqName.compare(seq->getName()) == 0) { return seq->getSequenceId(); } }
void CcbBase::update(float delta) { if (_needCallBack) { _needCallBack = false; CCArray *arr = m_pCCBReader->getAnimationManager()->getSequences(); CCBSequence* curSeq = NULL; CCObject *pElement = NULL; CCARRAY_FOREACH(arr, pElement) { CCBSequence *seq = (CCBSequence*)pElement; if (seq->getSequenceId() == _index) { curSeq = seq; break; } } if (curSeq) { m_pCCBReader->getAnimationManager()->runAnimationsForSequenceIdTweenDuration(_index, 0); setAnimationCompletedCallback(this, callfunc_selector(CcbBase::animationCompletedCallback)); float dt = (CSystem::currentTimeMillis() - _startTime) / 1000.0f; dt = dt + _skipTime - curSeq->getDuration(); while (dt > curSeq->getDuration()) { dt -= curSeq->getDuration(); } // dt可能为负数 暂时忽略不计 if(dt > 0) skip(m_pCcbNode, dt); _skipTime = dt > 0 ? dt : 0; _startTime = CSystem::currentTimeMillis(); // CCLOG("m_pCcbNode:%d skipTime:%f",m_pCcbNode, dt); } }
bool CCBReader::readSequences() { auto& sequences = _animationManager->getSequences(); int numSeqs = readInt(false); for (int i = 0; i < numSeqs; i++) { CCBSequence *seq = new (std::nothrow) CCBSequence(); seq->autorelease(); seq->setDuration(readFloat()); seq->setName(readCachedString().c_str()); seq->setSequenceId(readInt(false)); seq->setChainedSequenceId(readInt(true)); if(!readCallbackKeyframesForSeq(seq)) return false; if(!readSoundKeyframesForSeq(seq)) return false; sequences.pushBack(seq); } _animationManager->setAutoPlaySequenceId(readInt(true)); return true; }
void CCBAnimationManager::runAnimationsForSequenceIdTweenDuration(int nSeqId, float fTweenDuration) { CCASSERT(nSeqId != -1, "Sequence id couldn't be found"); _rootNode->stopAllActions(); for (auto nodeSeqIter = _nodeSequences.begin(); nodeSeqIter != _nodeSequences.end(); ++nodeSeqIter) { Node *node = nodeSeqIter->first; node->stopAllActions(); // Refer to CCBReader::readKeyframe() for the real type of value auto seqs = nodeSeqIter->second; auto seqNodeProps = seqs[nSeqId]; std::set<std::string> seqNodePropNames; if (!seqNodeProps.empty()) { // Reset nodes that have sequence node properties, and run actions on them for (auto iter = seqNodeProps.begin(); iter != seqNodeProps.end(); ++iter) { const std::string propName = iter->first; CCBSequenceProperty *seqProp = iter->second; seqNodePropNames.insert(propName); setFirstFrame(node, seqProp, fTweenDuration); runAction(node, seqProp, fTweenDuration); } } // Reset the nodes that may have been changed by other timelines auto& nodeBaseValues = _baseValues[node]; if (!nodeBaseValues.empty()) { for (auto iter = nodeBaseValues.begin(); iter != nodeBaseValues.end(); ++iter) { if (seqNodePropNames.find(iter->first) == seqNodePropNames.end()) { setAnimatedProperty(iter->first, node, iter->second, nullptr, fTweenDuration); } } } auto& nodeObject = _objects[node]; if (!nodeObject.empty()) { for (auto iter = nodeObject.begin(); iter != nodeObject.end(); ++iter) { if (seqNodePropNames.find(iter->first) == seqNodePropNames.end()) { setAnimatedProperty(iter->first, node, Value(), iter->second, fTweenDuration); } } } } // Make callback at end of sequence CCBSequence *seq = getSequence(nSeqId); Action *completeAction = Sequence::createWithTwoActions(DelayTime::create(seq->getDuration() + fTweenDuration), CallFunc::create( CC_CALLBACK_0(CCBAnimationManager::sequenceCompleted,this))); _rootNode->runAction(completeAction); // Set the running scene if(seq->getCallbackChannel() != nullptr) { Action* action = (Action *)actionForCallbackChannel(seq->getCallbackChannel()); if(action != nullptr) { _rootNode->runAction(action); } } if(seq->getSoundChannel() != nullptr) { Action* action = (Action *)actionForSoundChannel(seq->getSoundChannel()); if(action != nullptr) { _rootNode->runAction(action); } } _runningSequence = getSequence(nSeqId); }