import Random from "../utils/Random"; import { List } from "./General"; import Time from "./Time"; export enum EaseType { quadIn, quadOut, quadInOut, cubicIn, cubicOut, cubicInOut, quartIn, quartOut, quartInOut, quintIn, quintOut, quintInOut, sineIn, sineOut, sineInOut, expoIn, expoOut, expoInOut, circIn, circOut, circInOut, elasticIn, elasticOut, elasticInOut, backIn, backOut, backInOut, bounceIn, bounceOut, bounceInOut, none //smooth, //fade } //@ccclass export default class MyExtends { //取节点的世界坐标 /** * 得到一个节点的世界坐标 世界坐标原点为屏幕左下角 * node的原点在中心 * @param {*} node */ static localConvertWorldPointAR(node: cc.Node) { if (node) { return node.convertToWorldSpaceAR(cc.v2(0, 0)); } return null; } /** * 得到一个节点的世界坐标 世界坐标原点为屏幕左下角 * node的原点在左下边 * @param {*} node */ static localConvertWorldPoint(node: cc.Node) { if (node) { return node.convertToWorldSpace(cc.v2(0, 0)); } return null; } //3D世界坐标转化成某个节点下的坐标 /** * 把一个世界坐标的点,转换到某个节点下的坐标 * 原点在node中心 * @param {*} node * @param {*} worldPoint */ static worldConvertLocalPointAR3D(node: cc.Node, worldPoint: cc.Vec3) { if (node) { return node.convertToNodeSpaceAR(worldPoint); } return null; } //2D世界坐标转化成某个节点下的坐标 /** * 把一个世界坐标的点,转换到某个节点下的坐标 * 原点在node中心 * @param {*} node * @param {*} worldPoint */ static worldConvertLocalPointAR2D(node: cc.Node, worldPoint: cc.Vec2) { if (node) { return node.convertToNodeSpaceAR(worldPoint); } return null; } /** * 把一个世界坐标的点,转换到某个节点下的坐标 * 原点在node左下角 * @param {*} node * @param {*} worldPoint */ static worldConvertLocalPoint(node: cc.Node, worldPoint: cc.Vec2) { if (node) { return node.convertToNodeSpace(worldPoint); } return null; } //节点的本地坐标转到另一个节点的本地坐标下 /** * * (2D)把一个节点的本地坐标转到另一个节点的本地坐标下 原点在node左下角 * @param {*} node * @param {*} targetNode */ static convetOtherNodeSpace(node: cc.Node, targetNode: cc.Node) { if (!node || !targetNode) { return null; } //先转成世界坐标 let worldPoint = MyExtends.localConvertWorldPoint(node); return MyExtends.worldConvertLocalPoint(targetNode, worldPoint); } /** * * (2D)把一个节点的本地坐标转到另一个节点的本地坐标下 原点在node中心 * @param {*} node * @param {*} targetNode */ static convetOtherNodeSpaceAR(node: cc.Node, targetNode: cc.Node) { if (!node || !targetNode) { return null; } //先转成世界坐标 let worldPoint = MyExtends.localConvertWorldPointAR(node); return MyExtends.worldConvertLocalPointAR2D(targetNode, worldPoint); } //物体是否被其他物体覆盖,不仅仅为坐标不被覆盖,整个物体大小范围都不被覆盖 /** * 目标是否被覆盖物完全覆盖 * @param target 目标物体 * @param cover 覆盖物 */ static IsAllCovered(target: cc.Node, cover: cc.Node) { //if (target.x <= (cover.x + cover.width / 2) && target.x >= (cover.x - cover.width / 2) //&& target.y <= (cover.y + cover.height / 2) && target.y >= (cover.y - cover.height / 2)) } /** * 目标是否完全暴漏在覆盖物之外 默认最大尺寸为长宽中最大值 * @param target 目标物体 * @param cover 覆盖物 * @param offset 可选 误差偏移 范围缩小为负数 范围扩大为正数 */ static IsFullExposed(target: cc.Node, cover: cc.Node, offset?: number): boolean { let tempOffset: number = 0; if (offset) tempOffset = offset; if (target.x >= (cover.x + cover.width / 2 + target.width / 2 + tempOffset) || target.x <= (cover.x - cover.width / 2 - target.width / 2 - tempOffset) || target.y >= (cover.y + cover.height / 2 + target.height / 2 + tempOffset) || target.y <= (cover.y - cover.height / 2 - target.height / 2 - tempOffset)) { return true; } return false; } /** * 目标点是否超出节点范围 * @param pos 目标坐标 * @param rect 节点范围 */ static PointIsOverRect(pos: cc.Vec2, rect: cc.Node): boolean { if (pos.x >= (rect.x + rect.width / 2) || pos.x <= (rect.x - rect.width / 2) || pos.y >= (rect.y + rect.height / 2) || pos.y <= (rect.y - rect.height / 2)) { return true; } return false; } /** * 目标是否完全暴漏在若干覆盖物之外 * @param target 目标物体 * @param covers 覆盖物集合 * @param offset 可选 误差偏移 范围缩小为负数 范围扩大为正数 */ static IsFullExposedByCovers(target: cc.Node, covers: Array, offset?: number): boolean { let result = true; for (let i = 0; i < covers.length; i++) { if (!this.IsFullExposed(target, covers[i], offset)) { result = false; break; } } return result; } /**角度转弧度*/ static Angle2Arc(angle: number) { return angle / 180 * Math.PI; } /** * 角度转换至0- +-360 不区分符号 */ static CheckAngle(angle: number) { let result = angle; if (angle >= 360) result %= 360; else if (angle <= -360) result %= -360; return result; } /** * 角度转换至0-360 正数 */ static CheckNatureAngle(angle: number) { let result = angle; if (angle >= 360) result %= 360; else if (angle <= -360) result %= -360; return result >= 0 ? result : 360 + result; } /** * 从指定数组中拿出指定数量不重复的元素 并返回这些元素组成的数组 * @param num 拿取的数量 * @param ary 目标数组 */ static GetAryByAry(num: number, ary: Array): Array { let result = new Array(); let indexList = new List(); //let indexMap = new Map(); for (let i = 0; i < ary.length; i++) { indexList.Add(i); //indexMap.set(i, i); } for (let i = 0; i < num; i++) { let tempIndex = Random.Range(0, indexList.Count); result.push(ary[indexList.Item(tempIndex)]); indexList.RemoveAt(tempIndex); } //if (isSort) result = result.sort((a, b) => { return a - b }); //console.log("----------.Result:", result); return result; } /** * 从指定数组中拿出与当前指定索引不同的随机索引 * @param ary 数组 * @param curIndex 当前索引 */ static GetIndexByAry(ary: Array, curIndex: number): number { let pool: number[] = []; for (let i = 0; i < ary.length; i++) { if (i != curIndex) { pool.push(i); } } return pool[Random.Range(0, pool.length)]; } /** * 等待后执行 */ static async WaitTimeForCallback(time: number, callback: Function) { await Time.WaitForSeconds(time); callback(); } /** * 物体震动 * @param 要震动的物体节点 * @param duration 震动时长 */ static ScreenShock(node: cc.Node, duration: number) { let pos: cc.Vec2; pos = cc.v2(node.x, node.y); node.runAction( cc.repeatForever( cc.sequence( cc.moveTo(0.02, cc.v2(pos.x + 5, pos.y + 7)), cc.moveTo(0.02, cc.v2(pos.x + -6, pos.y + 7)), cc.moveTo(0.02, cc.v2(pos.x + -13, pos.y + 3)), cc.moveTo(0.02, cc.v2(pos.x + 3, pos.y + -6)), cc.moveTo(0.02, cc.v2(pos.x + -5, pos.y + 5)), cc.moveTo(0.02, cc.v2(pos.x + 2, pos.y + -8)), cc.moveTo(0.02, cc.v2(pos.x + -8, pos.y + -10)), cc.moveTo(0.02, cc.v2(pos.x + 3, pos.y + 10)), cc.moveTo(0.02, cc.v2(pos.x + 0, pos.y + 0)) ) ) ); setTimeout(() => { node.stopAllActions(); node.setPosition(pos); }, duration * 1000); } /** * 事件队列 无效 请使用 cc.sequence */ static Sequence(callbacks: Function | Function[]) { } /** * 秒转 h:m:s格式 * @param times 时间 秒 * @param type 类型 1 秒 2 分秒 3 时分秒 */ static TimeToFormat(times: number, type: number = 2) { let hour; let minute; let second; if (times > 0) { hour = Math.floor(times / 3600); if (hour < 10) { hour = "0" + hour; } minute = Math.floor((times - 3600 * hour) / 60); if (minute < 10) { minute = "0" + minute; } second = Math.floor((times - 3600 * hour - 60 * minute) % 60); if (second < 10) { second = "0" + second; } } else { hour = "00"; minute = "00"; second = "00"; } if (type == 3) return hour + ":" + minute + ":" + second; else return minute + ":" + second; //return { h: hour, m: minute, s: second }; } /** * 数字转001 020 等补0格式 * @param num 数字 * @param length 保留的长度 */ static ToNumString(num: number, length: number = 2) { switch (length) { case 1: return num.toString(); case 2: if (num < 10) return "0" + num; return num.toString(); case 3: if (num < 10) return "00" + num; else if (num < 100) return "0" + num; return num.toString(); } } //easeInQuad /** * @param t 动画执行到当前帧所进过的时间 * @param b 起始值 * @param c 需要变化的量 变化值 delta * @param d 动画的总时间 */ static EaseInQuad(t, b, c, d) { var x = t / d; //x值 var y = x * x; //y值 return b + c * y;//套入最初的公式 } /** * 返回带指定类型缓动的动作 * @param type 缓动类型 * @param action 动作 */ static ActionByEase(type: EaseType, action: cc.ActionInterval) { switch (type) { case EaseType.quadIn: return action.easing(cc.easeIn(3)); case EaseType.quadOut: return action.easing(cc.easeOut(3)); case EaseType.quadInOut: return action.easing(cc.easeInOut(3)); case EaseType.cubicIn: return action.easing(cc.easeCubicActionIn()); case EaseType.cubicOut: return action.easing(cc.easeCubicActionOut()); case EaseType.cubicInOut: return action.easing(cc.easeCubicActionInOut()); case EaseType.quartIn: return action.easing(cc.easeQuarticActionIn()); case EaseType.quartOut: return action.easing(cc.easeQuarticActionOut()); case EaseType.quartInOut: return action.easing(cc.easeQuarticActionInOut()); case EaseType.quintIn: return action.easing(cc.easeQuinticActionIn()); case EaseType.quintOut: return action.easing(cc.easeQuinticActionOut()); case EaseType.quintInOut: return action.easing(cc.easeQuinticActionInOut()); case EaseType.sineIn: return action.easing(cc.easeSineIn()); case EaseType.sineOut: return action.easing(cc.easeSineOut()); case EaseType.sineInOut: return action.easing(cc.easeSineInOut()); case EaseType.expoIn: return action.easing(cc.easeExponentialIn()); case EaseType.expoOut: return action.easing(cc.easeExponentialOut()); case EaseType.expoInOut: return action.easing(cc.easeExponentialInOut()); case EaseType.circIn: return action.easing(cc.easeCircleActionIn()); case EaseType.circOut: return action.easing(cc.easeCircleActionOut()); case EaseType.circInOut: return action.easing(cc.easeCircleActionInOut()); case EaseType.elasticIn: return action.easing(cc.easeElasticIn(1)); case EaseType.elasticOut: return action.easing(cc.easeElasticOut(1)); case EaseType.elasticInOut: return action.easing(cc.easeElasticInOut(1)); case EaseType.backIn: return action.easing(cc.easeBackIn()); case EaseType.backOut: return action.easing(cc.easeBackOut()); case EaseType.backInOut: return action.easing(cc.easeBackInOut()); case EaseType.bounceIn: return action.easing(cc.easeBounceIn()); case EaseType.bounceOut: return action.easing(cc.easeBounceOut()); case EaseType.bounceInOut: return action.easing(cc.easeBounceInOut()); case EaseType.none: return action; } } } export class PlayerPrefs { public static GetString(key: string, defaultValue: string = null): string { let value = cc.sys.localStorage.getItem(key); if (value !== value) { value = defaultValue; } return value; } public static GetInt(key: string, defaultValue: number = 0): number { let value = parseInt(cc.sys.localStorage.getItem(key)); if (value !== value) { value = defaultValue; } return value; } public static GetFloat(key: string, defaultValue: number = 0): number { let value = parseFloat(cc.sys.localStorage.getItem(key)); if (value !== value) { value = defaultValue; } return value; } public static GetObject(key: string, defaultValue: any): any { let value = cc.sys.localStorage.getItem(key); if (value) { value = JSON.parse(value); } else { value = defaultValue; } return value; } public static SetString(key: string, value: string) { if (key != null) { cc.sys.localStorage.setItem(key, value); } else { console.log("please set sure key"); } } public static SetInt(key: string, value: number) { if (key != null) { cc.sys.localStorage.setItem(key, value); } else { console.log("please set sure key"); } } public static SetFloat(key: string, value: number) { if (key != null) { cc.sys.localStorage.setItem(key, value); } else { console.log("please set sure key"); } } public static SetObject(key: string, value: any) { if (key != null) { cc.sys.localStorage.setItem(key, JSON.stringify(value)); } else { console.log("please set sure key"); } } public static GetItem(key: string, defaultValue: any) { let value = cc.sys.localStorage.getItem(key); if (value == null || value == undefined) { value = defaultValue; } return value; } public static SetItem(key: string, value: any) { if (key != null) { //如果是对象 需自行JSON.stringify()转换再存入 cc.sys.localStorage.setItem(key, value); } else { console.log("please set sure key"); } } }