// import GameMath from './GameMath'; // import { gameMethod } from '../cfg/gameMethod'; // import { gameCfg } from '../cfg/GameCfg'; // import Config from '../Config'; // import { Hdcid } from '../cfg/XyS'; import { gameMethod } from '../common/gameMethod'; import GameMath from './GameMath'; import { I18n } from './I18nUtil'; // import { WorkType } from '../cfg/XyWork'; // 本地化,格式化文字 export function localized(key: string, ...args): string { return stringFormat(key, args) // if (key == null || key.length == 0) { // return stringFormat(key, args) // } // let _lang = Config.lang // let data = GameCfg.lang.getItem(key) // if (data == null) { // return stringFormat(key, args) // } // let result = data[_lang] // if (result == null) { // return stringFormat(key, args) // } // return stringFormat(result, args) } // // 获取client配置表 // export function getWord(str: string, ...args): string { // if (gameMethod.isEmpty(gameCfg.langClient.getItem(str))) { // return str // } // let result = gameCfg.langClient.getItem(str)[Config.lang] // return stringFormat(result, args) // } // // 获取 clientText.csv配置表文字 // export function getText(str: string, ...args) { // let result = gameCfg.langClientText.getItem(str)[Config.lang] // return stringFormat(result, args) // } export function stringFormat(str: string, list: any[]): string { if (str == null) { return "" } let result = str list.forEach((element, index) => { result = result.replace(`%{${index}}`, element) }) return result } // /** // * 显示倒计时 // * @param time 倒计时结束时间戳 // * @param act 活动key // * @param hdcid 活动Hdcid // * @param type 倒计时展示类型 // * @returns // */ // export function showCdTime(time: number, act: WorkType, hdcid: string, type: string = '1') { // let cdTime: number = 0 // cdTime = time - GameDataCenter.timeModel.sevTime // if (cdTime >= 0) { // return this.showTime(cdTime, type) // } else { // // 防止延迟会一直重复发送请求 // if (GameDataCenter.timeModel.getIsKeyAdok(act)) { // GameDataCenter.timeModel.sendAdokKey(time, act, hdcid) // } // } // } /** * 秒级别(10位数) * @param time 时间戳 * @param type 类型 * 1: 大于一天,显示x天x时;小于一天,显示00:00:00(天数不足,补0) * 2: 1天36分(只显示最前面的两位) * 3: 小于一小时,显示xx:xx(分秒) * 4: 只显示最高单位 大于1天 显示1天 大于1小时 显示1时 * @returns */ export function showTime(time: number, type: string = "1"): string { if (time.toString().length == 13) { time = Math.floor(time / 1000) } if (time <= 0) { return type == "3" ? "00:00" : "00:00:00" } let tTime = '' let day: number = 0 let hour: number = 0 let minute: number = 0 let second: number = 0 day = Math.floor(time / (24 * 60 * 60)) hour = Math.floor((time % (24 * 60 * 60)) / (60 * 60)) minute = Math.floor((time % (60 * 60)) / 60) second = Math.floor(time % 60) if (type == "1") { if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dh', day, hour) } else if (hour > 0) { tTime = `${GameMath.addZero(day * 24 + hour)}:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` // tTime = `${GameMath.addZero(day * 24 + hour)}时${GameMath.addZero(minute)}分` } else if (minute > 0) { tTime = `00:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` // tTime = `${GameMath.addZero(minute)}分${GameMath.addZero(second)}秒` } else { tTime = `00:00:${GameMath.addZero(second)}` // tTime = `${GameMath.addZero(second)}秒` } } else if (type == "2") { if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dh', day, hour) } else if (hour > 0) { tTime = `${GameMath.addZero(day * 24 + hour)}时${GameMath.addZero(minute)}分` } else if (minute > 0) { tTime = `${GameMath.addZero(minute)}分${GameMath.addZero(second)}秒` } else { tTime = `${GameMath.addZero(second)}秒` } } else if (type == '3') { if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dh', day, hour) } else if (hour > 0) { tTime = `${GameMath.addZero(day * 24 + hour)}:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` // tTime = `${GameMath.addZero(day * 24 + hour)}时${GameMath.addZero(minute)}分` } else if (minute > 0) { tTime = `${GameMath.addZero(minute)}:${GameMath.addZero(second)}` // tTime = `${GameMath.addZero(minute)}分${GameMath.addZero(second)}秒` } else { tTime = `00:${GameMath.addZero(second)}` // tTime = `${GameMath.addZero(second)}秒` } } else if (type == '4') { if (day > 1) { tTime = I18n.getI18nText('common_timeformat_d', day) } else if (day > 0 || hour > 0) { tTime = I18n.getI18nText('common_timeformat_h', day * 24 + hour) } else if (minute > 0) { tTime = I18n.getI18nText('common_timeformat_m', minute) } else { tTime = I18n.getI18nText('common_timeformat_s', second) } } else if (type == '5') { if (day > 0) { tTime = `${GameMath.addZero(day * 24 + hour)}:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else if (hour > 0) { tTime = `${GameMath.addZero(day * 24 + hour)}:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else if (minute > 0) { tTime = `00:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else { tTime = `00:00:${GameMath.addZero(second)}` } } else if (type == '6') { if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dhms', day, hour, minute, second);// x天x小时x分x秒 } else if (hour > 0) { tTime = I18n.getI18nText('common_timeformat_hms', hour, minute, second);// x小时x分x秒 } else if (minute > 0) { tTime = I18n.getI18nText('common_timeformat_ms', minute, second);// x分x秒 } else { tTime = I18n.getI18nText('common_timeformat_s', second);// x秒 } } else if (type == '7') { if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dhms_2', day, GameMath.addZero(hour), GameMath.addZero(minute), GameMath.addZero(second)) } else if (hour > 0) { tTime = `${GameMath.addZero(hour)}:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else if (minute > 0) { tTime = `00:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else { tTime = `00:00:${GameMath.addZero(second)}` } } else if (type == '8') { // 显示两个单位 if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dh', day, hour) } else if (hour > 0) { tTime = `${GameMath.addZero(day * 24 + hour)}:${GameMath.addZero(minute)}` } else if (minute > 0) { tTime = `${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else { tTime = `00:${GameMath.addZero(second)}` } } return tTime } export function showTimeYMD(shijianchuo: number, type: number = 0): string { if (shijianchuo.toString().length == 10) { shijianchuo = shijianchuo * 1000 } var time = new Date(shijianchuo); var y = time.getFullYear() var m = time.getMonth() + 1 var d = time.getDate() var h = time.getHours() var mm = time.getMinutes() var s = time.getSeconds() if (type == 0) { return `${y}-${GameMath.addZero(m)}-${GameMath.addZero(d)} ${GameMath.addZero(h)}:${GameMath.addZero(mm)}:${GameMath.addZero(s)}` } else if (type == 1) { return `${GameMath.addZero(y)}-${GameMath.addZero(m)}-${GameMath.addZero(d)}` } else if (type == 2) { return `${GameMath.addZero(y)}.${GameMath.addZero(m)}.${GameMath.addZero(d)}` } else if (type == 3) { return `${GameMath.addZero(m)}-${GameMath.addZero(d)} ${GameMath.addZero(h)}:${GameMath.addZero(mm)}` } else if (type == 4) { return `${GameMath.addZero(m)}/${GameMath.addZero(d)}` } else if (type == 5) { return `${GameMath.addZero(y)}/${GameMath.addZero(m)}/${GameMath.addZero(d)}` } else if (type == 6) {//设置界面时间显示 return `${GameMath.addZero(y)}-${GameMath.addZero(m)}-${GameMath.addZero(d)} ${GameMath.addZero(h)}:${GameMath.addZero(mm)}:${GameMath.addZero(s)}` } else if (type == 7) { return `${GameMath.addZero(h)}:${GameMath.addZero(mm)}` } else if (type == 8) { return I18n.getI18nText('common_timeformat_ymd', y, m, d) } else if (type == 9) { return I18n.getI18nText('common_timeformat_md', m, d) } else if (type == 10) { return `${y}/${m}/${d}` } else if (type == 11) { // 00:00:00格式 return `${GameMath.addZero(h)}:${GameMath.addZero(mm)}:${GameMath.addZero(s)}` } else if (type == 12) { return `${GameMath.addZero(y)}/${GameMath.addZero(m)}/${GameMath.addZero(d)} ${GameMath.addZero(h)}:${GameMath.addZero(mm)}:${GameMath.addZero(s)}` } else if (type == 13) { return `${GameMath.addZero(m)}/${GameMath.addZero(d)} ${GameMath.addZero(h)}:${GameMath.addZero(mm)}:${GameMath.addZero(s)}` } } export function showTimeWord(time: number, type: string = "1"): string { let tTime = '' let month: number = 0 let day: number = 0 let hour: number = 0 let minute: number = 0 let second: number = 0 month = Math.floor(time / (30 * 24 * 60 * 60)) day = Math.floor(time / (24 * 60 * 60)) hour = Math.floor((time % (24 * 60 * 60)) / (60 * 60)) minute = Math.floor((time % (60 * 60)) / 60) second = Math.floor(time % 60) if (type == "1") { if (month > 0) { tTime = I18n.getI18nText('common_timeword_4', month) } else if (day > 0) { tTime = I18n.getI18nText('common_timeword_3', day) } else if (hour > 0) { tTime = I18n.getI18nText('common_timeword_2', hour) } else if (minute > 0) { tTime = I18n.getI18nText('common_timeword_1', minute) } else { tTime = I18n.getI18nText('common_timeword_5') } } else if (type == "2") { if (month > 0) { tTime = I18n.getI18nText('common_timeformat_mdhms_2', month, day, GameMath.addZero(hour), GameMath.addZero(minute), GameMath.addZero(second)) } else if (day > 0) { tTime = I18n.getI18nText('common_timeformat_dhms_2', day, GameMath.addZero(hour), GameMath.addZero(minute), GameMath.addZero(second)) } else if (hour > 0) { tTime = `${hour}:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else if (minute > 0) { tTime = `00:${GameMath.addZero(minute)}:${GameMath.addZero(second)}` } else if (second > 0) { tTime = `00:00:${GameMath.addZero(second)}` } else { tTime = `00:00:00` } } else { tTime = I18n.getI18nText('common_timeformat_unknowtype') } return tTime } export function IsSameDay(timestamp1: number, timestamp2: number) { const date1 = new Date(timestamp1 * 1000); // 转化为毫秒时间戳 const date2 = new Date(timestamp2 * 1000); return ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate() ); } // 阿拉伯数字转中文 // export function chineseByNumber(number: number): string { // const chineseNumbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']; // const chineseUnits = ['', '十', '百', '千', '万']; // if (number <= 10) { // return chineseNumbers[number]; // } else { // const numberString = number.toString(); // let result = ' '; // for (let i = 0; i < numberString.length; i++) { // const digit = parseInt(numberString[i]); // if (digit !== 0) { // if (numberString.length === 2 && i === 0 && digit === 1) { // result += chineseUnits[numberString.length - i - 1]; // } else { // result += chineseNumbers[digit] + chineseUnits[numberString.length - i - 1]; // } // } else { // if (i === 0 || numberString[i - 1] !== '0') { // result += chineseNumbers[digit]; // } // } // } // return result; // } // } export class FormulaCom { // return random int [min,max] static random(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1) + min) } static uuid(len1, len2) { let timestamp = (new Date()).valueOf(); return FormulaCom.random(Math.pow(10, len1 - 1) - 1, Math.pow(10, len1)).toString() + timestamp % (Math.pow(10, len2)) } static time: number = 0 static costTime(type: number) { if (type == 1) { this.time = Date.now() } else if (type == 2) { console.log(`cost ${Date.now() - this.time}ms`) } } //随机抽取元素不重复 static getRandomArrayElements(arr: Array, count: number): Array { count = Math.min(count, arr.length) var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index; while (i-- > min) { index = Math.floor((i + 1) * Math.random()); temp = shuffled[index]; shuffled[index] = shuffled[i]; shuffled[i] = temp; } return shuffled.slice(min); } // /** // * 一个时间点 距离今天相差几天 以1开始算 今天算1天 今天之后的算0天 // * @param str // */ // static passDay(str: number): number { // let Dates = new Date(GameDataCenter.timeModel.sevTime * 1000).setHours(0, 0, 0, 0);//获取今天0点0分0秒0毫秒。 // let checkTime = new Date(str * 1000).setHours(0, 0, 0, 0);//获取当天0点0分0秒0毫秒。 // if (Dates < checkTime) { // return 0 // } // return Math.abs(Math.floor((Dates - checkTime) / 86400000)) + 1; // } // a>b则返回>0 a=b则返回0 a vA.length) { return -1 } else { return 0 } } static getStrLength(str: string): number { let a = 0; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 255) a += 2;//按照预期计数增加2 else a++; } return a; } // 限制(默认16个字符) 中文2 英文1 static getLimitStr(str: string, limit: number = 16): string { let a = 0; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 255) a += 2;//按照预期计数增加2 else a++; if (a > limit) { return str.slice(0, i) } } return str } static isOverLimit(str: string, limit: number = 16): boolean { let a = 0; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 255) a += 2;//按照预期计数增加2 else a++; if (a > limit) { return true } } return false } // 多个对象在界面上的居中展示,需要box的锚点在中心 example: 3个道具 就是 -50 0 50 // index以0为初始 static getPosInBox(index: number, total: number, bgWidth: number, itemWidth: number): number { let space = total == 1 ? 0 : (((bgWidth - itemWidth * total) / (total - 1) + itemWidth)) let posx = 0 posx = -((total - 1) * (space / 2)) + index * (space) return posx } // static isMinGan(str: string): boolean { // str = str.replace("\\u00A0", "") //去空 // if (GameCfg.words.minGan.pool != null && str.length > 0) { // for (let i in GameCfg.words.minGan.pool) { // let _name = GameCfg.words.minGan.pool[i].name // if (str.toLowerCase().indexOf(_name.toLowerCase()) != -1) { // return true // } // } // } // return false // } // 提取包含 <%t>格式的字段 static getExecStrs(str): string[] { // var reg = /\<\%(.+?)\>/g var reg = /\<(.+?)\>/g var list = [] var result = null do { result = reg.exec(str) result && list.push(result[1]) } while (result) return list } // // 将文字中的<%t12648673123> 转化为时间 // // 返回 [解析后的字符串,时间戳,时间戳...] // static textAnalysis(text: string): string[] { // // list列表 ["t12323451514","t145132154"] // let list = FormulaCom.getExecStrs(text) // let timeList = [] // let result = [] // let resultText = text // list.forEach(element => { // if (element[0] == "t") { // // 去除英文,保留数字 // timeList.push(element.replace(/[^\d]/g, '')) // } // }); // timeList.forEach(time => { // let tag = "<%t" + time + ">" // // resultText = resultText.replace(tag, new Date(time).toTimeString()) // resultText = resultText.replace(tag, showTimeYMD(time)) // }) // result.push(resultText) // timeList.forEach(time => { // result.push(time) // }); // return result // } /** 让动画在指定区间内循环 */ static loopAtFrame(te: sp.spine.TrackEntry, sFrame: number, eFrame: number) { if (te.animationStart === 0) { te.animationStart = sFrame / 30; // 30是Spine动画的帧率 te.animationEnd = eFrame / 30; } } /** * 停止在指定帧。1是开始,-1是最后 * @param frame 帧数 */ static stopAtFrame(spineComp: sp.Skeleton, frame: number) { const te = spineComp.getCurrent(0) as sp.spine.TrackEntry; // 算出帧对应的时间 let time; if (frame === -1) { time = te.animation.duration; // 最后一帧 } else if (frame > 1) { time = (frame - 1) / 30; // 根据帧率算出对应时间,spine帧率是30 } else { time = 0; // 首帧 } // 对time作限制 if (time < 0) time = 0; if (time >= te.animation.duration) time = te.animation.duration - 0.01; // 太精确的话,动画会停在首帧,所以要减一点 te.timeScale = 0; // 让动画停止 te.trackTime = time; } /** * 把服务器时间戳 改为本地时间戳 * @param time 需要转换的时间戳 * @param utcMin 服务器时区(按分钟计) // -300 西5区美国 -5*60 GMT-5 // 0 // 480 东8区北京 8*60 */ static getUtcTime(time: number, utcHour: number): number { let utcMin = utcHour * 60 //本地时间类 let localtime = new Date(); //本地时区针对标准时区的偏移 let pym = localtime.getTimezoneOffset() //时间转换为指定时区时间 time += (pym + utcMin) * 60 return time } static getRandomTag(): string { let outString: string = ''; let inOptions: string = 'abcdefghijklmnopqrstuvwxyz0123456789'; for (let i = 0; i < 16; i++) { outString += inOptions.charAt(Math.floor(Math.random() * inOptions.length)); } return outString; } static getDistance(x1: number, y1: number, x2: number, y2: number) { var a = x2 - x1 var b = y2 - y1 return Math.sqrt(a * a + b * b) } /** * 根据锚点重新计算中心点世界坐标坐标 * @param pos 锚点的世界坐标 * @param node 节点 * @returns */ static fixAnchor(pos: cc.Vec2, node: cc.Node): cc.Vec2 { let x = pos.x - node.anchorX * node.width + node.width / 2 let y = pos.y - node.anchorY * node.height + node.height / 2 return new cc.Vec2(x, y) } /** * 获得某个节点中心点的世界坐标 * @param node * @returns */ static getWorldCenterPos(node: cc.Node): cc.Vec2 { return this.fixAnchor(this.getWorldPos(node), node) } static getWorldPos(node: cc.Node): cc.Vec2 { if (gameMethod.isEmpty(node)) return cc.v2(0, 0); return node.convertToWorldSpaceAR(cc.Vec2.ZERO) } static setPosByWorldPos(node: cc.Node, pos: cc.Vec2) { if (gameMethod.isEmpty(node)) return; let _pos = node.parent.convertToNodeSpaceAR(pos) node.x = _pos.x node.y = _pos.y } //获取node位于target的坐标相对坐标 static getPositionInView(node: cc.Node, target: cc.Node): { x: number, y: number } { let worldPos = node.parent.convertToWorldSpaceAR(node.position); let viewPos = target.convertToNodeSpaceAR(worldPos); return viewPos; } // 获取玩家最后一次登录时间 static getUserState(lastadok: number, sevTime: number) { let userState: string = '' let time = Math.floor((sevTime - lastadok) / 60) if (time < 6) { userState = I18n.getI18nText('common_userLoginState_1') } else if (time < 60) { userState = I18n.getI18nText('common_timeword_1', time) } else if (time < 24 * 60) { userState = I18n.getI18nText('common_timeword_2', Math.floor(time / 60)) } else { userState = I18n.getI18nText('common_timeword_3', Math.floor((time / 60) / 24)) } return userState } // 已知圆心,半径,角度,求坐标 static getPosbyAngle(centerX: number, centerY: number, range: number, angle: number): { x: number, y: number } { let radians = this.getRadiansByAngle(angle) let dx = Math.cos(radians) * range let dy = Math.sin(radians) * range return { x: centerX + dx, y: centerY + dy } } // 已知坐标求角度 static getAngleByPos(x1: number, y1: number, x2: number, y2: number): number { if (x1 == x2 && y1 == y2) { return 0 } let degree = Math.atan2(y2 - y1, x2 - x1) return degree * 180 / Math.PI } //求两个点的角度 static getAngle(startPos: cc.Vec2, endPos: cc.Vec2): number { //计算出朝向 var dx = endPos.x - startPos.x; var dy = endPos.y - startPos.y; var dir = cc.v2(dx, dy); //根据朝向计算出夹角弧度 var angle = dir.signAngle(cc.v2(1, 0)); //将弧度转换为欧拉角 var degree = angle / Math.PI * 180; return -degree } // 根据角度获取弧度 static getRadiansByAngle(angle: number) { return angle / 180 * Math.PI } // 根据弧度获取角度 static getAngleByRadians(radians: number) { return radians * 180 / Math.PI } static obj2Array(object: { [s: string]: T }): T[] { if (typeof object != "object") { return [] } return Object.values(object) // let array = [] // for (const key in object) { // array.push(object[key]) // } // return array } static strDLength(str: string): number { let rStr = str.replace(/[^\x00-\xff]/g, '')//双字节字符:(包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)) return str.length - rStr.length } // 首字母大写 static firstUpCase(str: string) { return str[0].toUpperCase() + str.substring(1) } // 判断字符长度 static getStrCharacterLength(str): number { let patternChinese = new RegExp("[\u4E00-\u9FA5]+"); // 中文 let leng = 0 for (let index = 0; index < str.length; index++) { if (patternChinese.test(str[index])) { leng += 2 } else { leng += 1 } } return leng } //根据索引获取当前行列数 // index 当前索引值(从0开始) elementsPerRow 一行有几个 static getRowAndColumnFromIndex(index: number, columnCount: number) { if (columnCount < 1) { throw new Error('Column count must be a positive integer.'); } const rowIndex = Math.floor(index / columnCount); const columnIndex = index % columnCount; return { rowIndex, columnIndex }; } // 对数组按数量分组 static groupTwoByTwo(input: T[], count: number): T[][] { const result: T[][] = []; for (let i = 0; i < input.length; i += count) { if (gameMethod.isEmpty(input[i]) || gameMethod.isEmpty(input[i + 1])) { console.error("该数组分配不足,检查数组长度") } result.push([input[i], input[i + 1]]); } return result; } } // 阿拉伯数字转中文 export function chineseByNumber(number: number): string { const chineseNumbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']; const chineseUnits = ['', '十', '百', '千', '万']; if (number <= 10) { return chineseNumbers[number]; } else { const numberString = number.toString(); let result = ' '; for (let i = 0; i < numberString.length; i++) { const digit = parseInt(numberString[i]); if (digit !== 0) { if (numberString.length === 2 && i === 0 && digit === 1) { result += chineseUnits[numberString.length - i - 1]; } else { result += chineseNumbers[digit] + chineseUnits[numberString.length - i - 1]; } } else { if (i === 0 || numberString[i - 1] !== '0') { result += chineseNumbers[digit]; } } } return result; } }