REDBatchNode.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //
  2. // REDBatchNode.cpp
  3. // cocos2d_libs
  4. //
  5. // Created by xiao鱼哥 on 2023/2/2.
  6. //
  7. #include "REDBatchNode.h"
  8. #include "base/CCDirector.h"
  9. #include "2d/CCSprite.h"
  10. #include "2d/CCSpriteFrame.h"
  11. #include "2d/CCNode.h"
  12. #include "REDAnimationManager.h"
  13. #include "2d/CCParticleSystemQuad.h"
  14. #include "base/CCEventDispatcher.h"
  15. #include "base/CCEventCustom.h"
  16. #include "base/CCEventListenerCustom.h"
  17. #include "2d/CCProgressTimer.h"
  18. #include "REDBatchNodeManager.h"
  19. using namespace cocos2d;
  20. namespace redream {
  21. REDBatchNode::REDBatchNode(){
  22. }
  23. REDBatchNode::~REDBatchNode(){
  24. REDBatchNodeManager::getInstance()->removeListener(_redreamName, this);
  25. }
  26. void REDBatchNode::setBatchPlistSpriteNames(REDPlistPic & SpNames){
  27. _needBatchPlistSpriteNames = SpNames;
  28. }
  29. void REDBatchNode::setRootNode(Node* node,REDAnimationManager* animMgr){
  30. if (_rootNode) {
  31. CCASSERT(0, "不允许再次设置");
  32. return;
  33. }
  34. _rootNode = node;
  35. _animMgr = animMgr;
  36. _redreamName = _animMgr->getREDFileName();
  37. REDBatchNodeManager::getInstance()->addListener(_redreamName, this);
  38. }
  39. void REDBatchNode::onListener(){
  40. mergeFinish();
  41. }
  42. void REDBatchNode::mergeFinish() {
  43. batchEnd(_rootNode);
  44. //重置一下帧动画,
  45. _animMgr->resetSpriteFrameOfAllChildrenAnimtion();
  46. };
  47. ///更新自己的frame
  48. ///@return true记录,下次快速访问
  49. bool REDBatchNode::resetSprite(Sprite* sp){
  50. ///获取SF,肯定会有.不会为空
  51. SpriteFrame* sf = sp->getSpriteFrame();
  52. string sfName = sf->getSpriteFrameName();
  53. if (sfName.empty()) {
  54. ///如果是空,说明是单图,暂时不处理
  55. ///为什么是空,是单图==> SpriteFrame的创建有2中方式,单图和plist,
  56. ///如果是plist则在添加到FrameCache时也会设置SpriteFrameName这个属性,
  57. ///如果是单图,也可能会有 _textureFilename这个属性,也可能没有.
  58. ///通过creat(filename...这样创建的就有,否则没有.
  59. }
  60. else{
  61. unordered_set<string> plist = _animMgr->getRepleacePlistSt();
  62. SpriteFrameCache* sfc = SpriteFrameCache::getInstance();
  63. SpriteFrame* nsf = sfc->getSpriteFrameByName(sfName,plist);
  64. if (nsf) {
  65. sp->setSpriteFrame(nsf);
  66. sp->setDirty(true);
  67. }
  68. else{
  69. // CCLOG("合批之后,有图没有找到 %s/%s",plist.c_str(),sfName.c_str());
  70. // CCASSERT(false, Str);
  71. }
  72. return true;
  73. }
  74. return false;
  75. }
  76. ///重置当前node,更加node的实际类型,做对应的操作.
  77. ///@return true 是否记录,下次快速访问使用
  78. bool REDBatchNode::resetNode(Node* node){
  79. ///Scale9Sprite 一样处理
  80. ///ControlButton中也是创建了Sprite作为child加入的.
  81. Sprite* sp = dynamic_cast<Sprite *>(node);
  82. if (sp) {//进入sprite的逻辑
  83. BlendFunc blendFunc = sp->getBlendFunc();
  84. if (resetSprite(sp)) {
  85. sp->setBlendFunc(blendFunc);
  86. return true;
  87. }
  88. return false;
  89. }
  90. ProgressTimer* pt = dynamic_cast<ProgressTimer*>(node);
  91. if (pt) {//进入 ProgressTimer 的逻辑
  92. Sprite* sp1 = pt->getSprite();
  93. if (sp1) {
  94. BlendFunc blendFunc = sp1->getBlendFunc();
  95. if (resetSprite(sp1)) {
  96. pt->resetBySpriteFrame();
  97. pt->setPercentage(pt->getPercentage());
  98. sp1->setBlendFunc(blendFunc);
  99. return true;
  100. }
  101. }
  102. return false;
  103. }
  104. //粒子特效.从CCB加载过程,会记录纹理Texture,这个纹理 可能是从Plist读的,也可能是单图.
  105. //如果是plist读的,则需要记住 frameName,需要改粒子的加载过程中的
  106. //如果是单图,也需要记录当时的路径,但是Texture2d里面的filepath已经是处理的路径,所以也需要记住单独的文件.
  107. //所以 如果需要支持所有的例子效果.需要改动的地方比较多.
  108. ZMLCCParticleSystemQuad* psq = dynamic_cast<ZMLCCParticleSystemQuad*>(node);
  109. if (psq) {
  110. BlendFunc blendFunc = psq->getBlendFunc();
  111. psq->resetTextureByKeyInfo(_animMgr->getRepleacePlistSt());
  112. psq->setBlendFunc(blendFunc);
  113. return true;
  114. }
  115. ParticleSystemQuad* ccpsq = dynamic_cast<ParticleSystemQuad*>(node);
  116. if (ccpsq) {
  117. BlendFunc blendFunc = ccpsq->getBlendFunc();
  118. ccpsq->resetTextureByKeyInfo(_animMgr->getRepleacePlistSt());
  119. ccpsq->setBlendFunc(blendFunc);
  120. return true;
  121. }
  122. return false;
  123. }
  124. void REDBatchNode::batchEnd(Node* node){
  125. resetNode(node);
  126. cocos2d::Vector<Node*>& children = node->getChildren();
  127. for( const auto &child: children){
  128. if (child->getBatchNode() == nullptr) {//子类不是batchNode的才进入.
  129. batchEnd(child);
  130. }
  131. else{
  132. CCLOG("这是一个嵌套的batchredream,不需要父节点处理,他自己去处理吧!");
  133. }
  134. }
  135. };
  136. bool REDBatchNode::init(){
  137. return true;
  138. }
  139. REDBatchNode *REDBatchNode::create()
  140. {
  141. REDBatchNode *ret = new (std::nothrow) REDBatchNode();
  142. if (ret && ret->init())
  143. {
  144. ret->autorelease();
  145. return ret;
  146. }
  147. else
  148. {
  149. CC_SAFE_DELETE(ret);
  150. return nullptr;
  151. }
  152. }
  153. }