1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222 |
- /** @format */
- import {ConstValue} from '../data/ConstValue'
- class CCUtils {
- /**
- * 设置Label文本
- * @param str
- * @param node
- * @param childUrl
- */
- public setLabel(str: string, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- const child = cc.find(childUrl, node)
- if (child) {
- node = cc.find(childUrl, node)
- }
- }
- let label = node.getComponent(cc.Label)
- if (node.getComponent('i18nLabel')) {
- label = node.getComponent('i18nLabel')
- }
- if (label) {
- label.string = str
- } else {
- cc.warn('setLabel err, str:', str)
- }
- }
- public labelForceUpdateRenderData(node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- const child = cc.find(childUrl, node)
- if (child) {
- node = cc.find(childUrl, node)
- }
- }
- let label = node.getComponent(cc.Label)
- if (label) {
- ;(<any>label)._forceUpdateRenderData()
- } else {
- cc.warn('labelForceUpdateRenderData err')
- }
- }
- /**
- * 设置LabelOutLine颜色
- * @param color '#XXXXXX'| cc.Color
- * @param node
- * @param childUrl
- */
- public setLabelOutlineColor(color: string | cc.Color, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const label = node.getComponent(cc.LabelOutline)
- if (label) {
- if (typeof color == 'string') {
- label.color = new cc.Color().fromHEX(color)
- } else {
- label.color = color
- }
- } else {
- cc.warn('setLabelOutlineColor err, color:', color)
- }
- }
- /**
- * 设置RichLabel文本
- * @param str
- * @param node
- * @param childUrl
- */
- public setRichLabel(str: string, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- let label = node.getComponent(cc.RichText)
- if (node.getComponent('i18nLabel')) {
- label = node.getComponent('i18nLabel')
- }
- if (label) {
- label.string = str
- } else {
- cc.warn('setRichLabel err, str:', str)
- }
- }
- public setRichLabelGray(node: cc.Node, childUrl?: string, grayColor?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- let label = node.getComponent(cc.RichText)
- let gray = grayColor ? grayColor : '#AAAAAA'
- if (label) {
- label.string = `<color=${gray}>${label.string.replace(/<color=[^>]*>/g, `<color=${gray}>`)}</color>`
- } else {
- cc.warn('setRichLabelGray err, label:', label)
- }
- }
- /**
- * 按照spriteFrame设置大小
- */
- public setSFAndScale(spriteFrame: cc.SpriteFrame, scale: number = 1, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- node.getComponent(cc.Sprite).spriteFrame = spriteFrame
- if (spriteFrame) {
- node.width = spriteFrame.getRect().width * scale
- node.height = spriteFrame.getRect().height * scale
- } else {
- cc.warn('setSFAndScale err')
- }
- }
- /**
- * 设置spriteFrame
- */
- public setSpriteFrame(spriteFrame: cc.SpriteFrame, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- let sprite = node.getComponent(cc.Sprite)
- if (!sprite) {
- cc.warn('setSFAndScale err no sprite')
- return
- }
- sprite.spriteFrame = spriteFrame
- }
- /**
- *
- * @param isInteract
- * @param node
- * @param childUrl
- */
- public setBtnInteract(isInteract: boolean, node: cc.Node, childUrl?: string, isHasWarn: boolean = true) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const button = node.getComponent(cc.Button)
- if (button) {
- button.interactable = isInteract
- } else {
- if (isHasWarn) {
- cc.warn('setBtnInteract err')
- }
- }
- }
- /**
- * 进度条 设置进度
- * @param progress
- * @param node
- * @param childUrl
- */
- public setProgress(progress: number, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const progressBar = node.getComponent(cc.ProgressBar)
- if (progressBar) {
- progressBar.progress = progress
- } else {
- cc.warn('setProgress err')
- }
- }
- /**
- * 滑动条 设置进度
- * @param progress
- * @param node
- * @param childUrl
- */
- public setSliderProgress(progress: number, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const progressBar = node.getComponent(cc.Slider)
- if (progressBar) {
- progressBar.progress = progress
- } else {
- cc.warn('setSiderProgress err')
- }
- }
- /**
- *
- * @param isInteract
- * @param node(父节点)
- * @param childUrl
- */
- public setTogglesInteract(isInteract: boolean, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const toggle = node.getComponent(cc.Toggle)
- if (toggle) {
- toggle.enabled = isInteract
- }
- }
- /**
- *
- * @param checkedIndex
- * @param node(父节点)
- * @param childUrl
- */
- public setTogglesChecked(checkedIndex: number, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const children = node.children
- children.forEach((value, index) => {
- const toggle = value.getComponent(cc.Toggle)
- if (toggle) {
- toggle.isChecked = index == checkedIndex
- }
- })
- }
- public setColor(color: string, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- node.color = cc.Color.WHITE.fromHEX(color)
- }
- /**
- * 按钮延迟激活
- */
- public btnDelayActive(time: number, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const btn = node.getComponent(cc.Button)
- if (btn) {
- btn.interactable = false
- node.stopAllActions()
- node.runAction(
- cc.sequence(
- cc.delayTime(time),
- cc.callFunc(() => {
- btn.interactable = true
- }),
- ),
- )
- } else {
- cc.warn('btnDelayActive err')
- }
- }
- /**
- * 设置EditBox文本
- * @param str
- * @param node
- * @param childUrl
- */
- public setEditBox(str: string, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- const child = cc.find(childUrl, node)
- if (child) {
- node = cc.find(childUrl, node)
- }
- }
- const editBox = node.getComponent(cc.EditBox)
- if (editBox) {
- editBox.string = str
- } else {
- cc.warn('setEditBox err, str:', str)
- }
- }
- /**
- * 停止动画
- */
- public stopAni(node: cc.Node, clipName?: string, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const ani = node.getComponent(cc.Animation)
- if (ani) {
- ani.play(clipName)
- ani.setCurrentTime(0, clipName)
- ani.sample(clipName)
- ani.stop(clipName)
- } else {
- //cc.warn('stopAni err')
- }
- }
- /**
- * 开始动画
- */
- public playAni(aniStr: string, startTime: number = 0, node: cc.Node, childUrl?: string): cc.Animation {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- this.stopAni(node, aniStr)
- const ani = node.getComponent(cc.Animation)
- if (ani) {
- ani.play(aniStr, startTime)
- return ani
- } else {
- cc.warn('playAni err')
- }
- }
- public playNodeAllAni(node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- node.active = true
- const children = node.children
- children.forEach(value => {
- const aniCom = value.getComponent(cc.Animation)
- if (aniCom) {
- this.stopAni(value)
- aniCom.play()
- }
- })
- }
- public stopNodeAllAni(node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- node.active = false
- const children = node.children
- children.forEach(value => {
- const aniCom = value.getComponent(cc.Animation)
- if (aniCom) {
- this.stopAni(value)
- }
- })
- }
- /**
- * 判断当前节点是否在屏幕内
- */
- public isInScreen(node: cc.Node, yIn: boolean = false, xIn: boolean = false) {
- if (!cc.isValid(node)) {
- return
- }
- let isyIn = false
- let isxIn = false
- const worldPos = node.convertToWorldSpaceAR(cc.v2(0, 0))
- isyIn = worldPos.y - node.height <= 1136 && worldPos.y + node.height >= 0
- isxIn = worldPos.x - node.width <= 640 && worldPos.x + node.width >= 0
- if (yIn) {
- return isyIn
- }
- if (xIn) {
- return isxIn
- }
- return isxIn && isyIn
- }
- /**
- * 获取全部的子节点(递归)
- * @param node
- */
- public getAllChildrenByRecurve(node: cc.Node) {
- let ret: cc.Node[] = []
- ret = ret.concat(node.children)
- for (let i = 0; i < node.children.length; i++) {
- ret = ret.concat(this.getAllChildrenByRecurve(node.children[i]))
- }
- return ret
- }
- /**
- * 获取全部的子节点(广度)
- * @param node
- */
- public getAllChildrenBFS(node: cc.Node) {
- if (!node || !node.children.length) {
- return
- }
- const ret = []
- let stack = []
- // 先将第一层节点放入栈
- for (let i = 0, len = node.children.length; i < len; i++) {
- stack.push(node.children[i])
- }
- let item = null
- while (stack.length) {
- item = stack.shift()
- ret.push(item)
- // 如果该节点有子节点,继续添加进入栈底
- if (item.children && item.children.length) {
- stack = stack.concat(item.children)
- }
- }
- return ret
- }
- /**
- * 获取全部的子节点(深度)
- * @param node
- */
- public getAllChildrenDFS(node: cc.Node): cc.Node[] {
- if (!node || !node.children.length) {
- return
- }
- const ret = []
- let stack = []
- // 先将第一层节点放入栈
- for (let i = 0, len = node.children.length; i < len; i++) {
- stack.push(node.children[i])
- }
- let item = null
- while (stack.length) {
- item = stack.shift()
- ret.push(item)
- // 如果该节点有子节点,继续添加进入栈顶
- if (item.children && item.children.length) {
- stack = item.children.concat(stack)
- }
- }
- return ret
- }
- /**
- * 获取name应该对应的node
- * @param {节点} nodes
- * @param {*} val
- */
- public findNodeByName(node: cc.Node, name: string): cc.Node | null {
- if (node.name === name) {
- return node
- }
- for (let i = 0; i < node.children.length; i++) {
- if (this.findNodeByName(node.children[i], name)) {
- // 若找到则返回该节点
- return this.findNodeByName(node.children[i], name)
- }
- }
- return null
- }
- public setNodeColorGray(isGray: boolean, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- node.color = isGray ? cc.Color.GRAY : cc.Color.WHITE
- }
- /**
- * 将节点置灰
- * @param node
- * @param isGray
- */
- public setAllGray(isGray: boolean, node: cc.Node, childUrl?: string) {
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const all = this.getAllChildrenDFS(node).concat(node)
- if (all) {
- for (let i = 0; i < all.length; i++) {
- if (all[i].name.indexOf('notGray') != -1) {
- continue
- }
- this.setBtnInteract(!isGray, all[i], null, false)
- this.setSpriteGray(isGray, all[i])
- //文字相关置灰
- const customKey = 'custom_originColor'
- let labGray = (obj: cc.LabelOutline | cc.Label) => {
- if (!obj?.isValid) return
- if (!isGray) {
- let originColor: string = obj[customKey]
- if (originColor) {
- if (obj instanceof cc.Label) {
- obj.node.color = cc.Color.WHITE.fromHEX(originColor)
- } else {
- obj.color = cc.Color.WHITE.fromHEX(originColor)
- }
- obj[customKey] = null
- }
- } else {
- let lbColor = obj instanceof cc.Label ? obj.node.color : obj.color
- if (!obj[customKey]) obj[customKey] = lbColor.toHEX()
- if (obj instanceof cc.Label) {
- obj.node.color = cc.Color.WHITE.fromHEX('#272727')
- } else {
- obj.color = cc.Color.WHITE.fromHEX('#A79D9C')
- }
- }
- }
- let label = all[i].getComponent(cc.Label)
- labGray(label)
- let labOutline = all[i].getComponent(cc.LabelOutline)
- labGray(labOutline)
- }
- }
- }
- /**
- * 将精灵置灰
- * @param node
- * @param isGray
- */
- public setSpriteGray(isGray: boolean, node: cc.Node, childUrl?: string) {
- if (!cc.isValid(node)) {
- return
- }
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- const sprite = node.getComponent(cc.Sprite)
- if (!sprite) {
- return
- }
- if (isGray) {
- sprite.setMaterial(0, cc.Material.getBuiltinMaterial('2d-gray-sprite'))
- } else {
- sprite.setMaterial(0, cc.Material.getBuiltinMaterial('2d-sprite'))
- }
- }
- /**
- * 返回使用数学计量单位K(千) M(兆) G(吉)....来表示的数字
- * @param n
- * @param fix 保留几位小数 0
- */
- // public getSCI(n: number | string | Long, fix?:number): string {
- // const base = Long.fromValue(n);
- // let baseString = n.toString(); // 小数部分
- // if (base.lessThanOrEqual(10000)) {
- // return base.toString();
- // }
- // const si = [
- // { value: 1, symbol: '' },
- // { value: 1E3, symbol: 'K' },
- // { value: 1E6, symbol: 'M' },
- // { value: 1E9, symbol: 'G' },
- // { value: 1E12, symbol: 'T' },
- // { value: 1E15, symbol: 'P' },
- // { value: 1E18, symbol: 'E' },
- // ];
- // if (fix && baseString.length > fix) {
- // if (baseString.length > 0) {
- // baseString = `.${baseString.substr(1, fix)}`;
- // } else {
- // baseString = '';
- // }
- // } else {
- // baseString = '';
- // }
- // let i;
- // for (i = si.length - 1; i > 0; i--) {
- // if (base.greaterThanOrEqual(si[i].value)) {
- // break;
- // }
- // }
- // return (base.divide(si[i].value)).toString() + baseString + si[i].symbol;
- // }
- /**
- * 将一个节点转换为Canvas下的坐标AR
- * @param node 指定的节点
- */
- public convertToWorldSpaceCanvasAR(node: cc.Node) {
- const pos = node.parent.convertToWorldSpaceAR(node.position)
- return cc.Canvas.instance.node.convertToNodeSpaceAR(pos)
- }
- /**
- * 将Canvas下的坐标转换为一个节点AR
- * @param node 指定的节点
- */
- public convertCanvasToNodeAR(node: cc.Node, pos: cc.Vec2 = cc.Vec2.ZERO) {
- const world = cc.Canvas.instance.node.convertToWorldSpaceAR(pos)
- return node.convertToNodeSpaceAR(world)
- }
- /**
- * node节点在target节点下的坐标AR
- * @param node 指定的节点
- */
- public convertNode2NodePosAR(node: cc.Node, target: cc.Node) {
- const pos = this.convertToWorldSpacePos(node)
- return this.convertWorldPosToNode(target, pos)
- }
- // 将一个节点转换为世界坐标
- public convertToWorldSpacePos(node: cc.Node) {
- return node.parent.convertToWorldSpaceAR(node.getPosition())
- }
- // 将世界坐标转为节点内坐标
- public convertWorldPosToNode(node: cc.Node, pos: cc.Vec2) {
- return node.convertToNodeSpaceAR(pos)
- }
- // 将触点坐标转为世界坐标
- public convertTouchPosToWorld(e) {
- let screenPos = e.getLocation()
- let dSize = cc.view.getDesignResolutionSize()
- let dV2 = cc.v2(dSize.width, dSize.height)
- let winV2 = cc.v2(cc.winSize.width, cc.winSize.height)
- return screenPos.sub(winV2.sub(dV2).divide(2))
- }
- // 角度转弧度
- angle2radian(angle: number): number {
- // 角度转弧度公式
- // π / 180 * 角度
- // 计算出弧度
- let radian = (Math.PI / 180) * angle
- // 返回弧度
- return radian
- }
- // 弧度转角度
- radian2angle(radian: number): number {
- // 弧度转角度公式
- // 180 / π * 弧度
- // 计算出角度
- let angle = (180 / Math.PI) * radian
- // 返回弧度
- return angle
- }
- // 角度转向量
- angle2pos(angle: number): cc.Vec2 {
- // tan = sin / cos
- // 将传入的角度转为弧度
- let radian = this.angle2radian(angle)
- // 算出cos,sin和tan
- let cos = Math.cos(radian) // 邻边 / 斜边
- let sin = Math.sin(radian) // 对边 / 斜边
- let tan = sin / cos // 对边 / 邻边
- // 结合在一起并归一化
- let vec = cc.v2(cos, sin).normalize()
- // 返回向量
- return vec
- }
- // 向量转角度
- pos2angle(vector: cc.Vec2, curNormalize: cc.Vec2 = cc.v2(1, 0)): number {
- // 将传入的向量归一化
- let dir = vector.normalize()
- // 计算出目标角度的弧度
- let radian = dir.signAngle(curNormalize)
- // 把弧度计算成角度
- let angle = -this.radian2angle(radian)
- // 返回角度
- return angle
- }
- /**
- * 震屏效果
- * @param duration 震屏时间
- */
- public shakeEffect(
- duration: number,
- node: cc.Node,
- origin: cc.Vec2,
- callBack?: Function,
- bgNode?: cc.Node,
- isShakeX = false,
- random: number = 5,
- ) {
- node.setPosition(origin)
- const speed = 0.02
- const action = []
- let num = duration / speed
- if (num > 10) {
- num = 10
- }
- let originScale = 1
- if (bgNode) {
- originScale = bgNode.scale
- bgNode.scale = originScale * (1 + 0.1)
- }
- for (let i = 0; i < num; i++) {
- let randomX = 0
- if (isShakeX) {
- randomX = Math.randomRangeInt(-random, random)
- }
- const randomY = Math.randomRangeInt(-random, random)
- action.push(cc.moveTo(speed, origin.sub(cc.v2(randomX * node.scale, randomY * node.scale))))
- }
- const shake = node.runAction(cc.repeatForever(cc.sequence(action)))
- setTimeout(() => {
- if (cc.isValid(node)) {
- node.stopAction(shake)
- node.setPosition(origin)
- if (bgNode) {
- bgNode.scale = originScale
- }
- callBack && callBack()
- }
- }, duration * 1000)
- }
- public capture() {
- // REAL_WIDTH REAL_HEIGHT 可能为小数向下取整避免有作为下标访问数组会数据错位
- const width = Math.floor(ConstValue.REAL_HEIGHT)
- const height = Math.floor(ConstValue.REAL_WIDTH)
- const node = new cc.Node()
- node.parent = cc.director.getScene()
- node.setPosition(width / 2, height / 2)
- const camera = node.addComponent(cc.Camera)
- const texture = new cc.RenderTexture()
- const gl = cc.game['_renderContext']
- texture.initWithSize(width, height, gl.STENCIL_INDEX8)
- camera.targetTexture = texture
- camera.render(cc.Canvas.instance.node)
- camera.enabled = false
- const data = texture.readPixels()
- const picData = new Uint8Array(width * height * 4)
- const rowBytes = width * 4
- for (let row = 0; row < height; row++) {
- const srow = height - 1 - row
- const start = srow * width * 4
- const reStart = row * width * 4
- for (let i = 0; i < rowBytes; i++) {
- picData[reStart + i] = data[start + i]
- }
- }
- camera.targetTexture = null
- node.destroy()
- texture.initWithData(picData, cc.Texture2D.PixelFormat.RGBA8888, width, height)
- const spriteFrame = new cc.SpriteFrame()
- spriteFrame.setTexture(texture)
- return spriteFrame
- }
- public getBundleAsync(name) {
- return new Promise((resolve: (bundle: cc.AssetManager.Bundle) => void, reject) => {
- let callFuc = (err, bundle) => {
- if (err) {
- console.error('loadBundle error name:', name)
- reject(null)
- } else {
- resolve(bundle)
- }
- }
- cc.assetManager.loadBundle(name, callFuc)
- })
- }
- /**
- *
- * 返回节点在世界坐标系下的对齐轴向的包围盒(AABB)不包含子节点的世界边框
- *
- * @param {节点} node节点
- */
- getBoundingBoxToWorld(node: any): cc.Rect {
- let w_n: number = node._contentSize.width
- let h_n: number = node._contentSize.height
- let rect_o = cc.rect(-node._anchorPoint.x * w_n, -node._anchorPoint.y * h_n, w_n, h_n)
- node._calculWorldMatrix()
- rect_o.transformMat4(rect_o, node._worldMatrix)
- return rect_o
- }
- /**
- *
- * 节点是否包含子节点
- *
- * @param {节点1} node1 容器判断节点
- * @param {节点2} node2 拖动节点
- */
- contains(node1: cc.Node, node2: cc.Node) {
- // 判断node2的中心点0,0是否在node1内
- return this.getBoundingBoxToWorld(node1).contains(node2.convertToWorldSpaceAR(cc.v2(0, 0)))
- }
- /**
- *
- * 节点是否包含子节点
- *
- * @param {节点1} node1
- * @param {世界坐标} p
- */
- containsP(node: cc.Node, p: cc.Vec3) {
- return this.getBoundingBoxToWorld(node).contains(cc.v2(p.x, p.y))
- }
- /**
- * 获取pos应该对应的node
- * @param {节点} nodes
- * @param {世界坐标} position
- */
- findNodeByPosition(nodes, position) {
- for (let iNode of nodes) {
- if (this.containsP(iNode, position) && iNode.active) {
- return iNode
- }
- }
- return null
- }
- setComponentByObj(component, obj) {
- for (let key in obj) {
- component[key] = obj[key]
- }
- }
- isEditorScene() {
- return cc.director.getScene().name == 'Editor'
- }
- drawLine(graphics, touches) {
- // 最小的移动距离
- const MIN_POINT_DISTANCE = 1
- // 从0开始移动1
- graphics.moveTo(touches[0].x, touches[0].y)
- // 从1开始移动n
- let lastIndex = 0
- for (let i = 1, l = touches.length; i < l; i++) {
- // 向量减法,并返回新结果
- if (touches[i].sub(touches[lastIndex]).mag() < MIN_POINT_DISTANCE) {
- continue
- }
- lastIndex = i
- // 画线
- graphics.lineTo(touches[i].x, touches[i].y)
- }
- graphics.stroke()
- }
- addBtnClickEvent(btnNode, fucName, target, componentName) {
- if (btnNode) {
- let button = btnNode.getComponent(cc.Button)
- if (button && button.clickEvents.length == 0) {
- let clickEventHandler = new cc.Component.EventHandler()
- clickEventHandler.target = target
- clickEventHandler.component = componentName
- clickEventHandler.handler = fucName
- button.clickEvents.push(clickEventHandler)
- }
- }
- }
- instantChildren(origin, num, parent?): cc.Node[] {
- let nodes = []
- if (!parent) parent = origin.parent
- for (let i = 0; i < num; i++) {
- let node = parent.children[i]
- if (!node) {
- node = cc.instantiate(origin)
- node.parent = parent
- }
- node.active = true
- nodes.push(node)
- }
- for (let i = num; i < parent.children.length; i++) {
- let node = parent.children[i]
- if (node) {
- node.active = false
- }
- }
- return nodes
- }
- getCirclePoints(r, pos, count, randomScope) {
- let points = []
- let radians = (Math.PI / 180) * Math.round(360 / count)
- for (let i = 0; i < count; i++) {
- let x = pos.x + r * Math.sin(radians * i)
- let y = pos.y + r * Math.cos(radians * i)
- points.unshift(cc.v3(x + (Math.random() - 0.5) * randomScope, y + (Math.random() - 0.5) * randomScope, 0))
- }
- return points
- }
- circleFlyNodes(
- nodes: cc.Node[],
- parent: cc.Node,
- startPos: cc.Vec3,
- toPos: cc.Vec3,
- nodeFinishCb: Function,
- finishCb: Function,
- ) {
- let circlePoints = this.getCirclePoints(60, startPos, nodes.length, 40)
- circlePoints.forEach((value, index) => {
- let tmp = nodes[index]
- tmp.parent = parent
- tmp.zIndex = 9999
- tmp.active = true
- tmp.position = startPos
- tmp.scale = 0.5
- let bezier = []
- for (let i = 0; i < 3; i++) {
- if (i == 2) {
- bezier.push(toPos)
- } else {
- bezier.push(cc.v2(Math.randomRangeInt(-400, 400), Math.randomRangeInt(-200, 200)))
- }
- }
- let action = cc.sequence(
- cc.moveTo(0.6, value),
- cc.delayTime(index * 0.03),
- cc.bezierTo(1, bezier).easing(cc.easeIn(3.0)),
- cc.callFunc(() => {
- if (cc.isValid(tmp)) {
- tmp.parent = null
- if (nodeFinishCb) {
- nodeFinishCb(tmp)
- } else {
- tmp.destroy()
- }
- }
- if (index == circlePoints.length - 1) {
- finishCb && finishCb()
- }
- }),
- )
- cc.tween(tmp).then(action).start()
- })
- }
- /**
- * 屏蔽多点触摸
- */
- private canTouch = true
- public cannotTouch() {
- if (this.canTouch) {
- this.canTouch = false
- setTimeout(() => {
- this.canTouch = true
- }, 100)
- return false
- }
- return true
- }
- editorLoadSync(url) {
- if (!CC_EDITOR) return
- let uuid = Editor.assetdb.remote.urlToUuid('db://assets/' + url)
- return new Promise((resolve: (asset) => void, reject) => {
- cc.assetManager.loadAny({uuid}, (err, asset) => {
- if (err) {
- resolve(null)
- } else {
- resolve(asset)
- }
- })
- })
- }
- editorLoadSprite(url, node, childUrl?: string) {
- if (!CC_EDITOR) return
- ccUtils.editorLoadSync(url + '.png' + url.substring(url.lastIndexOf('/'))).then(spriteFrame => {
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- let sprite = node.getComponent(cc.Sprite)
- if (sprite) sprite.spriteFrame = spriteFrame
- })
- }
- setPos(node, position: cc.Vec2) {
- node.x = position.x
- node.y = position.y
- }
- getPos(node) {
- return cc.v2(node.x, node.y)
- }
- resetAniNode(node, pos?: cc.Vec2) {
- node.opacity = 255
- node.angle = 0
- node.stopAllActions()
- if (pos) this.setPos(node, pos)
- }
- deepCopy(obj: any): any {
- const newobj: any = Array.isArray(obj) ? [] : {}
- for (const arr in obj) {
- if (typeof obj[arr] === 'object' && obj[arr] !== null) {
- newobj[arr] = this.deepCopy(obj[arr])
- } else {
- newobj[arr] = obj[arr]
- }
- }
- return newobj
- }
- getPosAngle(x1, y1, x2, y2) {
- // 直角的边长
- let x = Math.abs(x1 - x2)
- let y = Math.abs(y1 - y2)
- let z = Math.sqrt(x * x + y * y)
- let angle = Math.round((Math.asin(y / z) / Math.PI) * 180)
- if (y2 > y1 && x2 < x1) {
- angle = 180 - angle
- } else if (y2 < y1 && x2 < x1) {
- angle = 180 + angle
- } else if (y2 < y1 && x2 > x1) {
- angle = 360 - angle
- } else if (y2 == y1 && x2 > x1) {
- angle = 0
- } else if (y2 == y1 && x2 < x1) {
- angle = 180
- } else if (y2 > y1 && x2 == x1) {
- angle = 90
- } else if (y2 < y1 && x2 == x1) {
- angle = 270
- }
- return angle
- }
- tweenFloat(
- from: number,
- to: number,
- duration: number,
- onUpdate: (t: number) => void,
- onComplete?: Function,
- autoStart: boolean = true,
- ) {
- let o: Record<string, number> = {_value: from}
- Object.defineProperty(o, 'value', {
- get: () => o._value,
- set: (v: number) => {
- o._value = v
- onUpdate && onUpdate(o._value)
- },
- })
- let tween = cc.tween(o).to(duration, {value: to}).call(onComplete)
- if (autoStart) {
- tween.start()
- }
- return tween
- }
- generateAttackPoints(r, n, isLeft, repeat) {
- // 计算每个角度的间隔
- let angleStep = 90 / n
- // 存储点的坐标
- let points = []
- // 计算每个点的坐标
- for (let i = -45; i <= 45; i += angleStep) {
- // 将角度转换为弧度
- let radians = (i * Math.PI) / 180
- // 计算当前点的 x 和 y 坐标
- let x = +(r * Math.cos(radians)).toFixed(1)
- let y = +(r * Math.sin(radians)).toFixed(1)
- x = isLeft ? -x : x
- // 将点的坐标添加到数组中
- points.push({x, y})
- }
- points.sort((a, b) => {
- if (isLeft) {
- return a.x - b.x
- } else {
- return b.x - a.x
- }
- })
- for (let i = 0; i < repeat; i++) {
- points = points.concat(points)
- }
- return points
- }
- isEmpty(value: any): boolean {
- if (value === null || value === undefined) {
- return true
- }
- // 判断是否是字符串
- if (typeof value === 'string' && value.trim() === '') {
- return true
- }
- // 判断是否是数组或对象,长度为 0 则为空
- if (Array.isArray(value) && value.length === 0) {
- return true
- }
- if (typeof value === 'object' && Object.keys(value).length === 0) {
- return true
- }
- return false
- }
- //初始化进度条
- initProgressBar(node: cc.Node, progress: number, needSum: number, childUrl?: string) {
- this.setProgress(progress / needSum, node)
- //进度条标有进度
- if (childUrl != null) {
- ccUtils.setLabel(progress + '/' + needSum, node, childUrl)
- }
- }
- getAllUrlParams(url) {
- // 获取 URL 中的查询参数部分
- let queryString = url.split('?')[1]
- // 定义一个对象来存储参数
- let params = {}
- if (!queryString) return params
- // 分割查询参数,以 '&' 符号分隔
- let queryParams = queryString.split('&')
- // 遍历每个参数,并将其解析到 params 对象中
- queryParams.forEach(param => {
- // 分割键值对,以 '=' 符号分隔
- let keyValue = param.split('=')
- let key = decodeURIComponent(keyValue[0]) // 解码键
- let value = decodeURIComponent(keyValue[1] || '') // 解码值(默认为空字符串)
- // 如果 params 对象中已经存在相同的键,则将值转换为数组
- if (params[key]) {
- if (Array.isArray(params[key])) {
- params[key].push(value)
- } else {
- params[key] = [params[key], value]
- }
- } else {
- params[key] = value
- }
- })
- return params
- }
- //显示呼吸灯效果
- showEffectsBLN(isShow: boolean, node: cc.Node, childUrl?: string, time?: number) {
- if (childUrl) {
- node = cc.find(childUrl, node)
- }
- let hz = 0.75
- if (time) hz = time
- if (!node) return
- node.active = true
- if (node['effect'] == isShow) return
- node['effect'] = isShow
- let t = cc.tween
- node.opacity = 0
- node.stopAllActions()
- if (!isShow) {
- node.opacity = 0
- return
- }
- let showEffect = (tmpNode: cc.Node) => {
- t(tmpNode)
- .then(t().to(hz, {opacity: 255}))
- .call(() => {
- isShow ? hideEffect(tmpNode) : (node.opacity = 0)
- })
- .start()
- }
- let hideEffect = (tmpNode: cc.Node) => {
- t(tmpNode)
- .then(t().to(hz, {opacity: 0}))
- .call(() => {
- isShow ? showEffect(tmpNode) : (node.opacity = 0)
- })
- .start()
- }
- showEffect(node)
- }
- }
- export const ccUtils = new CCUtils()
|