#ifndef __RED_REDANIMATION_MANAGER_H__ #define __RED_REDANIMATION_MANAGER_H__ #include "base/CCMap.h" #include "2d/CCActionInterval.h" #include "2d/CCActionInstant.h" #include "2d/CCActionEase.h" #include "extensions/ExtensionMacros.h" #include "REDSequence.h" #include "REDKeyframe.h" #include "REDSequenceProperty.h" #include "extensions/GUI/CCControlExtension/CCControl.h" #include "2d/ZMLCCParticleSystem.h" #include "2d/ZMLCCParticleSystemQuad.h" #include "2d/ZGFrameActionSprite.h" #include "editor-support/spine/bake/RedBakeNode.h" #include namespace redream { enum class AnimationCompleteType { CHAINED, COMPLETED, STOPED }; #define RED_SEQ_COMPLETED_GLUE(SNAME, METHOD) if(strcmp(name, SNAME) == 0) { \ if (METHOD) {METHOD(SNAME); return;} \ } #define RED_SEQ_COMPLETED_AND_PLAY_NEXT_GLUE(SNAME, METHOD) if(strcmp(name, SNAME) == 0) { \ if (METHOD) {METHOD(SNAME); return;} \ } #define RED_SEQ_STOPPED_GLUE(SNAME, METHOD) if(strcmp(name, SNAME) == 0) { \ if (METHOD) {METHOD(SNAME); return;} \ } class CC_DLL REDAnimationManagerDelegate { public: virtual ~REDAnimationManagerDelegate() {} //完成的动画序列 virtual void completedAnimationSequenceNamed(const char *name, int seqId, int tag) = 0; // 动画播完了但是会继续播放下一条动画 virtual void completedAnimationAndPlayNextSequenceNamed(const char *name, int seqId, int tag){}; // 动画被stop掉了 virtual void stopAnimationSequenceNamed(const char *name, int seqId, int tag){}; }; class CC_DLL REDAnimationManager : public cocos2d::Ref { public: #pragma mark - Begin BatchNode ///add by songqingyu for BatchNode ///重新设置所有可能的sprite的displayFrame void resetSpriteFrameOfAllChildrenAnimtion(); void addDisplayFrameKeykframe(REDKeyframe* kf); void addSpriteFrameForNode(cocos2d::Node* pNode,const std::string& propName,const std::string& spriteFile,const std::string& spriteSheet); void setREDRootPath(std::string redRootPath); /// 后面的方法(getSpriteFrameByName)需要知道查找的spriteframeName所在的plist /// @param plistSt 初始加载时需要从这个plist中查找 /// @param replacePlistSt 合批之后需要从这个plist中查找 void setReaderPlist(std::unordered_set plistSt,std::unordered_set replacePlistSt); cocos2d::SpriteFrame* getSpriteFrameByName(const std::string& spriteFile,const std::string& spriteSheet,bool useDefaultEmpty=true); const std::unordered_set& getRepleacePlistSt(){return _repleacePlistSt;}; private: cocos2d::Vector _needResetSpriteFrames; std::string _redRootPath; std::unordered_set _readerPlistSt; std::unordered_set _repleacePlistSt; std::unordered_map>> _needResetObjProps; ///end #pragma mark end BatchNode - public: // bool _jsControlled; /** * @js ctor */ REDAnimationManager(); /** * @js NA * @lua NA */ ~REDAnimationManager(); static REDAnimationManager *fromNode(cocos2d::Node *node); cocos2d::Ref *_owner; virtual bool init(); cocos2d::Vector& getSequences(); void setSequences(const cocos2d::Vector& seq); int getAutoPlaySequenceId(); void setAutoPlaySequenceId(int autoPlaySequenceId); cocos2d::Node* getRootNode(); void setRootNode(cocos2d::Node* pRootNode); // weak reference void addDocumentCallbackNode(cocos2d::Node *node); void addDocumentCallbackName(std::string name); void addDocumentCallbackControlEvents(cocos2d::extension::Control::EventType eventType); void addDocumentOutletNode(cocos2d::Node *node); void addDocumentOutletName(std::string name); void setDocumentControllerName(const std::string &name); std::string getDocumentControllerName(); cocos2d::ValueVector& getDocumentCallbackNames(); cocos2d::Vector& getDocumentCallbackNodes(); cocos2d::ValueVector& getDocumentCallbackControlEvents(); cocos2d::ValueVector& getDocumentOutletNames(); cocos2d::Vector& getDocumentOutletNodes(); std::string getLastCompletedSequenceName(); cocos2d::ValueVector& getKeyframeCallbacks(); const cocos2d::Size& getRootContainerSize(); void setRootContainerSize(const cocos2d::Size &rootContainerSize); REDAnimationManagerDelegate* getDelegate(); void setDelegate(REDAnimationManagerDelegate* pDelegate); // retain const char* getRunningSequenceName(); const cocos2d::Size& getContainerSize(cocos2d::Node* pNode); void addNode(cocos2d::Node *pNode, const std::unordered_map>& seq); void setBaseValue(const cocos2d::Value& value, cocos2d::Node *pNode, const std::string& propName); void setObject(cocos2d::Ref* obj, cocos2d::Node *pNode, const std::string& propName); void moveAnimationsFromNode(cocos2d::Node* fromNode, cocos2d::Node* toNode); /** @deprecated This interface will be deprecated sooner or later.*/ CC_DEPRECATED_ATTRIBUTE void runAnimations(const char *pName, float fTweenDuration); /** @deprecated This interface will be deprecated sooner or later.*/ CC_DEPRECATED_ATTRIBUTE void runAnimations(const char *pName); /** @deprecated This interface will be deprecated sooner or later.*/ CC_DEPRECATED_ATTRIBUTE void runAnimations(int nSeqId, float fTweenDuraiton); void runAnimationsForSequenceNamedTweenDuration(const char *pName, float fTweenDuration, const std::function &callback = nullptr); void runAnimationsForSequenceNamed(const char *pName); void runAnimationsForSequenceIdTweenDuration(int nSeqId, float fTweenDuraiton, const std::function &callback = nullptr, REDAnimationManagerDelegate* listen = nullptr); void runAnimationsWithTag(int nSeqId, int tag); void runAnimationsWithListen(int nSeqId, REDAnimationManagerDelegate* listen); cocos2d::Spawn* getNodeAniByName(const char *pName,cocos2d::Node *pNode,cocos2d::Vec2 orginPos); /** * when this function bound to js ,the second param are callfunc_selector * @lua NA */ void setAnimationCompletedCallback(cocos2d::Ref *target, cocos2d::SEL_CallFunc callbackFunc); void debug(); /** * @js setCallFuncForJSCallbackNamed */ void setCallFunc(cocos2d::CallFunc *callFunc, const std::string &callbackNamed); cocos2d::Sequence* actionForCallbackChannel(REDSequenceProperty* channel); cocos2d::Sequence* actionForSoundChannel(REDSequenceProperty* channel); cocos2d::Sequence* actionForWiseChannel(REDSequenceProperty* channel); // return -1 if timeline not exist int getSequenceId(const char* pSequenceName); // get timeline duration float getSequenceDuration(const char* pSequenceName); std::string getREDFileName(); void setREDFileName(std::string filename); CC_SYNTHESIZE(float, _speed, AnimationSpeed); void updateSpeed(float speed); void refreshStatusOnFirstFream(int nSeqId, float fTweenDuraiton); // REDAnimationManagerDelegate* getDelegate(); // void addListen(REDAnimationManagerDelegate* pDelegate); // retain // void removeListen(REDAnimationManagerDelegate* pDelegate); void stopAllNodeAction(); private: void stopRootNodeAction(REDSequence* seq, std::function callback); const cocos2d::Value& getBaseValue(cocos2d::Node *pNode, const std::string& propName); Ref* getObject(cocos2d::Node *pNode, const std::string& propName); REDSequence* getSequence(int nSequenceId); cocos2d::ActionInterval* getAction(REDKeyframe *pKeyframe0, REDKeyframe *pKeyframe1, const std::string& propName, cocos2d::Node *pNode); void setAnimatedProperty(const std::string& propName, cocos2d::Node *pNode, const cocos2d::Value& value, Ref* obj, float fTweenDuration, bool isBaseValue); void setFirstFrame(cocos2d::Node *pNode, REDSequenceProperty *pSeqProp, float fTweenDuration); cocos2d::ActionInterval* getEaseAction(cocos2d::ActionInterval *pAction, REDKeyframe::EasingType easingType, float* fEasingOpt); void runAction(cocos2d::Node *pNode, REDSequenceProperty *pSeqProp, float fTweenDuration); void sequenceCompleted(const std::function &callback); void updateSpeed(float speed, cocos2d::Node* node); void resetAllChildrenAnimtion(int nSeqId, float fTweenDuration, bool isRunAction); private: cocos2d::Vector _sequences; std::unordered_map>> _nodeSequences; std::unordered_map> _baseValues; std::unordered_map> _objects; int _autoPlaySequenceId; cocos2d::Node *_rootNode; cocos2d::Size _rootContainerSize; REDAnimationManagerDelegate *_delegate; // REDSequence *_runningSequence; std::pair> _runningSequence; std::map> _runningActions; cocos2d::ValueVector _documentOutletNames; cocos2d::Vector _documentOutletNodes; cocos2d::ValueVector _documentCallbackNames; cocos2d::Vector _documentCallbackNodes; cocos2d::ValueVector _documentCallbackControlEvents; cocos2d::ValueVector _keyframeCallbacks; cocos2d::Map _keyframeCallFuncs; std::string _documentControllerName; std::string _lastCompletedSequenceName; cocos2d::SEL_CallFunc _animationCompleteCallbackFunc; cocos2d::Ref *_target; std::string _ccbFileName; REDAnimationManagerDelegate *_listen; int _lastTag; int _nowTag; public: friend class RedreamAnim; }; class CC_DLL REDSetSpriteFrame : public cocos2d::ActionInstant { public: /** creates a Place action with a position */ static REDSetSpriteFrame* create(cocos2d::SpriteFrame *pSpriteFrame); /** * @js NA * @lua NA */ ~REDSetSpriteFrame(); bool initWithSpriteFrame(cocos2d::SpriteFrame *pSpriteFrame); // Overrides virtual void update(float time) override; virtual REDSetSpriteFrame* clone() const override; virtual REDSetSpriteFrame* reverse() const override; private: cocos2d::SpriteFrame *_spriteFrame; }; class CC_DLL REDAnimation : public cocos2d::ActionInstant { public: /** creates a Place action with a position */ static REDAnimation* create(int animationId); /** * @js NA * @lua NA */ ~REDAnimation(); bool initWithAnimationId(int animationId); // Overrides virtual void update(float time) override; virtual REDAnimation* clone() const override; virtual REDAnimation* reverse() const override; private: int _animationId; }; class CC_DLL REDSoundEffect : public cocos2d::ActionInstant { public: static REDSoundEffect* actionWithSoundFile(const std::string &file, float pitch, float pan, float gain); /** * @js NA * @lua NA */ ~REDSoundEffect(); bool initWithSoundFile(const std::string &file, float pitch, float pan, float gain); // Overrides virtual void update(float time) override; virtual REDSoundEffect* clone() const override; virtual REDSoundEffect* reverse() const override; private: std::string _soundFile; float _pitch, _pan, _gain; }; class CC_DLL REDWiseEffect : public cocos2d::ActionInstant { public: static REDWiseEffect* actionWithConfig(const std::string &btnFileName, const std::string &eventName, bool forcePostEvent, const ValueVector& params); ~REDWiseEffect(); bool initWithConfig(const std::string &btnFileName, const std::string &eventName, bool forcePostEvent, const ValueVector& params); // Overrides virtual void update(float time) override; virtual REDWiseEffect* clone() const override; virtual REDWiseEffect* reverse() const override; private: std::string _btnFileName; std::string _eventName; bool _forcePostEvent; ValueVector _params; }; class CC_DLL REDLabelString : public cocos2d::ActionInstant { public: static REDLabelString* actionWithText(const std::string &text); /** * @js NA * @lua NA */ ~REDLabelString(); bool initWithText(const std::string &text); // Overrides virtual void update(float time) override; virtual REDLabelString* clone() const override; virtual REDLabelString* reverse() const override; private: std::string _text; }; class CC_DLL REDRotateTo : public cocos2d::ActionInterval { public: static REDRotateTo* create(float fDuration, float fAngle); bool initWithDuration(float fDuration, float fAngle); // Override virtual void update(float time) override; virtual REDRotateTo* clone() const override; virtual REDRotateTo* reverse() const override; virtual void startWithTarget(cocos2d::Node *pNode) override; private: float _startAngle; float _dstAngle; float _diffAngle; }; class CC_DLL REDRotateXTo: public cocos2d::ActionInterval { public: static REDRotateXTo* create(float fDuration, float fAngle); bool initWithDuration(float fDuration, float fAngle); // Overrides virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDRotateXTo* clone() const override; virtual REDRotateXTo* reverse() const override; virtual void update(float time) override; private: float _startAngle; float _dstAngle; float _diffAngle; }; class CC_DLL REDRotateYTo: public cocos2d::ActionInterval { public: static REDRotateYTo* create(float fDuration, float fAngle); bool initWithDuration(float fDuration, float fAngle); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDRotateYTo* clone() const override; virtual REDRotateYTo* reverse() const override; virtual void update(float time) override; private: float _startAngle; float _dstAngle; float _diffAngle; }; class CC_DLL REDFrameIndexTo : public cocos2d::ActionInterval { public: static REDFrameIndexTo* create(float fDuration, int startIndex, int endIndex); bool initWithDuration(float fDuration, int startIndex, int endIndex); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDFrameIndexTo* clone() const override; virtual REDFrameIndexTo* reverse() const override; virtual void update(float time) override; private: int _startIndex; int _endIndex; float _diffIndex; }; // add zml 粒子属性动画 // 粒子生成器尺寸 class CC_DLL REDParticlePosVarTo : public cocos2d::ActionInterval { public: static REDParticlePosVarTo* create(float fDuration, cocos2d::Vec2 size); bool initWithDuration(float fDuration, cocos2d::Vec2 size); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticlePosVarTo* clone() const override; virtual REDParticlePosVarTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startGravity; cocos2d::Vec2 _endGravity; cocos2d::Vec2 _diffGravity; }; // 重力 class CC_DLL REDGravityTo : public cocos2d::ActionInterval { public: static REDGravityTo* create(float fDuration, cocos2d::Vec2 gravity); bool initWithDuration(float fDuration, cocos2d::Vec2 gravity); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDGravityTo* clone() const override; virtual REDGravityTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startGravity; cocos2d::Vec2 _endGravity; cocos2d::Vec2 _diffGravity; }; //粒子速度 class CC_DLL REDParticleSpeedTo : public cocos2d::ActionInterval { public: static REDParticleSpeedTo* create(float fDuration, cocos2d::Vec2 gravity); bool initWithDuration(float fDuration, cocos2d::Vec2 gravity); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleSpeedTo* clone() const override; virtual REDParticleSpeedTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子生命 class CC_DLL REDParticleLifeTo : public cocos2d::ActionInterval { public: static REDParticleLifeTo* create(float fDuration, cocos2d::Vec2 gravity); bool initWithDuration(float fDuration, cocos2d::Vec2 gravity); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleLifeTo* clone() const override; virtual REDParticleLifeTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子开始大小 class CC_DLL REDParticleStartSizeTo : public cocos2d::ActionInterval { public: static REDParticleStartSizeTo* create(float fDuration, cocos2d::Vec2 gravity); bool initWithDuration(float fDuration, cocos2d::Vec2 gravity); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleStartSizeTo* clone() const override; virtual REDParticleStartSizeTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子结束尺寸 class CC_DLL REDParticleEndSizeTo : public cocos2d::ActionInterval { public: static REDParticleEndSizeTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleEndSizeTo* clone() const override; virtual REDParticleEndSizeTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子开始旋转角度 class CC_DLL REDParticleStartSpinTo : public cocos2d::ActionInterval { public: static REDParticleStartSpinTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleStartSpinTo* clone() const override; virtual REDParticleStartSpinTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子结束旋转角度 class CC_DLL REDParticleEndSpinTo : public cocos2d::ActionInterval { public: static REDParticleEndSpinTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleEndSpinTo* clone() const override; virtual REDParticleEndSpinTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子发射角度 class CC_DLL REDParticleAngleTo : public cocos2d::ActionInterval { public: static REDParticleAngleTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleAngleTo* clone() const override; virtual REDParticleAngleTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子重力模式切向加速度 class CC_DLL REDParticleTangentialAccelTo : public cocos2d::ActionInterval { public: static REDParticleTangentialAccelTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleTangentialAccelTo* clone() const override; virtual REDParticleTangentialAccelTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子径向加速度 class CC_DLL REDParticleRadialAccelTo : public cocos2d::ActionInterval { public: static REDParticleRadialAccelTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleRadialAccelTo* clone() const override; virtual REDParticleRadialAccelTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子半径模式开始半径 class CC_DLL REDParticleStartRadiusTo : public cocos2d::ActionInterval { public: static REDParticleStartRadiusTo* create(float fDuration, cocos2d::Vec2 floatVar); bool initWithDuration(float fDuration, cocos2d::Vec2 floatVar); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleStartRadiusTo* clone() const override; virtual REDParticleStartRadiusTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子半径模式结束半径 class CC_DLL REDParticleEndRadiusTo : public cocos2d::ActionInterval { public: static REDParticleEndRadiusTo* create(float fDuration, cocos2d::Vec2 gravity); bool initWithDuration(float fDuration, cocos2d::Vec2 gravity); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleEndRadiusTo* clone() const override; virtual REDParticleEndRadiusTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; //粒子半径模式每秒旋转 class CC_DLL REDParticleRotatePerSecondTo : public cocos2d::ActionInterval { public: static REDParticleRotatePerSecondTo* create(float fDuration, cocos2d::Vec2 gravity); bool initWithDuration(float fDuration, cocos2d::Vec2 gravity); // Override virtual void startWithTarget(cocos2d::Node *pNode) override; virtual REDParticleRotatePerSecondTo* clone() const override; virtual REDParticleRotatePerSecondTo* reverse() const override; virtual void update(float time) override; private: cocos2d::Vec2 _startFloatVar; cocos2d::Vec2 _endFloatVar; cocos2d::Vec2 _diffFloatVar; }; class CC_DLL REDEaseInstant : public cocos2d::ActionEase { public: static REDEaseInstant* create(cocos2d::ActionInterval *pAction); virtual REDEaseInstant* clone() const override; virtual REDEaseInstant* reverse() const override; virtual void update(float dt) override; }; /** @class EaseBezierByTimeAction @brief Ease Bezier @ingroup Actions */ class CC_DLL EaseBezierByTimeAction : public cocos2d::ActionEase { public: /** @brief Create the action with the inner action. @param action The pointer of the inner action. @return A pointer of EaseBezierAction action. If creation failed, return nil. */ static EaseBezierByTimeAction* create(cocos2d::ActionInterval* action); virtual void update(float time) override; virtual EaseBezierByTimeAction* clone() const override; virtual EaseBezierByTimeAction* reverse() const override; /** @brief Set the bezier parameters. */ virtual void setBezierParamer( float p0, float p1, float p2, float p3); CC_CONSTRUCTOR_ACCESS: EaseBezierByTimeAction() {} virtual ~EaseBezierByTimeAction() {} protected: float _p0; float _p1; float _p2; float _p3; private: CC_DISALLOW_COPY_AND_ASSIGN(EaseBezierByTimeAction); }; #pragma mark - RedBakeAnimationInstantAction class CC_DLL RedBakeAnimationInstantAction: public cocos2d::ActionInstant { public: static RedBakeAnimationInstantAction* create(const RedBakeNodeFrame& frame); bool init(const RedBakeNodeFrame& frame); virtual void update(float time) override; virtual RedBakeAnimationInstantAction* clone() const override; virtual RedBakeAnimationInstantAction* reverse() const override; private: RedBakeNodeFrame _bakeFrame; }; } #endif // __RED_REDANIMATION_MANAGER_H__