MyExtends.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. import Random from "../utils/Random";
  2. import { List } from "./General";
  3. import Time from "./Time";
  4. export enum EaseType {
  5. quadIn,
  6. quadOut,
  7. quadInOut,
  8. cubicIn,
  9. cubicOut,
  10. cubicInOut,
  11. quartIn,
  12. quartOut,
  13. quartInOut,
  14. quintIn,
  15. quintOut,
  16. quintInOut,
  17. sineIn,
  18. sineOut,
  19. sineInOut,
  20. expoIn,
  21. expoOut,
  22. expoInOut,
  23. circIn,
  24. circOut,
  25. circInOut,
  26. elasticIn,
  27. elasticOut,
  28. elasticInOut,
  29. backIn,
  30. backOut,
  31. backInOut,
  32. bounceIn,
  33. bounceOut,
  34. bounceInOut,
  35. none
  36. //smooth,
  37. //fade
  38. }
  39. //@ccclass
  40. export default class MyExtends {
  41. //取节点的世界坐标
  42. /**
  43. * 得到一个节点的世界坐标 世界坐标原点为屏幕左下角
  44. * node的原点在中心
  45. * @param {*} node
  46. */
  47. static localConvertWorldPointAR(node: cc.Node) {
  48. if (node) {
  49. return node.convertToWorldSpaceAR(cc.v2(0, 0));
  50. }
  51. return null;
  52. }
  53. /**
  54. * 得到一个节点的世界坐标 世界坐标原点为屏幕左下角
  55. * node的原点在左下边
  56. * @param {*} node
  57. */
  58. static localConvertWorldPoint(node: cc.Node) {
  59. if (node) {
  60. return node.convertToWorldSpace(cc.v2(0, 0));
  61. }
  62. return null;
  63. }
  64. //3D世界坐标转化成某个节点下的坐标
  65. /**
  66. * 把一个世界坐标的点,转换到某个节点下的坐标
  67. * 原点在node中心
  68. * @param {*} node
  69. * @param {*} worldPoint
  70. */
  71. static worldConvertLocalPointAR3D(node: cc.Node, worldPoint: cc.Vec3) {
  72. if (node) {
  73. return node.convertToNodeSpaceAR(worldPoint);
  74. }
  75. return null;
  76. }
  77. //2D世界坐标转化成某个节点下的坐标
  78. /**
  79. * 把一个世界坐标的点,转换到某个节点下的坐标
  80. * 原点在node中心
  81. * @param {*} node
  82. * @param {*} worldPoint
  83. */
  84. static worldConvertLocalPointAR2D(node: cc.Node, worldPoint: cc.Vec2) {
  85. if (node) {
  86. return node.convertToNodeSpaceAR(worldPoint);
  87. }
  88. return null;
  89. }
  90. /**
  91. * 把一个世界坐标的点,转换到某个节点下的坐标
  92. * 原点在node左下角
  93. * @param {*} node
  94. * @param {*} worldPoint
  95. */
  96. static worldConvertLocalPoint(node: cc.Node, worldPoint: cc.Vec2) {
  97. if (node) {
  98. return node.convertToNodeSpace(worldPoint);
  99. }
  100. return null;
  101. }
  102. //节点的本地坐标转到另一个节点的本地坐标下
  103. /**
  104. * * (2D)把一个节点的本地坐标转到另一个节点的本地坐标下 原点在node左下角
  105. * @param {*} node
  106. * @param {*} targetNode
  107. */
  108. static convetOtherNodeSpace(node: cc.Node, targetNode: cc.Node) {
  109. if (!node || !targetNode) {
  110. return null;
  111. }
  112. //先转成世界坐标
  113. let worldPoint = MyExtends.localConvertWorldPoint(node);
  114. return MyExtends.worldConvertLocalPoint(targetNode, worldPoint);
  115. }
  116. /**
  117. * * (2D)把一个节点的本地坐标转到另一个节点的本地坐标下 原点在node中心
  118. * @param {*} node
  119. * @param {*} targetNode
  120. */
  121. static convetOtherNodeSpaceAR(node: cc.Node, targetNode: cc.Node) {
  122. if (!node || !targetNode) {
  123. return null;
  124. }
  125. //先转成世界坐标
  126. let worldPoint = MyExtends.localConvertWorldPointAR(node);
  127. return MyExtends.worldConvertLocalPointAR2D(targetNode, worldPoint);
  128. }
  129. //物体是否被其他物体覆盖,不仅仅为坐标不被覆盖,整个物体大小范围都不被覆盖
  130. /**
  131. * 目标是否被覆盖物完全覆盖
  132. * @param target 目标物体
  133. * @param cover 覆盖物
  134. */
  135. static IsAllCovered(target: cc.Node, cover: cc.Node) {
  136. //if (target.x <= (cover.x + cover.width / 2) && target.x >= (cover.x - cover.width / 2)
  137. //&& target.y <= (cover.y + cover.height / 2) && target.y >= (cover.y - cover.height / 2))
  138. }
  139. /**
  140. * 目标是否完全暴漏在覆盖物之外 默认最大尺寸为长宽中最大值
  141. * @param target 目标物体
  142. * @param cover 覆盖物
  143. * @param offset 可选 误差偏移 范围缩小为负数 范围扩大为正数
  144. */
  145. static IsFullExposed(target: cc.Node, cover: cc.Node, offset?: number): boolean {
  146. let tempOffset: number = 0;
  147. if (offset)
  148. tempOffset = offset;
  149. if (target.x >= (cover.x + cover.width / 2 + target.width / 2 + tempOffset) || target.x <= (cover.x - cover.width / 2 - target.width / 2 - tempOffset)
  150. || target.y >= (cover.y + cover.height / 2 + target.height / 2 + tempOffset) || target.y <= (cover.y - cover.height / 2 - target.height / 2 - tempOffset)) {
  151. return true;
  152. }
  153. return false;
  154. }
  155. /**
  156. * 目标点是否超出节点范围
  157. * @param pos 目标坐标
  158. * @param rect 节点范围
  159. */
  160. static PointIsOverRect(pos: cc.Vec2, rect: cc.Node): boolean {
  161. if (pos.x >= (rect.x + rect.width / 2) || pos.x <= (rect.x - rect.width / 2)
  162. || pos.y >= (rect.y + rect.height / 2) || pos.y <= (rect.y - rect.height / 2)) {
  163. return true;
  164. }
  165. return false;
  166. }
  167. /**
  168. * 目标是否完全暴漏在若干覆盖物之外
  169. * @param target 目标物体
  170. * @param covers 覆盖物集合
  171. * @param offset 可选 误差偏移 范围缩小为负数 范围扩大为正数
  172. */
  173. static IsFullExposedByCovers(target: cc.Node, covers: Array<cc.Node>, offset?: number): boolean {
  174. let result = true;
  175. for (let i = 0; i < covers.length; i++) {
  176. if (!this.IsFullExposed(target, covers[i], offset)) {
  177. result = false;
  178. break;
  179. }
  180. }
  181. return result;
  182. }
  183. /**角度转弧度*/
  184. static Angle2Arc(angle: number) {
  185. return angle / 180 * Math.PI;
  186. }
  187. /**
  188. * 角度转换至0- +-360 不区分符号
  189. */
  190. static CheckAngle(angle: number) {
  191. let result = angle;
  192. if (angle >= 360)
  193. result %= 360;
  194. else if (angle <= -360)
  195. result %= -360;
  196. return result;
  197. }
  198. /**
  199. * 角度转换至0-360 正数
  200. */
  201. static CheckNatureAngle(angle: number) {
  202. let result = angle;
  203. if (angle >= 360)
  204. result %= 360;
  205. else if (angle <= -360)
  206. result %= -360;
  207. return result >= 0 ? result : 360 + result;
  208. }
  209. /**
  210. * 从指定数组中拿出指定数量不重复的元素 并返回这些元素组成的数组
  211. * @param num 拿取的数量
  212. * @param ary 目标数组
  213. */
  214. static GetAryByAry(num: number, ary: Array<any>): Array<any> {
  215. let result = new Array<any>();
  216. let indexList = new List<number>();
  217. //let indexMap = new Map();
  218. for (let i = 0; i < ary.length; i++) {
  219. indexList.Add(i);
  220. //indexMap.set(i, i);
  221. }
  222. for (let i = 0; i < num; i++) {
  223. let tempIndex = Random.Range(0, indexList.Count);
  224. result.push(ary[indexList.Item(tempIndex)]);
  225. indexList.RemoveAt(tempIndex);
  226. }
  227. //if (isSort) result = result.sort((a, b) => { return a - b });
  228. //console.log("----------.Result:", result);
  229. return result;
  230. }
  231. /**
  232. * 从指定数组中拿出与当前指定索引不同的随机索引
  233. * @param ary 数组
  234. * @param curIndex 当前索引
  235. */
  236. static GetIndexByAry(ary: Array<any>, curIndex: number): number {
  237. let pool: number[] = [];
  238. for (let i = 0; i < ary.length; i++) {
  239. if (i != curIndex) {
  240. pool.push(i);
  241. }
  242. }
  243. return pool[Random.Range(0, pool.length)];
  244. }
  245. /**
  246. * 等待后执行
  247. */
  248. static async WaitTimeForCallback(time: number, callback: Function) {
  249. await Time.WaitForSeconds(time);
  250. callback();
  251. }
  252. /**
  253. * 物体震动
  254. * @param 要震动的物体节点
  255. * @param duration 震动时长
  256. */
  257. static ScreenShock(node: cc.Node, duration: number) {
  258. let pos: cc.Vec2;
  259. pos = cc.v2(node.x, node.y);
  260. node.runAction(
  261. cc.repeatForever(
  262. cc.sequence(
  263. cc.moveTo(0.02, cc.v2(pos.x + 5, pos.y + 7)),
  264. cc.moveTo(0.02, cc.v2(pos.x + -6, pos.y + 7)),
  265. cc.moveTo(0.02, cc.v2(pos.x + -13, pos.y + 3)),
  266. cc.moveTo(0.02, cc.v2(pos.x + 3, pos.y + -6)),
  267. cc.moveTo(0.02, cc.v2(pos.x + -5, pos.y + 5)),
  268. cc.moveTo(0.02, cc.v2(pos.x + 2, pos.y + -8)),
  269. cc.moveTo(0.02, cc.v2(pos.x + -8, pos.y + -10)),
  270. cc.moveTo(0.02, cc.v2(pos.x + 3, pos.y + 10)),
  271. cc.moveTo(0.02, cc.v2(pos.x + 0, pos.y + 0))
  272. )
  273. )
  274. );
  275. setTimeout(() => {
  276. node.stopAllActions();
  277. node.setPosition(pos);
  278. }, duration * 1000);
  279. }
  280. /**
  281. * 事件队列 无效 请使用 cc.sequence
  282. */
  283. static Sequence(callbacks: Function | Function[]) {
  284. }
  285. /**
  286. * 秒转 h:m:s格式
  287. * @param times 时间 秒
  288. * @param type 类型 1 秒 2 分秒 3 时分秒
  289. */
  290. static TimeToFormat(times: number, type: number = 2) {
  291. let hour;
  292. let minute;
  293. let second;
  294. if (times > 0) {
  295. hour = Math.floor(times / 3600);
  296. if (hour < 10) {
  297. hour = "0" + hour;
  298. }
  299. minute = Math.floor((times - 3600 * hour) / 60);
  300. if (minute < 10) {
  301. minute = "0" + minute;
  302. }
  303. second = Math.floor((times - 3600 * hour - 60 * minute) % 60);
  304. if (second < 10) {
  305. second = "0" + second;
  306. }
  307. } else {
  308. hour = "00";
  309. minute = "00";
  310. second = "00";
  311. }
  312. if (type == 3)
  313. return hour + ":" + minute + ":" + second;
  314. else
  315. return minute + ":" + second;
  316. //return { h: hour, m: minute, s: second };
  317. }
  318. /**
  319. * 数字转001 020 等补0格式
  320. * @param num 数字
  321. * @param length 保留的长度
  322. */
  323. static ToNumString(num: number, length: number = 2) {
  324. switch (length) {
  325. case 1:
  326. return num.toString();
  327. case 2:
  328. if (num < 10)
  329. return "0" + num;
  330. return num.toString();
  331. case 3:
  332. if (num < 10)
  333. return "00" + num;
  334. else if (num < 100)
  335. return "0" + num;
  336. return num.toString();
  337. }
  338. }
  339. //easeInQuad
  340. /**
  341. * @param t 动画执行到当前帧所进过的时间
  342. * @param b 起始值
  343. * @param c 需要变化的量 变化值 delta
  344. * @param d 动画的总时间
  345. */
  346. static EaseInQuad(t, b, c, d) {
  347. var x = t / d; //x值
  348. var y = x * x; //y值
  349. return b + c * y;//套入最初的公式
  350. }
  351. /**
  352. * 返回带指定类型缓动的动作
  353. * @param type 缓动类型
  354. * @param action 动作
  355. */
  356. static ActionByEase(type: EaseType, action: cc.ActionInterval) {
  357. switch (type) {
  358. case EaseType.quadIn:
  359. return action.easing(cc.easeIn(3));
  360. case EaseType.quadOut:
  361. return action.easing(cc.easeOut(3));
  362. case EaseType.quadInOut:
  363. return action.easing(cc.easeInOut(3));
  364. case EaseType.cubicIn:
  365. return action.easing(cc.easeCubicActionIn());
  366. case EaseType.cubicOut:
  367. return action.easing(cc.easeCubicActionOut());
  368. case EaseType.cubicInOut:
  369. return action.easing(cc.easeCubicActionInOut());
  370. case EaseType.quartIn:
  371. return action.easing(cc.easeQuarticActionIn());
  372. case EaseType.quartOut:
  373. return action.easing(cc.easeQuarticActionOut());
  374. case EaseType.quartInOut:
  375. return action.easing(cc.easeQuarticActionInOut());
  376. case EaseType.quintIn:
  377. return action.easing(cc.easeQuinticActionIn());
  378. case EaseType.quintOut:
  379. return action.easing(cc.easeQuinticActionOut());
  380. case EaseType.quintInOut:
  381. return action.easing(cc.easeQuinticActionInOut());
  382. case EaseType.sineIn:
  383. return action.easing(cc.easeSineIn());
  384. case EaseType.sineOut:
  385. return action.easing(cc.easeSineOut());
  386. case EaseType.sineInOut:
  387. return action.easing(cc.easeSineInOut());
  388. case EaseType.expoIn:
  389. return action.easing(cc.easeExponentialIn());
  390. case EaseType.expoOut:
  391. return action.easing(cc.easeExponentialOut());
  392. case EaseType.expoInOut:
  393. return action.easing(cc.easeExponentialInOut());
  394. case EaseType.circIn:
  395. return action.easing(cc.easeCircleActionIn());
  396. case EaseType.circOut:
  397. return action.easing(cc.easeCircleActionOut());
  398. case EaseType.circInOut:
  399. return action.easing(cc.easeCircleActionInOut());
  400. case EaseType.elasticIn:
  401. return action.easing(cc.easeElasticIn(1));
  402. case EaseType.elasticOut:
  403. return action.easing(cc.easeElasticOut(1));
  404. case EaseType.elasticInOut:
  405. return action.easing(cc.easeElasticInOut(1));
  406. case EaseType.backIn:
  407. return action.easing(cc.easeBackIn());
  408. case EaseType.backOut:
  409. return action.easing(cc.easeBackOut());
  410. case EaseType.backInOut:
  411. return action.easing(cc.easeBackInOut());
  412. case EaseType.bounceIn:
  413. return action.easing(cc.easeBounceIn());
  414. case EaseType.bounceOut:
  415. return action.easing(cc.easeBounceOut());
  416. case EaseType.bounceInOut:
  417. return action.easing(cc.easeBounceInOut());
  418. case EaseType.none:
  419. return action;
  420. }
  421. }
  422. }
  423. export class PlayerPrefs {
  424. public static GetString(key: string, defaultValue: string = null): string {
  425. let value = cc.sys.localStorage.getItem(key);
  426. if (value !== value) {
  427. value = defaultValue;
  428. }
  429. return value;
  430. }
  431. public static GetInt(key: string, defaultValue: number = 0): number {
  432. let value = parseInt(cc.sys.localStorage.getItem(key));
  433. if (value !== value) {
  434. value = defaultValue;
  435. }
  436. return value;
  437. }
  438. public static GetFloat(key: string, defaultValue: number = 0): number {
  439. let value = parseFloat(cc.sys.localStorage.getItem(key));
  440. if (value !== value) {
  441. value = defaultValue;
  442. }
  443. return value;
  444. }
  445. public static GetObject(key: string, defaultValue: any): any {
  446. let value = cc.sys.localStorage.getItem(key);
  447. if (value) {
  448. value = JSON.parse(value);
  449. } else {
  450. value = defaultValue;
  451. }
  452. return value;
  453. }
  454. public static SetString(key: string, value: string) {
  455. if (key != null) {
  456. cc.sys.localStorage.setItem(key, value);
  457. } else {
  458. console.log("please set sure key");
  459. }
  460. }
  461. public static SetInt(key: string, value: number) {
  462. if (key != null) {
  463. cc.sys.localStorage.setItem(key, value);
  464. } else {
  465. console.log("please set sure key");
  466. }
  467. }
  468. public static SetFloat(key: string, value: number) {
  469. if (key != null) {
  470. cc.sys.localStorage.setItem(key, value);
  471. } else {
  472. console.log("please set sure key");
  473. }
  474. }
  475. public static SetObject(key: string, value: any) {
  476. if (key != null) {
  477. cc.sys.localStorage.setItem(key, JSON.stringify(value));
  478. } else {
  479. console.log("please set sure key");
  480. }
  481. }
  482. public static GetItem(key: string, defaultValue: any) {
  483. let value = cc.sys.localStorage.getItem(key);
  484. if (value == null || value == undefined) {
  485. value = defaultValue;
  486. }
  487. return value;
  488. }
  489. public static SetItem(key: string, value: any) {
  490. if (key != null) {
  491. //如果是对象 需自行JSON.stringify()转换再存入
  492. cc.sys.localStorage.setItem(key, value);
  493. } else {
  494. console.log("please set sure key");
  495. }
  496. }
  497. }