RUUtils.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. #include "RUUtils.h"
  2. #include "RUPlatform.h"
  3. #include <fstream>
  4. #include "RUMapRhombusGrid.h"
  5. #include "RUQCoreLayer.h"
  6. #include "RUQCoreBtn.h"
  7. NS_RU_BEGIN
  8. int randomInt(int start, int end){
  9. CCASSERT(end >= start, "----------ERROR:随机值范围不对");
  10. int len = end - start + 1;
  11. int value = rand() % len;
  12. return value + start;
  13. }
  14. int randomIndexByRatio(const vector<int> &array){
  15. //权重随机
  16. int allWeight = 0;
  17. for (int i = 0; i < array.size(); i++) {
  18. allWeight += array.at(i);
  19. };
  20. int randomNum = randomInt(1, allWeight);
  21. int flagWeight = 0;
  22. for (int i = 0; i < array.size(); i++) {
  23. int tWeight = array.at(i);
  24. flagWeight += tWeight;
  25. if (randomNum <= flagWeight) {
  26. return i;
  27. };
  28. };
  29. return 0;
  30. }
  31. Vec2 up(const Vec2 &logicPos){
  32. return Vec2(logicPos.x, logicPos.y - 1);
  33. }
  34. Vec2 down(const Vec2 &logicPos){
  35. return Vec2(logicPos.x, logicPos.y + 1);
  36. }
  37. Vec2 left(const Vec2 &logicPos){
  38. return Vec2(logicPos.x - 1, logicPos.y);
  39. }
  40. Vec2 right(const Vec2 &logicPos){
  41. return Vec2(logicPos.x + 1, logicPos.y);
  42. }
  43. Vec2 upLeft(const Vec2 &logicPos){
  44. return Vec2(logicPos.x - 1, logicPos.y - 1);
  45. }
  46. Vec2 upRight(const Vec2 &logicPos){
  47. return Vec2(logicPos.x + 1, logicPos.y -1);
  48. }
  49. Vec2 downLeft(const Vec2 &logicPos){
  50. return Vec2(logicPos.x - 1, logicPos.y + 1);
  51. }
  52. Vec2 downRight(const Vec2 &logicPos){
  53. return Vec2(logicPos.x + 1, logicPos.y + 1);
  54. }
  55. void LockScreenForSec(float sec)
  56. {
  57. redutils::Platform::getInstance()->reportLog("LockScreenForSec start");
  58. Layer* layer = Layer::create();
  59. Scene* scene = Director::getInstance()->getRunningScene();
  60. scene->addChild(layer);
  61. EventDispatcher* eventDispatcher = Director::getInstance()->getEventDispatcher();
  62. auto listen = EventListenerTouchOneByOne::create();
  63. listen->onTouchBegan = [](Touch*touch, Event*event){return true;};
  64. listen->setSwallowTouches(true);
  65. eventDispatcher->addEventListenerWithSceneGraphPriority(listen,layer);
  66. layer->runAction(Sequence::create(DelayTime::create(sec),CallFunc::create(CC_CALLBACK_0(Layer::removeFromParent,layer)),nullptr));
  67. redutils::Platform::getInstance()->reportLog("LockScreenForSec end");
  68. }
  69. void LockScreenByTag(int tag)
  70. {
  71. #define LOCAL_ZORDER_TOP (100000)
  72. Layer* layer = Layer::create();
  73. Scene* scene = Director::getInstance()->getRunningScene();
  74. scene->addChild(layer, LOCAL_ZORDER_TOP, tag);
  75. EventDispatcher* eventDispatcher = Director::getInstance()->getEventDispatcher();
  76. auto listen = EventListenerTouchOneByOne::create();
  77. listen->onTouchBegan = [](Touch*touch, Event*event){return true;};
  78. listen->setSwallowTouches(true);
  79. eventDispatcher->addEventListenerWithSceneGraphPriority(listen, layer);
  80. }
  81. void unLockScreenByTag(int tag)
  82. {
  83. Scene* scene = Director::getInstance()->getRunningScene();
  84. Node* node = scene->getChildByTag(tag);
  85. if(node){
  86. node->removeFromParent();
  87. }
  88. }
  89. void splitString(const std::string& s, std::vector<std::string>& v, const std::string& c)
  90. {
  91. if (s.length() == 1 && s != c) {
  92. v.push_back(s);
  93. return;
  94. }
  95. std::string::size_type pos1, pos2;
  96. pos2 = s.find(c);
  97. pos1 = 0;
  98. while(std::string::npos != pos2)
  99. {
  100. v.push_back(s.substr(pos1, pos2-pos1));
  101. pos1 = pos2 + c.size();
  102. pos2 = s.find(c, pos1);
  103. }
  104. if(pos1 != s.length())
  105. v.push_back(s.substr(pos1));
  106. }
  107. ProgressTimer* createCCProgressTimeFromCCSprite(Sprite* sprite,const ProgressArgs& args){
  108. auto midPoint = args.midPoint;
  109. auto barChangeRate = args.barChangeRate;
  110. auto reverse = args.reverse;
  111. auto progressType = args.progressType;
  112. auto progressTime = ProgressTimer::create(sprite);
  113. progressTime->setType(progressType);
  114. progressTime->setMidpoint(midPoint);
  115. progressTime->setBarChangeRate(barChangeRate);
  116. progressTime->setReverseDirection(reverse);
  117. progressTime->setScaleX(sprite->getScaleX());
  118. progressTime->setScaleY(sprite->getScaleY());
  119. progressTime->setPosition(sprite->getPosition());
  120. progressTime->setRotation(sprite->getRotation());
  121. sprite->getParent()->addChild(progressTime);
  122. sprite->setVisible(false);
  123. return progressTime;
  124. }
  125. int getGTLevel(kGTLevelType type, int baseLevel)
  126. {
  127. int gtLevel = baseLevel;
  128. switch (type) {
  129. case kGTLevelType::DEFAULT:
  130. gtLevel = -gtLevel;
  131. break;
  132. case kGTLevelType::MINIGAME:
  133. gtLevel += 1000;
  134. break;
  135. case kGTLevelType::BI_ROOM:
  136. gtLevel += 9000;
  137. break;
  138. case kGTLevelType::BI_TASK:
  139. gtLevel += 10000;
  140. break;
  141. default:
  142. break;
  143. }
  144. return -1 * gtLevel;
  145. }
  146. bool protobufLoad(const string& fileName, google::protobuf::MessageLite* data){
  147. std::string writablePath = FileUtils::getInstance()->getWritablePath();
  148. string file = writablePath + "/" + fileName;
  149. if(FileUtils::getInstance()->isFileExist(file)){
  150. Data datas = FileUtils::getInstance()->getDataFromFile(file);
  151. data->ParseFromArray(datas.getBytes(), datas.getSize());
  152. return true;
  153. }
  154. return false;
  155. }
  156. void protobufSave(const string& fileName, google::protobuf::MessageLite* data){
  157. std::string writablePath = FileUtils::getInstance()->getWritablePath();
  158. string file = writablePath + "/" + fileName;
  159. fstream output(file, ios::out | ios::trunc | ios::binary);
  160. data->SerializeToOstream(&output);
  161. output.close();
  162. }
  163. vector<Vec2> getRhombusGridFromPolygon(const Vec2& ori, vector<Vec2> poly, MapRhombusGrid* rhombusGrid, bool bStrictMode) {
  164. /*占用网格,要考虑包容或相交
  165. 1.多边形包含网格 判断网格中有点在多边形内部
  166. 2.网格包含多边形 判断多边形中有点在网格内部。 (1,2)可以用射线法判断
  167. 3.相交 枚举多边形边和网格变判断相交即可。 线段相交
  168. */
  169. Size gridSize = rhombusGrid->getRhombusSize();
  170. #define max(x,y) (x>y?x:y)
  171. auto isIntersect = [](const pair<Vec2, Vec2>& line1, const pair<Vec2, Vec2>& line2) -> bool {
  172. double x1 = line1.first.x, y1 = line1.first.y, x2 = line1.second.x, y2 = line1.second.y;
  173. double x3 = line2.first.x, y3 = line2.first.y, x4 = line2.second.x, y4 = line2.second.y;
  174. double d = (y2 - y1) * (x4 - x3) - (x2 - x1) * (y4 - y3);
  175. if (d == 0) {
  176. return false;
  177. }
  178. double s = ((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)) / d;
  179. double t = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / (-d);
  180. return s >= 0 && s <= 1 && t >= 0 && t <= 1;
  181. };
  182. auto checkGridPoly = [=](const vector<Vec2>& gridPoly, const vector<Vec2>& poly)->bool{
  183. for(auto gridPoint:gridPoly){
  184. if(isPointInPolygon(gridPoint, poly))return true;
  185. }
  186. for(auto polyPoint:poly){
  187. if(isPointInPolygon(polyPoint, gridPoly))return true;
  188. }
  189. int ngridPoly = (int)gridPoly.size(), npoly = (int)poly.size();
  190. for(int i=0;i<ngridPoly;i++){
  191. for(int j=0;j<npoly;j++){
  192. if(isIntersect(make_pair(gridPoly[i], gridPoly[(i+1)%ngridPoly]), make_pair(poly[j], poly[(j+1)%npoly])))return true;
  193. }
  194. }
  195. return false;
  196. };
  197. vector<Vec2>res;
  198. int n = (int)poly.size();
  199. for(int i=0;i<n;i++) {poly[i].x-=ori.x, poly[i].y-=ori.y;}
  200. //计算可能grid
  201. int minX=poly[0].x, maxX=poly[0].x, minY=poly[0].y, maxY=poly[0].y;
  202. for(auto item:poly){
  203. if(item.x<minX)minX=item.x;
  204. if(item.x>maxX)maxX=item.x;
  205. if(item.y<minY)minY=item.y;
  206. if(item.y>maxY)maxY=item.y;
  207. }
  208. auto ld = rhombusGrid->getGridPosition(Vec2(minX,minY));
  209. auto ru = rhombusGrid->getGridPosition(Vec2(maxX,maxY));
  210. for(int i=max(0,ld.x-1);i<=ru.x+1;i++){
  211. for(int j=max(0,ld.y-1);j<=ru.y+1;j++){
  212. if((i+j)%2==0) continue;
  213. auto gridCenter = rhombusGrid->getGridCenter(Vec2(i,j));
  214. vector<Vec2> gridPoly;
  215. if (bStrictMode) {
  216. gridPoly.push_back(gridCenter+Vec2(0,gridSize.height/2));
  217. gridPoly.push_back(gridCenter+Vec2(gridSize.width/2,0));
  218. gridPoly.push_back(gridCenter+Vec2(0,-gridSize.height/2));
  219. gridPoly.push_back(gridCenter+Vec2(-gridSize.width/2,0));
  220. } else {
  221. float ratio = 0.2;
  222. {
  223. auto p = gridCenter+Vec2(0,gridSize.height/2)*ratio;
  224. float w = gridSize.width * (1.0-ratio) * ratio;
  225. gridPoly.push_back(Vec2(p.x - w/2.0, p.y));
  226. gridPoly.push_back(Vec2(p.x + w/2.0, p.y));
  227. }
  228. {
  229. auto p = gridCenter+Vec2(gridSize.width/2,0)*ratio;
  230. float h = gridSize.height * (1.0-ratio) * ratio;
  231. gridPoly.push_back(Vec2(p.x, p.y + h/2.0));
  232. gridPoly.push_back(Vec2(p.x, p.y - h/2.0));
  233. }
  234. {
  235. auto p = gridCenter+Vec2(0,-gridSize.height/2)*ratio;
  236. float w = gridSize.width * (1.0-ratio) * ratio;
  237. gridPoly.push_back(Vec2(p.x + w/2.0, p.y));
  238. gridPoly.push_back(Vec2(p.x - w/2.0, p.y));
  239. }
  240. {
  241. auto p = gridCenter+Vec2(-gridSize.width/2,0)*ratio;
  242. float h = gridSize.height * (1.0-ratio) * ratio;
  243. gridPoly.push_back(Vec2(p.x, p.y - h/2.0));
  244. gridPoly.push_back(Vec2(p.x, p.y + h/2.0));
  245. }
  246. }
  247. if (checkGridPoly(gridPoly, poly)) {
  248. res.push_back(Vec2(i,j));
  249. }
  250. }
  251. }
  252. return res;
  253. }
  254. int getLocalToday()
  255. {
  256. // 获取当前的系统时间
  257. auto now = std::chrono::system_clock::now();
  258. // 转换为 time_t
  259. std::time_t now_t = std::chrono::system_clock::to_time_t(now);
  260. // 转换为本地时间
  261. std::tm* now_local = std::localtime(&now_t);
  262. // 计算到1970-1-1的天数,考虑润年,但是不用考虑400年的问题
  263. int days = now_local->tm_yday + (now_local->tm_year - 70) * 365 + (now_local->tm_year - 69) / 4;
  264. return days;
  265. }
  266. ccBezierConfig calBezierConfig(const Vec2& startPoint, const Vec2& endPoint, string stencil, BezierParams* config) {
  267. ccBezierConfig res;
  268. res.endPosition = endPoint;
  269. // 计算endPoint相对于startPoint是哪个象限(方向)
  270. float valueX = endPoint.x > startPoint.x ? 1.0 : -1.0;
  271. float valueY = endPoint.y > startPoint.y ? 1.0 : -1.0;
  272. float distance = startPoint.distance(endPoint);
  273. // cos,sin为直线和x轴(1,0)或(-1,0)的夹角值,两值均为正值
  274. float cos = (endPoint.x - startPoint.x) * valueX / distance;
  275. float sin = sqrt(1 - pow(cos, 2));
  276. float bezierCur = config->bezierCur;
  277. float bezierDec = config->bezierDec;
  278. float basisPointRation = config->basisPointRatio;
  279. // 下沉后下弧线飞行到目标点
  280. if (stencil == "Subsidence") {
  281. // 控制点 2 为两点之间线段的中垂线上的一点,13象限左移x-,y+,24象限左移为x-,y-。此外sin,cos值外翻。
  282. float controlPoint2X = ((endPoint.x - startPoint.x) * basisPointRation + startPoint.x) + valueX * bezierCur * distance * sin;
  283. float controlPoint2Y = ((endPoint.y - startPoint.y) * basisPointRation + startPoint.y) - valueY * bezierCur * distance * cos;
  284. // 控制点1 为两点延长线的一点
  285. float controlPoint1X = startPoint.x - valueX * bezierDec * distance * cos;
  286. float controlPoint1Y = startPoint.y - valueY * bezierDec * distance * sin;
  287. res.controlPoint_1 = Vec2(controlPoint1X, controlPoint1Y);
  288. res.controlPoint_2 = Vec2(controlPoint2X, controlPoint2Y);
  289. }
  290. return res;
  291. }
  292. void iterateParticles(Node* pNode, std::function<void(cocos2d::ParticleSystem*)> cb) {
  293. if (pNode == nullptr) {
  294. return;
  295. }
  296. cocos2d::Vector<Node*> children = pNode->getChildren();
  297. for_each(children.begin(), children.end(), [=](Node* child) {
  298. ParticleSystem* part = dynamic_cast<ParticleSystem*>(child);
  299. if (part != nullptr) {
  300. cb(part);
  301. }
  302. if (child != nullptr) {
  303. iterateParticles(child, cb);
  304. }
  305. });
  306. }
  307. void iterateNode(Node* pNode, std::function<void(Node*)> cb) {
  308. if (pNode == nullptr) {
  309. return;
  310. }
  311. cocos2d::Vector<Node*> children = pNode->getChildren();
  312. for_each(children.begin(), children.end(), [=](Node* child) {
  313. cb(child);
  314. iterateNode(child, cb);
  315. });
  316. }
  317. void changeNodeParent(Node* node, Node* parent) {
  318. if (node->getParent() == parent) {
  319. return;
  320. }
  321. Vec2 pos = node->getParent()->convertToWorldSpace(node->getPosition());
  322. node->retain();
  323. node->removeFromParentAndCleanup(false);
  324. parent->addChild(node);
  325. node->setPosition(parent->convertToNodeSpace(pos));
  326. node->release();
  327. return;
  328. }
  329. bool isPointOnLine(const Vec2& point, const Vec2& lineStart, const Vec2& lineEnd) {
  330. float minX = fmin(lineStart.x, lineEnd.x);
  331. float maxX = fmax(lineStart.x, lineEnd.x);
  332. float minY = fmin(lineStart.y, lineEnd.y);
  333. float maxY = fmax(lineStart.y, lineEnd.y);
  334. // Check if the point's x and y are within the line's bounds
  335. if (point.x < minX || point.x > maxX || point.y < minY || point.y > maxY) {
  336. return false;
  337. }
  338. // Check if the point is on the line
  339. float dx = lineEnd.x - lineStart.x;
  340. float dy = lineEnd.y - lineStart.y;
  341. if (abs(dx * (point.y - lineStart.y) - dy * (point.x - lineStart.x)) < 0.00001) {
  342. return true;
  343. }
  344. return false;
  345. }
  346. bool isPointInPolygon(const Vec2& point, const std::vector<Vec2>& polygon) {
  347. bool inside = false;
  348. auto i = polygon.begin();
  349. auto j = std::prev(polygon.end()); // last vertex
  350. for (; i != polygon.end(); j = i++) {
  351. if (isPointOnLine(point, *i, *j)) {
  352. // The point is on the boundary
  353. return true;
  354. }
  355. if (((i->y > point.y) != (j->y > point.y)) &&
  356. (point.x < (j->x - i->x) * (point.y - i->y) / (j->y - i->y) + i->x)) {
  357. inside = !inside;
  358. }
  359. }
  360. return inside;
  361. }
  362. Json getConfigWithName(const std::string& jsonName) {
  363. Json json;
  364. const string path = jsonName;
  365. string cfg;
  366. Data datas = FileUtils::getInstance()->getDataFromFile(path);
  367. unsigned char* data = datas.getBytes();
  368. ssize_t len = datas.getSize();
  369. string err = "";
  370. cfg = string(data,data+len);
  371. json = Json::parse(cfg, err);
  372. CCASSERT(err == "", "load config failed !" + jsonName);
  373. if (!json.is_null()) {
  374. return json["main_sheet"];
  375. }
  376. return json;
  377. }
  378. std::list<float> parseAsFloatList(const string& v) {
  379. // str使用,分割的一系列float类型
  380. std::list<float> ret;
  381. int startPos = 0;
  382. int nPos = v.find(",");
  383. string conf = v.substr(startPos, nPos);
  384. while (nPos != string::npos) {
  385. ret.push_back(Value(conf).asFloat());
  386. startPos = nPos + 1;
  387. nPos = v.find(",", startPos);
  388. conf = v.substr(startPos, nPos-startPos);
  389. }
  390. // 最后一个
  391. ret.push_back(Value(conf).asFloat());
  392. return ret;
  393. }
  394. std::vector<string> parseAsStringList(const string& v, const string& sep) {
  395. // str使用,分割的一系列float类型
  396. std::vector<std::string> ret;
  397. int startPos = 0;
  398. int nPos = v.find(sep);
  399. string conf = v.substr(startPos, nPos);
  400. while (nPos != string::npos) {
  401. ret.push_back(conf);
  402. startPos = nPos + 1;
  403. nPos = v.find(sep, startPos);
  404. conf = v.substr(startPos, nPos-startPos);
  405. }
  406. // 最后一个
  407. ret.push_back(conf);
  408. return ret;
  409. }
  410. std::vector<int> parseAsIntList(const string& v) {
  411. // str使用,分割的一系列float类型
  412. std::vector<int> ret;
  413. int startPos = 0;
  414. int nPos = v.find(",");
  415. string conf = v.substr(startPos, nPos);
  416. while (nPos != string::npos) {
  417. ret.push_back(Value(conf).asInt());
  418. startPos = nPos + 1;
  419. nPos = v.find(",", startPos);
  420. conf = v.substr(startPos, nPos-startPos);
  421. }
  422. // 最后一个
  423. ret.push_back(Value(conf).asInt());
  424. return ret;
  425. }
  426. std::vector<std::pair<cocos2d::Value,cocos2d::Value>> parseAsPairList(const string& v, const string& sep) {
  427. // str使用,分割的一系列float类型
  428. std::vector<std::pair<cocos2d::Value,cocos2d::Value>> ret;
  429. auto nPos = v.find(sep);
  430. std::size_t startPos = 0;
  431. string conf = v.substr(startPos, nPos);
  432. while (nPos != string::npos) {
  433. {
  434. auto nPos1 = conf.find(":");
  435. ret.push_back({cocos2d::Value(conf.substr(0, nPos1)), cocos2d::Value(conf.substr(nPos1+1))});
  436. }
  437. startPos = nPos + 1;
  438. nPos = v.find(sep, startPos);
  439. conf = v.substr(startPos, nPos-startPos);
  440. }
  441. // 最后一个
  442. {
  443. auto nPos1 = conf.find(":");
  444. ret.push_back({cocos2d::Value(conf.substr(0, nPos1)), cocos2d::Value(conf.substr(nPos1+1))});
  445. }
  446. return ret;
  447. }
  448. std::vector<std::pair<std::string,std::string>> parseAsPairStringList(const string& v) {
  449. // str使用,分割的一系列string类型
  450. std::vector<std::pair<std::string,std::string>> ret;
  451. int startPos = 0;
  452. int nPos = v.find(",");
  453. string conf = v.substr(startPos, nPos);
  454. while (nPos != string::npos) {
  455. {
  456. int nPos1 = conf.find(":");
  457. ret.push_back({conf.substr(0, nPos1), conf.substr(nPos1+1)});
  458. }
  459. startPos = nPos + 1;
  460. nPos = v.find(",", startPos);
  461. conf = v.substr(startPos, nPos-startPos);
  462. }
  463. // 最后一个
  464. {
  465. int nPos1 = conf.find(":");
  466. ret.push_back({conf.substr(0, nPos1), conf.substr(nPos1+1)});
  467. }
  468. return ret;
  469. }
  470. int parseStringAsTime(const std::string& str) {
  471. std::string tStr = str;
  472. int secs = 0;
  473. auto pos = tStr.find("d");
  474. if (pos != std::string::npos) {
  475. int d = std::stoi(tStr.substr(0, pos));
  476. secs = d * 3600 * 24;
  477. tStr = tStr.substr(pos+1);
  478. }
  479. pos = tStr.find("h");
  480. if (pos != std::string::npos) {
  481. int h = std::stoi(tStr.substr(0, pos));
  482. secs += h * 3600;
  483. tStr = tStr.substr(pos+1);
  484. }
  485. pos = tStr.find("m");
  486. if (tStr.find("m") != std::string::npos) {
  487. int m = std::stoi(tStr.substr(0, pos));
  488. secs += m * 60;
  489. tStr = tStr.substr(pos+1);
  490. }
  491. if (tStr.size() > 0) {
  492. secs += std::stoi(tStr);
  493. }
  494. return secs;
  495. }
  496. void showTimingInLable(cocos2d::Label* label, std::function<int()> getCooldown, bool showHours, bool hourAlways) {
  497. if (label->isScheduled("SCH_Update_Time")) {
  498. label->unschedule("SCH_Update_Time");
  499. }
  500. auto updateLb = [=](int secsCooldown){
  501. // 设置时间
  502. int days = secsCooldown / (3600*24);
  503. int hours = (secsCooldown % (3600*24)) / 3600;
  504. int mins = (secsCooldown % 3600) / 60;
  505. int secs = secsCooldown % 60;
  506. std::string str;
  507. if (days > 0) {
  508. str = Value(days).asString() + "d " + Value(hours).asString() + "h";
  509. } else {
  510. if (showHours) {
  511. if (hours > 0 || hourAlways) {
  512. if (hours >= 10) {
  513. str = Value(hours).asString();
  514. } else {
  515. if (hourAlways) {
  516. str = "0";
  517. }
  518. str += Value(hours).asString();
  519. }
  520. str += ":";
  521. }
  522. } else {
  523. mins += hours*60;
  524. }
  525. if (mins >= 10) {
  526. str += Value(mins).asString();
  527. } else {
  528. str += "0" + Value(mins).asString();
  529. }
  530. str += ":";
  531. if (secs >= 10) {
  532. str += Value(secs).asString();
  533. } else {
  534. str += "0" + Value(secs).asString();
  535. }
  536. }
  537. label->setString(str);
  538. };
  539. updateLb(getCooldown());
  540. label->schedule([=](float){
  541. int secs = getCooldown();
  542. if (secs >= 0) {
  543. updateLb(secs);
  544. }
  545. // 小于0的时候不更新,由调用者自己决定行为
  546. }, 0.2, 10000000, 0.2, "SCH_Update_Time");
  547. }
  548. Node* readNodeWithAdapt(redream::REDReader * reader, const char* resName, bool bUseAdapt) {
  549. std::string name = resName;
  550. Node* node = nullptr;
  551. if (bUseAdapt) {
  552. name = resName + Value("_720x1540").asString();
  553. node = reader->readNodeGraphFromFile(name.c_str());
  554. }
  555. if (node == nullptr) {
  556. node = reader->readNodeGraphFromFile(resName);
  557. if (node == nullptr) {
  558. name = resName + Value("_680x1200").asString();
  559. node = reader->readNodeGraphFromFile(name.c_str());
  560. }
  561. }
  562. return node;
  563. }
  564. QCoreLayer* readLayer(const char* resName, bool bUseAdapt) {
  565. // FIXME: 不能写到qcorelayer里面去很尴尬
  566. std::string name = resName;
  567. if (bUseAdapt) {
  568. name = resName + Value("_720x1540.redream").asString();
  569. if (FileUtils::getInstance()->isFileExist(name)) {
  570. return QCoreLayer::Layer(name);
  571. }
  572. }
  573. if (FileUtils::getInstance()->isFileExist(std::string(resName)+".redream")) {
  574. return QCoreLayer::Layer(resName);
  575. }
  576. name = resName + Value("_680x1200.redream").asString();
  577. if (FileUtils::getInstance()->isFileExist(resName)) {
  578. return QCoreLayer::Layer(resName);
  579. }
  580. return nullptr;
  581. }
  582. void smartScaleHeight(Node* layer, Size designSize)
  583. {
  584. // 两边留出余量:振屏的时候不穿帮
  585. Size frameSize = Director::getInstance()->getVisibleSize() + Size(30, 0);
  586. Size contentSize = layer->getContentSize();
  587. float scaleX = layer->getScaleX();
  588. float scaleY = layer->getScaleY();
  589. contentSize.width *= scaleX;
  590. contentSize.height *= scaleY;
  591. if ((frameSize.height / frameSize.width) < (contentSize.height / contentSize.width)) {
  592. // content 的宽度需要检查
  593. float targetScale = frameSize.width / contentSize.width;
  594. layer->setScaleX(targetScale * scaleX);
  595. layer->setScaleY(targetScale * scaleY);
  596. } else if ((frameSize.height / frameSize.width) > (contentSize.height / contentSize.width)) {
  597. // content 的高度需要检查
  598. float targetScale = frameSize.height / contentSize.height;
  599. layer->setScaleX(targetScale * scaleX);
  600. layer->setScaleY(targetScale * scaleY);
  601. }
  602. }
  603. NS_RU_END