"use strict"; cc._RF.push(module, '693baLcvz1DyrnZJgdT0PMM', 'nx.math'); // Scripts/nx/kernel/nx.math.js "use strict"; /******************************************************************************* * * Nx数据结构相关方法 * * * * 2021.12.10 ******************************************************************************/ require("base64"); require("rseed"); var md = require("md5"); // 默认小数位数 var DefPN = 2; var NxMath = cc.Class({ name: "NxMath", // 创建 ctor: function ctor() { this.uuTracker = 1000; }, // ------------------------------------------------------------ // 方法集:基本的数据类型判断 // ------------------------------------------------------------ // 数字 numGood: function numGood(_n) { return _n === +_n; }, // 正数 numPositive: function numPositive(_n, _inZero /* true */) { if (!this.numGood(_n)) { return false; } return _inZero !== false ? _n >= 0 : _n > 0; }, // 为X的数 numEqual: function numEqual(_n, _t) { return this.numGood(_n) && _n == _t; }, // 大于X的数 numGreater: function numGreater(_n, _t) { return this.numGood(_n) && _n > _t; }, // 小于X的数 numLess: function numLess(_n, _t) { return this.numGood(_n) && _n < _t; }, // 范围内的数 numInRange: function numInRange(_n, _range /* [x,y] */) { if (!this.arrGood(_range) || _range.length != 2) { return false; } return this.numGood(_n) && _n >= _range[0] && _n <= _range[1]; }, // 数字修正 numFix: function numFix(_num, _def) { if (_def === void 0) { _def = 0; } var ret = _num; if (!nx.dt.numGood(ret)) { ret = _def; } return ret; }, // 浮点精确度 toFixedDecimal: function toFixedDecimal(_n) { if (!this.numGood(_n)) { return 0; } // 多保留一位来保证浮点数精度 var fixedNumber = (_n * 100).toFixed(1); return Number((parseInt(fixedNumber) / 100).toFixed(2)); }, // 布尔 isBool: function isBool(_b) { return _b === !!_b; }, // 字节数格式化 formatBytes: function formatBytes(bytes, decimals) { if (decimals === void 0) { decimals = 2; } if (bytes === 0) return '0 Bytes'; var k = 1024; var dm = decimals & lt; 0 ? 0 : decimals; var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; }, // ------------------------------------------------------------ // 方法集:方法的方法 // ------------------------------------------------------------ // 有效方法 fnGood: function fnGood(_f) { return _f != null && typeof _f === "function"; }, // 空方法 fnEmpty: function fnEmpty() {}, // 空方法报错 fnEmptyError: function fnEmptyError(_fn) { if (this.fnGood(_fn)) { nx.error("方法已经存在:", _fn.name); } }, // 安全回调 fnInvoke: function fnInvoke(_fn) { if (!this.fnGood(_fn)) { return; } if (CC_DEBUG) { _fn.apply(null, Array.prototype.slice.call(arguments, 1)); } else { try { _fn.apply(null, Array.prototype.slice.call(arguments, 1)); } catch (e) { nx.error("[异常]:" + (e ? e.message + "\n" + e.stack : "未知错误!")); if (e && cc.sys.isNative && window && window.__errorHandler) { window.__errorHandler(e.message, "", "", e.stack); } } } }, // ------------------------------------------------------------ // 方法集:字符串的方法 // ------------------------------------------------------------ // 字符串 strGood: function strGood(_s) { return _s === _s + ""; }, // 非空字符串 strNEmpty: function strNEmpty(_s) { return this.strGood(_s) && _s != ""; }, // 空字符串 strEmpty: function strEmpty(_s) { return !this.strNEmpty(_s); }, // 字符串去空格 strTrim: function strTrim(_s) { if (this.strNEmpty(_s)) { return _s.replace(/^(\s|\u00A0)+/, "").replace(/(\s|\u00A0)+$/, ""); } return ""; }, // 获取字节长度 strBytes: function strBytes(_s) { if (!this.strNEmpty(_s)) { return 0; } var len = 0; for (var i = 0; i < _s.length; i++) { var a = _s.charAt(i); if (a.match(/[^\x00-\xff]/ig) != null) { len += 2; } else { len += 1; } } return len; }, // 字符串省略截取 strCut: function strCut(str, len) { if (!str || !len) { return ""; } var build = ""; for (var i = 0; i < str.length && len > 0; i++) { build += str.substr(i, 1); len -= str.charCodeAt(i) > 127 ? 2 : 1; } if (build.length < str.length) build += ".."; return build; }, // 字符串省略截取(逆向) strCutR: function strCutR(str, len) { if (!str || !len) { return ""; } var build = ""; for (var i = str.length - 1; i >= 0 && len > 0; i--) { build = str.substr(i, 1) + build; len -= str.charCodeAt(i) > 127 ? 2 : 1; } if (build.length < str.length) { build = "****" + build; } return build; }, /** * key#value属性串转数组 * @param {*} _sp */ pairSplit: function pairSplit(_sp) { var _ref; var a = _sp.split('#'); if (a.length != 2) { nx.error("pairSplit失败,格式无效!", _sp); return null; } var k = a[0]; var v = a[1]; // 如果值是数字,那么转为数字 if (Number(v) == v) { v = Number(v); } return _ref = {}, _ref[k] = v, _ref; }, /** * 特定key#value属性串转数组 * 用于统一拆分Array[String]数据 * @param {*} _arr */ arrPairSplit: function arrPairSplit(_arr) { var _this = this; var ret = []; if (this.arrEmpty(_arr)) { return ret; } _arr.forEach(function (_sp) { var d = _this.pairSplit(_sp); if (d) { ret.push(d); } }); return ret; }, /** * 补零 * @param num: 被操作数 * @param n: 固定的总位数 */ prefixZero: function prefixZero(num, n) { return (Array(n).join(0) + num).slice(-n); }, /** * 字符串替换 * replaceAll */ replace: function replace(_str, _old, _new) { return _str.replace(new RegExp(_old, "gm"), _new); }, // ------------------------------------------------------------ // 方法集:数组的方法 // ------------------------------------------------------------ // 数组 arrGood: function arrGood(_a) { return Object.prototype.toString.call(_a) === "[object Array]"; }, // 非空数组 arrNEmpty: function arrNEmpty(_a) { return this.arrGood(_a) && _a.length > 0; }, // 空数组 arrEmpty: function arrEmpty(_a) { return !this.arrNEmpty(_a); }, // 是不是数组成员 arrMember: function arrMember(_a, _m, _fn) { if (!this.arrNEmpty(_a)) { return false; } _fn = _fn || function (_v) { return _v == _m; }; for (var i = 0; i < _a.length; ++i) { if (_fn(_a[i])) { return true; } } return false; }, // 合并数据[带关键字且不能重复] arrConcat: function arrConcat(_a1, _a2) { if (!this.arrGood(_a1) || !this.arrGood(_a2)) { nx.error("合并失败,参数不能为空!"); return null; } // 合并Table绑定列表 if (CC_DEBUG) { var _exist = function _exist(_key) { for (var k in _a1) { var m = _a1[k]; if (m[0] == _key) { return true; } } return false; }; for (var i in _a2) { var binder = _a2[i]; if (_exist(binder[0])) { nx.error("合并失败: %s,有重复关键字项!", binder[0]); return null; } } } return _a1.concat(_a2); }, // 从数组中删除 arrDelete: function arrDelete(_a, _fn, _once) { if (!this.arrNEmpty(_a) || !this.fnGood(_fn)) { return _a; } var i = _a.length; while (i--) { if (_fn(_a[i])) { _a.splice(i, 1); if (_once != false) { break; } } } return _a; }, // 对象转数组对 arrFromMap: function arrFromMap(_map) { if (!this.objGood(_map)) { nx.warn("对象为空,转换失败!"); return []; } var pairs = []; for (var i in _map) { pairs.push([i, _map[i]]); } return pairs; }, // 数组比较(成员相同) arrCompare: function arrCompare(_a, _b) { if (!this.arrGood(_a) || !this.arrGood(_b) || _a.length != _b.length) { return false; } for (var i in _a) { if (!this.arrMember(_b, _a[i])) { return false; } } return true; }, // ------------------------------------------------------------ // 方法集:对象的方法 // ------------------------------------------------------------ // 创建一个UUID(运行时唯一) newUUID: function newUUID(_key) { if (!this.strNEmpty(_key)) { _key = "OBJ"; } return _key + ++this.uuTracker; }, // 创建永不重复的Tag newTag: function newTag(_key) { var tag = this.md5(cc.sys.now().toString()); if (this.strEmpty(_key)) { return tag; } return _key + "." + tag; }, // 空对象 objGood: function objGood(_o) { return _o != null && typeof _o === "object" && Array.isArray(_o) === false; }, // 非空对象 objNEmpty: function objNEmpty(_o) { if (!this.objGood(_o)) { return false; } return Object.keys(_o).length > 0; }, // 空对象 objEmpty: function objEmpty(_o) { return !this.objNEmpty(_o); }, // 对象合并 objConcat: function objConcat(_dic1, _dic2) { if (!this.objGood(_dic1)) { return this.objClone(_dic2); } if (!this.objGood(_dic1)) { return this.objClone(_dic1); } var dic = this.objClone(_dic1); for (var k in _dic2) { dic[k] = this.objClone(_dic2[k]); } return dic; }, // 获取对象成员数量 objLen: function objLen(_dic) { if (!this.objGood(_dic)) { return 0; } return Object.keys(_dic).length; }, // 深复制 objClone: function objClone(_obj) { // 非对象直接使用返回 if (!_obj || typeof _obj !== "object") { return _obj; } var out = _obj.constructor === Array ? [] : {}; var _clone = function _clone(o, c) { for (var i in o) { if (o[i] && typeof o[i] === "object") { if (o[i].constructor === Array) { c[i] = []; } else { c[i] = {}; } _clone(o[i], c[i]); } else { c[i] = o[i]; } } return c; }; return _clone(_obj, out); }, // 复制属性到对象 copyProperties: function copyProperties(_object, _dic, _log) { if (_log === void 0) { _log = false; } if (!this.objGood(_object) || !this.objGood(_dic)) { return false; } if (_log) { nx.debug("[DT]属性更新:"); } for (var k in _dic) { _object[k] = this.objClone(_dic[k]); if (_log) { nx.debug("\t\t键值: %s", k); } } }, // ------------------------------------------------------------ // 方法集:随机数的方法 // ------------------------------------------------------------ // 范围随机数 randomRange: function randomRange(_min, _max) { var Range = _max - _min; var Rand = Math.random(); var num = _min + Math.round(Rand * Range); //四舍五入 return num; }, // ------------------------------------------------------------ // 方法集:加密的方法 // ------------------------------------------------------------ // 获取md5 md5: function md5(key) { return md.hex_md5(key); }, // 加密 encode64: function encode64(str, pwd) { str = Base64.encode(str); //Base64加密 var prand = ""; for (var i = 0; i < pwd.length; i++) { prand += pwd.charCodeAt(i).toString(); } var sPos = Math.floor(prand.length / 5); var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos * 2) + prand.charAt(sPos * 3) + prand.charAt(sPos * 4) + prand.charAt(sPos * 5)); var incr = Math.ceil(pwd.length / 2); var modu = Math.pow(2, 31) - 1; if (mult < 2) { alert("Please choose a more complex or longer password."); return null; } var salt = Math.round(Math.random() * 1000000000) % 100000000; prand += salt; while (prand.length > 10) { prand = (parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length))).toString(); } prand = (mult * prand + incr) % modu; var enc_chr = ""; var enc_str = ""; for (var i = 0; i < str.length; i++) { enc_chr = parseInt(str.charCodeAt(i) ^ Math.floor(prand / modu * 255)); if (enc_chr < 16) { enc_str += "0" + enc_chr.toString(16); } else enc_str += enc_chr.toString(16); prand = (mult * prand + incr) % modu; } salt = salt.toString(16); while (salt.length < 8) salt = "0" + salt; enc_str += salt; return enc_str; }, // 解密 decode64: function decode64(str, pwd) { var prand = ""; for (var i = 0; i < pwd.length; i++) { prand += pwd.charCodeAt(i).toString(); } var sPos = Math.floor(prand.length / 5); var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos * 2) + prand.charAt(sPos * 3) + prand.charAt(sPos * 4) + prand.charAt(sPos * 5)); var incr = Math.round(pwd.length / 2); var modu = Math.pow(2, 31) - 1; var salt = parseInt(str.substring(str.length - 8, str.length), 16); str = str.substring(0, str.length - 8); prand += salt; while (prand.length > 10) { prand = (parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length))).toString(); } prand = (mult * prand + incr) % modu; var enc_chr = ""; var enc_str = ""; for (var i = 0; i < str.length; i += 2) { enc_chr = parseInt(parseInt(str.substring(i, i + 2), 16) ^ Math.floor(prand / modu * 255)); enc_str += String.fromCharCode(enc_chr); prand = (mult * prand + incr) % modu; } return Base64.decode(enc_str); }, // ------------------------------------------------------------ // 方法集:JSON // ------------------------------------------------------------ // 安全执行(异常捕获) trycatch: function trycatch(_dosth, _error) { try { _dosth(); } catch (e) { nx.error("[异常]:" + (e ? e.message + "\n" + e.stack : "未知错误!")); if (_error) { _error(e); } if (e && cc.sys.isNative && window && window.__errorHandler) { window.__errorHandler(e.message, "", "", e.stack); } } }, // JSON压缩 enjson: function enjson(_object) { try { return JSON.stringify(_object); } catch (e) { nx.error("[异常]:" + (e ? e.message + "\n" + e.stack : "未知错误!")); // if( e && cc.sys.isNative && window && window.__errorHandler ) { // window.__errorHandler( e.message, "", "", e.stack ); // } return ""; } }, // JSON解析 dejson: function dejson(_str) { // 空返回 if (!this.strNEmpty(_str)) { return null; } try { return JSON.parse(_str); } catch (e) { nx.error("[异常]:" + (e ? e.message + "\n" + e.stack : "未知错误!")); // if( e && cc.sys.isNative && window && window.__errorHandler ) { // window.__errorHandler( e.message, "", "", e.stack ); // } return null; } }, // ------------------------------------------------------------ // 方法集:时间的方法 // ------------------------------------------------------------ // 秒级时间戳 timeStamp: function timeStamp() { return Math.floor(cc.sys.now() / 1000); }, // 格式化日期 fmtDate: function fmtDate(_date, _year) { if (_year === void 0) { _year = true; } _date = _date ? _date : new Date(); if (this.numGood(_date)) { _date = new Date(_date); } var _format = function _format(v) { return v < 10 ? "0" + v : v; }; if (!_year) { return nx.text.formatS("%s:%s", _format(_date.getMonth() + 1), _format(_date.getDate())); } return nx.text.formatS("%s-%s-%s", _format(_date.getFullYear()), _format(_date.getMonth() + 1), _format(_date.getDate())); }, // 格式化日期 fmtDateLoc: function fmtDateLoc(_date, _year) { if (_year === void 0) { _year = true; } _date = _date ? _date : new Date(); if (!_year) { return nx.text.formatS("%s%s", nx.text.format("month", _date.getMonth() + 1), nx.text.format("day", _date.getDate())); } return nx.text.formatS("%s%s%s", nx.text.format("year", _date.getFullYear()), nx.text.format("month", _date.getMonth() + 1), nx.text.format("day", _date.getDate())); }, // 格式化时间 fmtTime: function fmtTime(_date) { _date = _date ? _date : new Date(); var _format = function _format(v) { return v < 10 ? "0" + v : v; }; return nx.text.formatS("%s:%s:%s", _format(_date.getHours()), _format(_date.getMinutes()), _format(_date.getSeconds())); }, // 格式化时间 fmtTimeFromSecs: function fmtTimeFromSecs(_secs, _full) { if (_full === void 0) { _full = false; } if (!this.numPositive(_secs, false)) { return _full ? "00:00:00" : "00:00"; } var f = function f(v) { return v < 10 ? "0" + v : v; }; var h = Math.floor(_secs / 3600); _secs = _secs % 3600; var m = Math.floor(_secs / 60); var s = Math.floor(_secs % 60); // 完整版本 if (_full) { return nx.text.formatS("%s:%s:%s", f(h), f(m), f(s)); } // 时:分:秒 if (h > 0) { return nx.text.formatS("%d:%s:%s", h, f(m), f(s)); } // 分:秒 if (m > 0) { return nx.text.formatS("%s:%s", f(m), f(s)); } // 秒 return '00:' + f(s); }, // 计算剩余天数(向上取整) // _ts: 秒级时间戳 getDaysFromNow: function getDaysFromNow(_ts) { var secs = Math.max(0, _ts - cc.sys.now() / 1000); var days = Math.ceil(secs / (24 * 3600)); return days; }, // ------------------------------------------------------------ // 方法集:URL的方法 // ------------------------------------------------------------ // 格式化URL formatURL: function formatURL(_url, _args) { if (!this.strNEmpty(_url)) { nx.error("WebTask:URL参数不能为空!"); return ""; } if (!this.objGood(_args)) { return encodeURI(_url); } var aline = ""; for (var k in _args) { aline += aline == "" ? "?" : "&"; var v = _args[k]; var o = this.objGood(v) || this.arrGood(v); aline += k + "=" + (o ? nx.dt.enjson(v) : v); } return encodeURI(_url + aline); }, // ------------------------------------------------------------ // 方法集:数量方法 // ------------------------------------------------------------ /** * 数量千分化 * @param {*} _count : 数量 * @param {*} _pn : 小数位数 * @returns */ fmtCount: function fmtCount(_count, _pn) { if (!nx.dt.numPositive(_pn) || _pn < 0 || _pn > 20) { _pn = DefPN; } _count = parseFloat((_count + "").replace(/[^\d\.-]/g, "")).toFixed(_pn) + ""; var l = _count.split(".")[0].split("").reverse(); var r = _count.split(".")[1]; var t = ""; for (var i = 0; i < l.length; i++) { t += l[i] + ((i + 1) % 3 == 0 && i + 1 != l.length ? "," : ""); } if (r) { var ret = t.split("").reverse().join("") + "." + r; } else { var ret = t.split("").reverse().join(""); } if ((ret.charAt(0) == "-" || ret.charAt(0) == "+") && ret.charAt(1) == ",") { ret = ret.charAt(0) + ret.slice(2); } return ret; }, /** * 数量简化 * @param {*} _count 数量 * @param {*} _sdd 强制+号 * @param {*} _pn 小数位数 * @param {*} _trimZero 忽略尾部0 * @returns */ shortCount: function shortCount(_count, _sdd, _pn, _trimZero) { if (_sdd === void 0) { _sdd = false; } if (_pn === void 0) { _pn = 2; } if (_trimZero === void 0) { _trimZero = true; } // 转数字 _count = parseInt(_count); if (!this.numGood(_count)) { _count = 0; } var lessZero = false; if (_count < 0) { lessZero = true; _count *= -1; } if (!this.numPositive(_pn)) { _pn = DefPN; } var value = ""; var unitKey = ""; // 国际通用KM小数点后保留2位来展示 // 小于1K // if( _count < 1000 ) { if (_count < 100000000) { value = "" + this.toFixedDecimal(_count); if (!_trimZero) { value = this.fmtCount(value, _pn); } } // // 1M > _count >= 1K // else if( _count >= 1000 && _count < 1000000 ) { // value = this.toFixedDecimal( _count / 1000 ).toFixed( _pn ); // unitKey = "K"; // } // 1B > _count >= 1M else if (_count >= 100000000 && _count < 1000000000) { value = this.toFixedDecimal(_count / 1000000).toFixed(_pn); unitKey = "M"; } // >= 1B else { value = this.toFixedDecimal(_count / 1000000000).toFixed(_pn); unitKey = "B"; } // 末尾0忽略 if (_trimZero) { value = Number(value) + unitKey; } else { value += unitKey; } if (lessZero) { value = "-" + value; } else { if (_sdd === true) { value = "+" + value; } } return value; }, // ------------------------------------------------------------ // 方法集:WEB参数解析 // ------------------------------------------------------------ // 获取URL网址参数 parseURLArgs: function parseURLArgs() { var theRequest = {}; // 非浏览器不处理 if (!cc.sys.isBrowser || !location) { return theRequest; } // 获取url中"?"符后的字串 var url = location.search; if (url.indexOf("?") != -1) { var str = url.substr(1); var strs = str.split("&"); for (var i = 0; i < strs.length; i++) { theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]); } } return theRequest; }, // 针对URL不正规的参数解析 queryURLArg: function queryURLArg(_key) { // 非浏览器不处理 if (!cc.sys.isBrowser || !window.location) { return null; } var reg = new RegExp('(^|&)' + _key + '=([^&]*)(&|$)', 'i'); var serach = ''; if (window.location.search.length > 0) { serach = window.location.search.substr(1); } else { serach = window.location.href.split('?')[1] ? window.location.href.split('?')[1] : ''; } var r = serach.match(reg); if (r != null) { return unescape(r[2]); } return null; }, // ------------------------------------------------------------ // 方法集:距离的方法 // ------------------------------------------------------------ // 格式化距离 formatDistance: function formatDistance(_meters) { if (typeof _meters != "number") { return nx.text.format("distance_none"); } if (_meters < 1000) { return nx.text.format("distance_m", _meters); } var km = Math.floor(_meters / 1000); return nx.text.format("distance_km", km); }, // 文件大小字节转K,M,G formatFileSize: function formatFileSize(_size) { if (!_size) { return ""; } var num = 1024.00; //byte if (_size < num) return _size + "B"; if (_size < Math.pow(num, 2)) return (_size / num).toFixed(2) + "K"; //kb if (_size < Math.pow(num, 3)) return (_size / Math.pow(num, 2)).toFixed(2) + "M"; //M if (_size < Math.pow(num, 4)) return (_size / Math.pow(num, 3)).toFixed(2) + "G"; //G return (_size / Math.pow(num, 4)).toFixed(2) + "T"; //T }, // 检测账号是否包含中文 formatAccount: function formatAccount(str) { if (typeof str !== 'string') { return false; } //去除字符串的左右两边空格 //+表示匹配一次或多次,|表示或者,\s和\u00A0匹配空白字符,/^以……开头,$以……结尾,/g全局匹配,/i忽略大小写 str = (str || "").replace(/^(\s|\u00A0)+|(\s|\u00A0)+$/g, ""); //匹配中文,match返回包含中文的数组 var chinese = str.match(/[\u4e00-\u9fa5]/g); //计算字符个数 return !!chinese; }, // 检测姓名是否是中文 formatChineseName: function formatChineseName(str) { if (str.length <= 1) { return false; } var re = /[^\u4e00-\u9fa5]/; return !re.test(str); }, // 随机字符串生成 randomStr: function randomStr(min, max, strRange) { var rd = function rd(_l, _r) { if (_r > _l) { return Math.round(Math.random() * (_r - _l)) + _l; } else { return _l; } }; var str = ""; strRange = strRange || '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; var n = rd(min, max); var len = strRange.length; for (var i = 0; i < n; i++) { var pos = rd(1, len) - 1; str += strRange.charAt(pos); } return str; } }); // 模块导出 module.exports = NxMath; cc._RF.pop();