123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- //
- // RedBakeNode.hpp
- // cocos2d_libs
- //
- // Created by Liang zhong on 2022/11/11.
- //
- #ifndef RedBakeNode_h
- #define RedBakeNode_h
- #include "2d/CCNode.h"
- #include <stdio.h>
- #include "cocos2d.h"
- #include "RedSpineBakeManage.h"
- #if COCOS2D_VERSION < 0x00040000
- #include <spine/SkeletonBatch.h>//v3/
- #include <spine/SkeletonTwoColorBatch.h>//v3/
- #else
- #include <spine/v4/SkeletonBatch.h>
- #include <spine/v4/SkeletonTwoColorBatch.h>
- #endif
- using namespace std;
- using namespace cocos2d;
- struct RedBakeNodeFrame {
- std::string animationName; // 时间线名字
- float elapsedTime = .0; // 当前播放过的时间
- bool loop = true; // 是否循环
-
- RedBakeNodeFrame()
- : animationName(""),
- elapsedTime(0.0f),
- loop(true)
- {}
-
- RedBakeNodeFrame(const std::string& _animationName, float _elapsedTime, bool _loop)
- : animationName(_animationName),
- elapsedTime(_elapsedTime),
- loop(_loop)
- {}
- };
- enum RBN_STATE {Unknown,Complete,Break,Pause,Resume,MixPreAniEnd};
- typedef std::function<void(std::string animationName,RBN_STATE aState)> RBNListener;
- class RedBakeNode : public Node {
- public:
- static RedBakeNode *create(const std::string aFileName);
- static RedBakeNode *create();
-
- RedBakeNode(const std::string aFileName);
- RedBakeNode();
- ~RedBakeNode();
-
- // 属性设置
- void setBakeDataFile(const std::string& aFileName);
- const std::string& getBakeDataFile() const; // 当前选中播放中的时间线
-
- // 时间线K帧支持
- std::vector<std::string> getAnimations(); // 所有的时间线列表
- void setBakeFrame(RedBakeNodeFrame frame); // 设置节点为指定时间线,指定时间的状态
- RedBakeNodeFrame getBakeFrame();
-
- // 打开或者关闭自动绘制(每帧自动绘制)
- void startAutoDraw();
- void stopAutoDraw();
-
- // 获取时间线的长度
- float getAnimDuration(const std::string& tl);
-
- bool playAnimation (const std::string& animationName, bool loop, float spdRate = 1.f);
- bool stopCurrentAnimation();
- bool pauseCurrentAnimation();
- bool resumeCurrentAnimation();
- bool currentAnimationIsPaused();
- bool playMixAnimation(const std::string& animationName, bool loop,float aMixTime);
- bool playMixAnimation(const std::string& animationName, bool loop,float aMixTime,Point aDis);//Point aDis用来处理上下节点连接时,初始位置有偏移,单一节点不需要
- bool IscurrentAnimationFinished();
- void updateLoop(bool loop);
-
- void setFlipX(bool aFlipX); //当前动画是否X翻转
- bool isFlipX(); //当前动画是否翻转
- void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override;
- void drawBake (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) ;
- void drawMixBake (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) ;
-
- void setBakeSpineID(std::string aId);
- void resetPlayInfo();
- void setRBNListener(RBNListener& aListener);
- void update (float deltaTime) override;
- void updateSelfFunc(float deltaTime, bool bInFrameMode = false);
-
- //组合bakenode的时候调整绘制顺序
- void drawSelfFunc(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags);
- void addAttachNodeBeforeSlot(std::string aSlotName,RedBakeNode * aBakeNode);//添加一个绘制附件,并指定一个slot绑定,绘制层时先绘制bakenode再绘制slot
- void removeAttachNode(std::string aSlotName);//删除一个slot
- void removeAllAttachNode();//删除全部slot
- void attachNodeBeUpdated();//当Attach修改的时候,需要更新下singleattch和attchsize
-
- //组合Bakenode时候父子连动
- void addFatherNodeBindMove(std::string aBoneName,RedBakeNode * aBakeNode);//添加父Bakenode,确保自己和父node一起运动,aBoneName是父node关于自己的连接点
- void removeFatherNode();//移除父Bakenode,确保自己和父node一起运动,aBoneName是父node关于自己的连接点
- const Point getFatherBoneOffset(std::string aBoneName);//获取父节点对应bone的偏移量
- const Point getFatherBoneOffsetByIndex(int aIndex);//获取父节点对应bone的偏移量
- int getFatherBoneOffsetIndex(std::string aBoneName);//获取父节点对应bone的偏移量对应的数组索引,用来加速性能
-
- //用来记录多个spine合并播放时,骨骼连接点初始的位置差
- void setDisPos(Point aPos);
-
- void updateRealCurrentBakeFrame(float aReal);//用来指定动画起始位子,这样上下半身走路可以同步,不会同手同脚
- float getRealCurrentBakeFrame();//获取当前播放的位置
-
- // 设置纹理
- void setTexture(Texture2D*);
-
- void setEventCallBack(std::function<void(std::string)> cb);
-
- void handleEvent(std::function<void(std::string)> cb);
-
- Vec2 getSpeechPos();
- protected:
- bool animationIsInscreen(); //判断某个Slot是否在屏幕内
- void _stopSelfDraw(); //关闭自我绘制功能,由其他RedBakeNode来绘制
- void _startSelfDraw(); //开启自我绘制功能
- //通过BakeFrame的小数部分合并两个Traingle中的顶点Vert的数据,相当于给动画做差值,因为帧率没有这么稳定,卡的时候走的可能是一帧半
- void mergeTwoVert(V3F_C4B_T2F *beginVert,V3F_C4B_T2F *endVert,int aCount,Point offsetPos);
-
- void _reloadVertMap();
-
- bool switchAnimation(const std::string& animationName, bool loop);
-
- RedBakeNodeFrame _curFrame;
- std::vector<V3F_C4B_T2F *> _vertArr;
-
- int _totalBakeFrame = -1; //指定当前的Animation最大的BakeFrame
- int _currentBakeFrame = -1; //当前的Animation播放到第几个BakeFrame
- float _realCurrentBakeFrame = -1;//当前的Animation播放到第几个BakeFrame,这个是实际值,因为帧无法完全对齐,每帧间隔在卡的时候会变
- float _currentFrameFracpart = 0.0; //当前的Animation播放到第几个BakeFrame的小数部分,rs = (1-_currentFrameFracpart)begin+end
- std::map<int,BKAE_FRAME_PLAY> _slotFrameArray; //记录当前slot各属性播放进度
- std::vector<BKAE_FRAME_PLAY *> _slotFrameArrayVect; //_slotFrameArray的加速版本,解决性能问题
- int _currentDrawOrderIndex = 0;
-
-
- std::string _bakeSpineID;
- bool _isLoop = false; //当前动画是否时Loop
- bool _firstDraw = true; //当前动画是否是首日调用
- bool _currentAnimationIsFinished = true; //当前动画是否播放完
- bool _currentAnimationIsPaused = false; //当前动画是否播暂停
- bool _isFlipX = false; //当前动画是否X翻转
- bool _isFirstReset = false; //每次调用playAnimation的时候设置成ture,每次resetPlayInfo设置成false,这样确保第一次resetPlayInfo能创建没有slot
- RedAnimationBakeModel *_currentBakeAnimation = nullptr;
- std::string _fileName;
- std::string _fileNameFull;
- RBNListener _listener = nullptr;
-
- SEL_SCHEDULE _schUpdate = nullptr;
-
- std::map<std::string,RedBakeNode *> _attachNodeMap; //记录挂载的RedBakeNode节点,用来组合RedBakeNode一起绘制的
- //判断_attachNodeMap是否改变,updateSelfFunc里面有遍历_attachNodeMap的,但是上半身结束的时候可能会导致下半身的_attachNodeMap重置,导致遍历出问题
- bool _attachNodeMapHasChanged = false;
- RedBakeNode *_singleAttachNode = nullptr;//当_attachNodeMap中size为1的时候,_singleAttachNode等于这个唯一,用于加速
- int _attachNodeMapSize = 0;//表示_attachNodeMap的数量
-
- bool _drawSelf = true; //是否自我绘制,默认true,自己会绘制自己,否就由其他RedBakeNode来调用Draw函数
-
- RedBakeNode *_fatherNode = nullptr; //记录当前节点需要跟随一起动的父节点
- std::string _fatherNodeBoneName; //记录当前节点需要跟随一起动的父节点的骨骼名字,这个骨骼定义了自己的偏移
- Point _disPos = {0,0}; //用来记录多个spine合并播放时,骨骼连接点初始的位置差
-
- Vec2 zeroPos;//默认的原点
- bool isInScreen = true; //当前Node是否在屏幕内
- int _fatherNodePosIndex = -1; //用来索引_fatherNode中Bone偏移放在数组的什么位子,这个数组是用来加快性能的,之前是Map,所以需要记录
-
- cocos2d::Mat4 newTransform;//用于draw里面处理flip
-
- Texture2D* _texture = nullptr;
-
- std::function<void(std::string)> _eventCallBack;
-
- Vec2 _speechPos = Vec2(0,0);
- };
- #endif /* RedBakeNode_h */
|