IAPCtlShopUI.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //
  2. // IAPCtlShopUI.cpp
  3. // TileManor
  4. //
  5. // Created by 徐炼新 on 2024/1/16.
  6. //
  7. #include "IAPCtlShopUI.hpp"
  8. #include "IAPCtlShopItem.hpp"
  9. #include "RUUtils.h"
  10. #include "RUPlatform.h"
  11. IAPCtlShopUI* IAPCtlShopUI::_instance = nullptr;
  12. IAPCtlShopUI* IAPCtlShopUI::getInstance() {
  13. if (_instance == nullptr) {
  14. _instance = new IAPCtlShopUI();
  15. _instance->autorelease();
  16. _instance->retain();
  17. }
  18. return _instance;
  19. }
  20. IAPCtlShopUI::IAPCtlShopUI() {
  21. }
  22. IAPCtlShopUI::~IAPCtlShopUI() {
  23. }
  24. bool IAPCtlShopUI::isShowing() {
  25. return _bUIShowing;
  26. }
  27. void IAPCtlShopUI::clear() {
  28. _goodsInfo.clear();
  29. for (auto& gi : _goodsItems) {
  30. gi->release();
  31. }
  32. _goodsItems.clear();
  33. _allSizes.clear();
  34. _cb = nullptr;
  35. }
  36. bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, int placementId) {
  37. redutils::Platform::getInstance()->reportLog("open iap");
  38. _cfg = cfg;
  39. _bUIShowing = true;
  40. _placementId = placementId;
  41. clear();
  42. _layer = redutils::RUReboltLayer::createReboltLayer("shop_interface.redream");
  43. pNode->addChild(_layer, 3);
  44. _layer->registerOnNotify([this](const redutils::ReboltNotifyData& data){
  45. _onNotifyDevelopment(data);
  46. });
  47. _layer->runBehaviacWhitFunName("初始化");
  48. // _igCoin->doOwnInit();
  49. if (_goodsInfo.size() == 0) {
  50. IAPConf::getInstance()->getAllGoods(_goodsInfo);
  51. }
  52. // 构建 list 区域
  53. constructShopItem(false);
  54. cocos2d::Size size = _ndScrollArea->getContentSize();
  55. _tableView = redutils::RUTableView::create(&_tableData, cocos2d::Size(size.width, size.height));
  56. _tableView->setCascadeOpacityEnabled(true);
  57. _tableView->setCascadeColorEnabled(true);
  58. _tableView->setDirection(ScrollViewSmooth::Direction::VERTICAL);
  59. _tableView->setVerticalFillOrder(TableViewSmooth::VerticalFillOrder::TOP_DOWN, false);
  60. _tableView->setDelegate(&_tableData);
  61. _tableView->setBounceable(true);
  62. // _tableView->setOutSightClean(false);
  63. _ndScrollArea->addChild(_tableView);
  64. return true;
  65. }
  66. bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, iap::ShopRequirement& requirement,int placementId) {
  67. redutils::Platform::getInstance()->reportLog("open iap");
  68. _cfg = cfg;
  69. _bUIShowing = true;
  70. _placementId = placementId;
  71. clear();
  72. _layer = redutils::RUReboltLayer::createReboltLayer("shop_interface.redream");
  73. pNode->addChild(_layer, 3);
  74. _layer->registerOnNotify([this](const redutils::ReboltNotifyData& data){
  75. _onNotifyDevelopment(data);
  76. });
  77. _layer->runBehaviacWhitFunName("初始化");
  78. // _igCoin->doOwnInit();
  79. if (_goodsInfo.size() == 0) {
  80. IAPConf::getInstance()->getAllGoods(_goodsInfo);
  81. }
  82. sortGoods(requirement);
  83. // 构建 list 区域
  84. constructShopItem(false);
  85. cocos2d::Size size = _ndScrollArea->getContentSize();
  86. _tableView = redutils::RUTableView::create(&_tableData, cocos2d::Size(size.width, size.height));
  87. _tableView->setCascadeOpacityEnabled(true);
  88. _tableView->setCascadeColorEnabled(true);
  89. _tableView->setDirection(ScrollViewSmooth::Direction::VERTICAL);
  90. _tableView->setVerticalFillOrder(TableViewSmooth::VerticalFillOrder::TOP_DOWN, false);
  91. _tableView->setDelegate(&_tableData);
  92. _tableView->setBounceable(true);
  93. // _tableView->setOutSightClean(false);
  94. _ndScrollArea->addChild(_tableView);
  95. return true;
  96. }
  97. void IAPCtlShopUI::_onNotifyDevelopment(const redutils::ReboltNotifyData& data) {
  98. if (data.notify == "绑定显示区域") {
  99. _ndScrollArea = data.outNode;
  100. } else if (data.notify == "绑定coin节点") {
  101. // _igCoin = new MapIGCoin(data.reboltRedManager);
  102. } else if (data.notify == "退出") {
  103. auto rm = RemoveSelf::create();
  104. auto cf = CallFunc::create([=]() {
  105. _layer->removeFromParent();
  106. _layer = nullptr;
  107. _bUIShowing = false;
  108. redutils::Platform::getInstance()->reportLog("iap closed");
  109. });
  110. _layer->runAction(Sequence::create(rm, cf, NULL));
  111. if (_cb) {
  112. _cb();
  113. }
  114. _cb = nullptr;
  115. }
  116. }
  117. void IAPCtlShopUI::constructShopItem(bool bShowAll) {
  118. int index = 0;
  119. _tableData.setCascadeOpacity(true);
  120. _tableData.clear();
  121. cocos2d::Size size = _ndScrollArea->getContentSize();
  122. auto delayIdx = 0;
  123. cocos2d::Vec2 offset(size.width, 0);
  124. float dur = 0.4;
  125. int height = 0;
  126. // 加入一个表头
  127. {
  128. Node* nd = Node::create();
  129. _tableData.insertCell(index++, nd);
  130. int h = size.height*0.08;
  131. _allSizes.push_back(cocos2d::Size(size.width, h));
  132. height += h;
  133. }
  134. // 当前有效的区域
  135. for (const auto& gi : _goodsInfo) {
  136. if (bShowAll || gi.always) {
  137. bool bNeedAnim = height <= size.height;
  138. Node* nd = Node::create();
  139. nd->setCascadeOpacityEnabled(true);
  140. nd->setCascadeColorEnabled(true);
  141. auto si = IAPCtlShopItem::create(gi, _placementId);
  142. auto sz = si->getSize();
  143. cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
  144. nd->addChild(si);
  145. si->setPosition(bNeedAnim ? pos+offset : pos);
  146. _goodsItems.push_back(si);
  147. _tableData.insertCell(index++, nd);
  148. _allSizes.push_back(sz);
  149. height += sz.height;
  150. if (bNeedAnim) {
  151. // 加入动画
  152. auto d = DelayTime::create(delayIdx*dur/8.0);
  153. auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
  154. si->runAction(Sequence::create(d, m, NULL));
  155. delayIdx ++;
  156. }
  157. }
  158. }
  159. if (!bShowAll) {
  160. // 加入show All btn, 这个是一定会有动画的
  161. auto sz = cocos2d::Size(584, 130);
  162. Node* nd = Node::create();
  163. nd->setCascadeOpacityEnabled(true);
  164. nd->setCascadeColorEnabled(true);
  165. _btnShowAll = redutils::RUReboltLayer::createReboltLayer("shop_more_btn.redream");
  166. nd->addChild(_btnShowAll);
  167. _btnShowAll->setPosition(Vec2(size.width/2.0, sz.height/2.0) + offset);
  168. _tableData.insertCell(index++, nd);
  169. _btnShowAll->registerOnNotify([this](const redutils::ReboltNotifyData& data){
  170. if (data.notify == "点击") {
  171. auto rm = RemoveSelf::create();
  172. auto cf = CallFunc::create([=](){
  173. _btnShowAll = NULL;
  174. _tableData.clear();
  175. _goodsItems.clear();
  176. _allSizes.clear();
  177. constructShopItem(true);
  178. _tableView->reloadData(true);
  179. });
  180. _btnShowAll->runAction(Sequence::create(rm, cf, NULL));
  181. }
  182. });
  183. redutils::iterateNode(nd, [](Node* nd){
  184. nd->setCascadeOpacityEnabled(true);
  185. nd->setCascadeColorEnabled(true);
  186. });
  187. _btnShowAll->runBehaviacWhitFunName("初始化");
  188. _allSizes.push_back(sz);
  189. // 加入动画
  190. auto d = DelayTime::create(delayIdx*dur/8.0);
  191. auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
  192. _btnShowAll->runAction(Sequence::create(d, m, NULL));
  193. delayIdx ++;
  194. } else {
  195. // 底部添加一个额外节点(一个是底部的广告,还有就是美观一些)
  196. _tableData.insertCell(index++, Node::create());
  197. _allSizes.push_back(cocos2d::Size(584, 150));
  198. }
  199. _tableData._numberOfCellsInTableView = [=](cocos2d::extension::TableViewSmooth*)->ssize_t{
  200. return _allSizes.size();
  201. };
  202. _tableData._tableCellSizeForIndex = [=](cocos2d::extension::TableViewSmooth*, ssize_t idx)->Size{
  203. if (idx < _allSizes.size()) {
  204. return _allSizes[idx];
  205. } else {
  206. return Size(0,0);
  207. }
  208. };
  209. // 防止拉动的时候才创建
  210. _layer->scheduleOnce([=](float){
  211. for (int i=0; i<_allSizes.size(); i++) {
  212. _tableView->updateCellAtIndex(i);
  213. }
  214. }, 0.05, "SCH_Update_Cells");
  215. }
  216. void IAPCtlShopUI::sortGoods(iap::ShopRequirement &requirement){
  217. std::map<int, bool> m;
  218. int cnt = 0;
  219. for(const auto& goodsInfo : _goodsInfo){
  220. for(const auto area : goodsInfo.areas){
  221. bool flag = false;
  222. for(int i = 0;i < area.size(); i++){
  223. if(area[i].name != "coin")continue;
  224. if(std::stoi(area[i].count) >= requirement.coinsMin){
  225. m[cnt] = true;
  226. flag = true;
  227. break;
  228. }else{
  229. m[cnt] = false;
  230. flag = true;
  231. break;
  232. }
  233. }
  234. if(flag)break;
  235. }
  236. cnt++;
  237. }
  238. std::vector<GoodsInfo> newGoodsInfo;
  239. // 添加符合条件的礼包
  240. for(int i = 0;i < _goodsInfo.size(); i++){
  241. if(m[i]){
  242. newGoodsInfo.push_back(_goodsInfo[i]);
  243. }
  244. }
  245. // 添加不符合条件的礼包(不清楚是不是需要显示,暂放到列表末尾)
  246. for(int i = 0;i < _goodsInfo.size(); i++){
  247. if(!m[i]){
  248. newGoodsInfo.push_back(_goodsInfo[i]);
  249. }
  250. }
  251. _goodsInfo = newGoodsInfo;
  252. }
  253. void IAPCtlShopUI::quit() {
  254. if (_layer) {
  255. _layer->runBehaviacWhitFunName("退出");
  256. }
  257. }