import { _decorator, CCBoolean, Component, find, instantiate, Label, Node, NodePool, Prefab, sp, tween, UITransform, v3 } from 'cc'; import { UIBase } from 'db://assets/mx/module/ui/UIBase'; import { GBundle, UIID } from '../../game/ConfigRes'; import { zidanScript } from './zidanScript'; import { monsterScript } from './monsterScript'; import { GEvent } from 'db://assets/mx/module/event/GEvent'; import { atgSkill } from './atgSkill'; import MTools from 'db://assets/mx/tools/MTools'; import { atgDoor } from './atgDoor'; const { ccclass, property } = _decorator; @ccclass('gaoyaguo') export class gaoyaguo extends Component { moveDoor: Node = null; menMove: Node = null; Gaozidan: Node = null; gaoyaguoNode: Node = null; gaoyaguo_guo: Node = null; gaoyaguozidanLayer: Node = null; guoEffect: Node = null; guoEffectFire: Node = null; ui_center: Node = null; monsterCore: monsterScript = null; zidanCore: zidanScript = null; monsterLayer: Node = null; gaoyaguoTime: number = 0; gaoyaguospeend = 0.5 gaoyaguoMaxTime = 0.03 zhujueNode: Node = null; qiangNode1: Node = null; qiangNode2: Node = null; quedanNode: Node = null; zhuzhutaiNode: Node = null; zhujueSpine: Node = null zhujueSpineAnimation: string = '待机' isPlayAnim = false jiedianIndex = 1 public static Instance: gaoyaguo = null; zhujueTakeZidanNum = 0 _sGame: boolean = false; isGameOver = false sendZidanTimeFix = 0.1 sendZidanTime = 0 skillMonsterNum = 0 gaoyaguoHieNum = 666 @property(CCBoolean) debugSendZidan: boolean = false; guoNum = 0 onDestroy(): void { } onLoad(): void { gaoyaguo.Instance = this; this.ui_center = this.node.getChildByName('ui_center'); this.menMove = find('menMove', this.ui_center); this.zhujueNode = find('zhandou/主角', this.ui_center); this.qiangNode1 = find('zhandou/主角墙1', this.ui_center); this.qiangNode2 = find('zhandou/主角墙2', this.ui_center); this.quedanNode = find('zhandou/缺弹提示', this.ui_center); this.zhujueSpine = find('zhandou/主角/主角spine', this.ui_center); this.zhuzhutaiNode = find('zhandou/求助字体', this.ui_center); this.gaoyaguoNode = this.ui_center.getChildByName('高压锅'); this.gaoyaguo_guo = this.gaoyaguoNode.getChildByName('锅'); this.gaoyaguozidanLayer = this.gaoyaguoNode.getChildByName('子弹层'); this.monsterCore = this.ui_center.getChildByName('monsterCore').getComponent(monsterScript); this.zidanCore = this.ui_center.getChildByName('zidanCore').getComponent(zidanScript); this.guoEffect = this.gaoyaguo_guo.getChildByName('攻击效果'); this.guoEffectFire = this.gaoyaguo_guo.getChildByName('喷火效果'); this.Gaozidan = this.ui_center.getChildByName('高压锅子弹'); this.guoNum = this.gaoyaguoHieNum//parseInt(this.gaoyaguo_guo.getChildByName('num').getComponent(Label).string); this.gaoyaguo_guo.getChildByName('num').getComponent(Label).string = this.guoNum.toString() this.moveDoor = find('光门蓝5Move', this.menMove); let bg2 = this.ui_center.getChildByName('bg2') this.monsterLayer = bg2.getChildByName('monsterLayer'); //开始游戏 this.gaoyaguoNode.active = true this.ui_center.getChildByName('引导指针').active = true this.startGame() } protected onEnable(): void { GEvent.Ins.on(GEvent.gaoyaguoAttack, this.gaoyaguoAttack, this); GEvent.Ins.on(GEvent.gaoyaguoAttackToPlayer, this.gaoyaguoAttackToPlayer, this); GEvent.Ins.on(GEvent.hitGaoyaguo, this.hitGaoyaguo, this); GEvent.Ins.on(GEvent.hitZhujue, this.hitZhujue, this); } protected onDisable(): void { GEvent.Ins.off(GEvent.gaoyaguoAttack, this.gaoyaguoAttack, this); GEvent.Ins.off(GEvent.gaoyaguoAttackToPlayer, this.gaoyaguoAttackToPlayer, this); GEvent.Ins.off(GEvent.hitGaoyaguo, this.hitGaoyaguo, this); GEvent.Ins.off(GEvent.hitZhujue, this.hitZhujue, this); } hitZhujue(hitCountOrZidan: number, zidanMaybe?: Node) { //子弹数目给主角(每颗子弹单独事件 +1,避免与主角/墙盒多帧重叠时重复累加) const add = typeof hitCountOrZidan === 'number' ? hitCountOrZidan : 1; this.zhujueTakeZidanNum += add; //console.log('hitZhujue++++ this.zhujueTakeZidanNum +++===', add, this.zhujueTakeZidanNum ) this.zhujueNode.getChildByName('zidanNum').active = true let zidanNum = this.zhujueNode.getChildByName('zidanNum').getComponent(Label) zidanNum.string = this.zhujueTakeZidanNum.toString() } hitGaoyaguo(hitCountOrZidan: number | Node, zidanMaybe?: Node) { const hitCount = typeof hitCountOrZidan === 'number' ? hitCountOrZidan : 1; this.guoNum -= hitCount; this.gaoyaguo_guo.getChildByName('num').getComponent(Label).string = this.guoNum.toString(); //从高压锅上掉落子弹,子弹角度随机 ,掉落的位置子弹层的子节点上随机。 //子节点如果上面的子弹如果大于20,就判断掉落的子弹和现有子弹的位置有没有重叠,子弹掉落完成,删除重叠的子弹 for (let i = 0; i < hitCount; i++) { this.dropZidan() } if (!MTools.beforeTimes(110, "hitGaoyaguo")) { tween(this.gaoyaguo_guo) .to(0.1, { scale: v3(1.1, 1.1, 1.1) }) .call(() => { this.gaoyaguo_guo.scale = v3(1, 1, 1) }) .start() this.guoEffect.active = true this.guoEffect.scale = v3(0.1, 0.1, 0.1) tween(this.guoEffect) .to(0.1, { scale: v3(1, 1, 1) }) .call(() => { this.guoEffect.active = false }) .start() this.guoEffectFire.active = true this.guoEffectFire.scale = v3(0.1, 0.1, 0.1) tween(this.guoEffectFire) .to(0.1, { scale: v3(1, 1, 1) }) .call(() => { this.guoEffectFire.active = false }) .start() } if (this.guoNum <= 0) { this.gaoyaguoNode.getChildByName('光门1').active = false this.gaoyaguoNode.getChildByName('光门2').active = false this.gaoyaguoNode.getChildByName('墙4').active = false this.gaoyaguoNode.getChildByName('墙').active = false this.gaoyaguoNode.getChildByName('墙2').active = false this.gaoyaguoNode.getChildByName('墙3').active = false let baozha = this.gaoyaguoNode.getChildByName('爆炸4') this.gaoyaguoNode.getChildByName('锅').active = false baozha.active = true gg.audio.playEffect({ name: '汽水炸弹爆炸', path: 'sound/武器音效/' }); //停止发射子弹 this._sGame = false // this.gaoyaguozidanLayer 移除 for (let i = 0; i < this.gaoyaguozidanLayer.children.length; i++) { let node = this.gaoyaguozidanLayer.children[i] node.destroyAllChildren() } GEvent.Ins.emit(GEvent.gaoyaguoBoom, this.jiedianIndex) this.scheduleOnce(() => { baozha.active = false //进入下一个阶段 this.gaoyaguozidanLayer.active = false //场景向下移动 this.gaoyaguoNode.active = false this.beginMoveScene() }, 0.5) } } dropZidan() { let zidan = instantiate(this.Gaozidan) let findNode = null let allAdd20 = false for (let i = 0; i < this.gaoyaguozidanLayer.children.length; i++) { let node = this.gaoyaguozidanLayer.children[i] if (node.children.length < 30) { findNode = node break } } if (!findNode) { let randomIndex = Math.floor(Math.random() * this.gaoyaguozidanLayer.children.length) findNode = this.gaoyaguozidanLayer.children[randomIndex] allAdd20 = true } findNode.addChild(zidan) let zidanAngle = Math.random() * 360 zidan.worldPosition = this.guoEffect.worldPosition let endPosix = findNode.getComponent(UITransform).contentSize.width / 2 let endPosiy = findNode.getComponent(UITransform).contentSize.height / 2 //-endPosix dao endPosix let randx = MTools.getRandomValue(-endPosix, endPosix) let randy = MTools.getRandomValue(-endPosiy, endPosiy) zidan.active = true tween(zidan) .to(0.5, { x: randx, y: randy, angle: zidanAngle }) .call(() => { zidan.active = true //检测有没有重叠的子弹 if (allAdd20) { this.checkZidanOverlap(findNode, zidan) } }) .start() } checkZidanOverlap(findNode: Node, zidan: Node) { let zidanList = findNode.children for (let i = 0; i < zidanList.length; i++) { let zidanItem = zidanList[i] if (zidanItem.worldPosition.equals(zidan.worldPosition)) { zidanItem.active = false zidanItem.destroy() break } } } private _worldDirToZidanCoreLocalDir(zidanCoreNode: Node, startWorld: any, dirWorld: any) { const parentTrans = zidanCoreNode.getComponent(UITransform); if (!parentTrans) { return dirWorld; } // 将 world 方向转换到 zidanCoreNode 的本地坐标系里(zidanScript.update 用的是 child.position/local 坐标移动) const startLocal = parentTrans.convertToNodeSpaceAR(startWorld); const endLocal = parentTrans.convertToNodeSpaceAR(startWorld.clone().add(dirWorld)); const dirLocal = endLocal.subtract(startLocal); dirLocal.z = 0; if (dirLocal.lengthSqr() < 0.0001) { return v3(0, 1, 0); } dirLocal.normalize(); return dirLocal; } gaoyaguoAttackToPlayer(zidanNum: number, startNode: Node, zidanTakeNumber) { // 创建子弹,子弹方向(门:0=向上,1=朝主角) let zidanNum2 = 1 if (zidanNum == 30) { zidanNum2 = 10 } if (zidanNum == 20) { zidanNum2 = 100 } if (zidanNum == 30 || zidanNum == 20) { zidanNum = zidanNum / 10 } const door = startNode.getComponent(atgDoor); const direction = door?.direction ?? 0; const sourceDoorNumber = door?.doorNumber ?? zidanNum; const zidanCoreNode = this.ui_center.getChildByName('zidanCore'); if (!zidanCoreNode) return; // 子弹在出生点做横向“平铺”偏移,避免完全重叠 const spacing = 36; // 世界坐标间距(按子弹尺寸可调) // 注意:x30/x20 会把 zidanNum 变成 3/2,这里必须用“修正后的 zidanNum”算中心,否则子弹出生点会被偏移到屏幕外 const centerIndex = (zidanNum - 1) / 2; //最多暂时6个子弹 // 主角世界坐标(勿在循环内用 subtract 改写,Vec3.subtract 会 mutate 调用者) const protagonistWorld = direction === 0 ? null : (this.zhujueNode?.worldPosition?.clone() ?? null); //gg.audio.playEffect({ name: '彩虹飞弹发射', path: 'sound/武器音效/' }); for (let i = 0; i < zidanNum; i++) { const zidan = this.zidanCore.getZidan(); zidan.scale = v3(1, 1, 1); const startWorld = startNode.worldPosition.clone(); startWorld.x += (i - centerIndex) * spacing; zidan.active = false zidanCoreNode.addChild(zidan); // 先挂到正确父节点,再设置 worldPosition,避免 reparent 导致世界坐标被改写 zidan.worldPosition = startWorld; const skill = zidan.getComponent(atgSkill); skill.setSkillData(this.zidanCore, zidanNum2); skill.owner = 'enemy'; // 这批子弹由某个门生成,短时间内忽略与该门的碰撞,防止递归触发 // x5 等高倍率门更容易“出生点仍在门碰撞盒内”导致指数递归,忽略帧数加大 skill.setIgnoreDoor(startNode, sourceDoorNumber); this.scheduleOnce(() => { zidan.active = true }, 0.1) // zidanScript.update 用的是 zidanCoreNode 的本地坐标移动,所以这里直接计算“本地方向” let dirLocal = v3(0, 1, 0); if (protagonistWorld) { const parentTrans = zidanCoreNode.getComponent(UITransform); if (parentTrans) { const startLocal = parentTrans.convertToNodeSpaceAR(startWorld); const targetLocal = parentTrans.convertToNodeSpaceAR(protagonistWorld); dirLocal = targetLocal.subtract(startLocal); dirLocal.z = 0; if (dirLocal.lengthSqr() < 0.0001) { dirLocal = v3(0, 1, 0); } else { dirLocal.normalize(); } } } skill.setMoveDir(dirLocal); // 子弹朝向飞行方向(0°=向上) const rawAngle = (Math.atan2(dirLocal.x, dirLocal.y) * 180) / Math.PI; zidan.angle = -rawAngle; } } gaoyaguoAttack(zidanNum: number, startNode: Node) { //创建子弹打高压锅 // console.log('gaoyaguoAttack', zidanNum) let zidanCoreNode = this.ui_center.getChildByName('zidanCore') const door = startNode.getComponent(atgDoor); const sourceDoorNumber = door?.doorNumber ?? zidanNum; // 子弹在出生点做横向“平铺”偏移,避免完全重叠 const spacing = 36; // 世界坐标间距(按子弹尺寸可调) const centerIndex = (zidanNum - 1) / 2; const guoWorldPos = this.gaoyaguo_guo.worldPosition.clone(); //gg.audio.playEffect({ name: '彩虹飞弹发射', path: 'sound/武器音效/' }); for (let i = 0; i < zidanNum; i++) { let zidan = this.zidanCore.getZidan() zidan.scale = v3(1, 1, 1); const startWorld = startNode.worldPosition.clone(); startWorld.x += (i - centerIndex) * spacing; zidanCoreNode.addChild(zidan) // 先挂到正确父节点,再设置 worldPosition,避免 reparent 导致世界坐标被改写 zidan.worldPosition = startWorld const skill = zidan.getComponent(atgSkill); skill.setSkillData(this.zidanCore); // 这批子弹由某个门生成,短时间内忽略与该门的碰撞,防止递归触发 skill.setIgnoreDoor(startNode, sourceDoorNumber >= 5 ? 30 : 18); //计算子弹方向:从子弹出生点指向高压锅(每发单独 clone,避免 Vec3.subtract 污染下一发) const dirWorld = guoWorldPos.clone().subtract(startWorld); dirWorld.z = 0; dirWorld.normalize(); const dirLocal = this._worldDirToZidanCoreLocalDir(zidanCoreNode, startWorld, dirWorld); skill.setMoveDir(dirLocal); // 子弹朝向飞行方向(0°=向上) const rawAngle = (Math.atan2(dirLocal.x, dirLocal.y) * 180) / Math.PI; zidan.angle = -rawAngle; zidan.active = true } } update(dt: number) { if (this.isGameOver) { return } if (this.jiedianIndex == 3 || this.jiedianIndex == 4) { this.sendZidanTime += dt if (this.sendZidanTime >= this.sendZidanTimeFix) { this.sendZidanTime = 0 //发送子弹 this.sendZidan() } } if (!this._sGame) { return; } this.gaoyaguoTime += dt if (this.gaoyaguoTime >= this.gaoyaguoMaxTime) { this.gaoyaguoTime = 0; //高压锅向y轴向下移动 let moveDiry = -this.gaoyaguospeend let posi = this.gaoyaguoNode.position.clone() posi.y += moveDiry this.gaoyaguoNode.setPosition(posi) if (posi.y <= -500) { //游戏结束失败 this.gameoverFail() } } } sendZidan() { // 发射子弹:一次尽量 3 颗(不足则 1 颗),并排间隔 18 // 索敌范围 1000:优先取 monsterLayer 里 y 最小的组节点,再在该组里找离主角最近的怪物 const dbg = this.debugSendZidan; if (dbg) { console.log('[sendZidan] tick', { jiedianIndex: this.jiedianIndex, zhujueTakeZidanNum: this.zhujueTakeZidanNum, monsterGroups: this.monsterLayer?.children?.length ?? -1, zidanCoreChildren: this.ui_center?.getChildByName('zidanCore')?.children?.length ?? -1, }); } if (this.zhujueTakeZidanNum <= 0) { if (dbg) console.log('[sendZidan] 子弹数目不够') //缺弹提示+求助字体 this.quedanNode.active = true this.zhuzhutaiNode.active = true //播放动画一次 if (this.zhujueSpineAnimation != '待机') { this.zhujueSpineAnimation = '待机' this.zhujueSpine.getComponent(sp.Skeleton).setAnimation(0, this.zhujueSpineAnimation, true); } if (!this.isPlayAnim) { this.isPlayAnim = true tween(this.quedanNode) .to(0.1, { scale: v3(0.1, 0.1, 0.1) }) .to(0.5, { scale: v3(0.5, 0.5, 0.5) }) .union() .repeatForever() .start() tween(this.zhuzhutaiNode) .to(0.1, { scale: v3(0.1, 0.1, 0.1) }) .to(0.5, { scale: v3(0.5, 0.5, 0.5) }) .union() .repeatForever() .start() } return }; if (!this.monsterLayer || !this.zhujueNode) { if (dbg) console.log('[sendZidan] fallback: monsterLayer/zhujueNode missing -> shoot up'); } this.quedanNode.active = false this.zhuzhutaiNode.active = false if (this.zhujueSpineAnimation == '待机') { this.zhujueSpineAnimation = '攻击' this.zhujueSpine.getComponent(sp.Skeleton).setAnimation(0, this.zhujueSpineAnimation, true); } const zidanCoreNode = this.ui_center?.getChildByName('zidanCore') ?? null; const parentTrans = zidanCoreNode?.getComponent(UITransform) ?? null; if (!zidanCoreNode || !parentTrans) { if (dbg) console.log('[sendZidan] abort: zidanCoreNode/UITransform missing'); return; } const range = 360; const heroWorld = this.zhujueNode.worldPosition.clone(); // 1) 找到 monsterLayer 中 y 最小的节点(最靠近主角) let groupNode: Node | null = null; let minY = Number.POSITIVE_INFINITY; for (const n of this.monsterLayer.children) { if (!n?.isValid || n.children.length <= 0) continue; const y = n.worldPosition.y; if (y < minY) { minY = y; groupNode = n; } } if (!groupNode) { if (dbg) console.log('[sendZidan] fallback: no monster group -> shoot up'); } // 2) 在该组内找离主角最近的怪物(优先 child,fallback 用组节点) let targetNode: Node | null = null; let bestD2 = range * range + 1; const candidates = groupNode.children.length > 0 ? groupNode.children : [groupNode]; for (const c of candidates) { if (!c?.isValid) continue; if (!c.active) { continue } const p = c.worldPosition; const dx = p.x - heroWorld.x; const dy = p.y - heroWorld.y; const d2 = dx * dx + dy * dy; if (d2 < bestD2) { bestD2 = d2; targetNode = c; } } if (!targetNode) { if (dbg) console.log('[sendZidan] fallback: no target in group -> shoot up'); } // 超出索敌范围不发射,也不扣数 const hasTargetInRange = !!targetNode && bestD2 <= range * range; if (!hasTargetInRange) { if (dbg) console.log('[sendZidan] fallback: target out of range -> shoot up', { bestD2, range2: range * range }); if (this.zhujueSpineAnimation != '待机') { this.zhujueSpineAnimation = '待机' this.zhujueSpine.getComponent(sp.Skeleton).setAnimation(0, this.zhujueSpineAnimation, true); } return; } let fireCount = this.zhujueTakeZidanNum >= 3 ? 3 : 1; // if (this.jiedianIndex == 4) { fireCount = this.zhujueTakeZidanNum >= 6 ? 6 : 1; } const spacing = 36; const centerIndex = (fireCount - 1) / 2; const targetWorld = hasTargetInRange ? targetNode!.worldPosition.clone() : heroWorld.clone().add(v3(0, 1000, 0)); const heroLocalBase = parentTrans.convertToNodeSpaceAR(heroWorld); const targetLocalFixed = parentTrans.convertToNodeSpaceAR(targetWorld); if (dbg) { console.log('[sendZidan] fire', { fireCount, heroWorld: { x: heroWorld.x, y: heroWorld.y }, targetWorld: { x: targetWorld.x, y: targetWorld.y }, targetName: hasTargetInRange ? targetNode!.name : 'fallback_up', groupName: groupNode?.name ?? 'none', }); } //gg.audio.playEffect({ name: '彩虹飞弹发射', path: 'sound/武器音效/' }); for (let i = 0; i < fireCount; i++) { const zidan = this.zidanCore.getZidan(); zidanCoreNode.addChild(zidan); const skill = zidan.getComponent(atgSkill); skill.setSkillData(this.zidanCore, 1); skill.owner = 'player'; // 统一用 zidanCore 本地坐标生成与移动(避免 world 坐标在多层级缩放/移动下产生偏差,导致“只在左边发射/屏外”) const startLocal = heroLocalBase.clone(); startLocal.x += (i - centerIndex) * spacing; // 主角子弹出生点略微前移,避免“贴脸怪物”瞬间命中回收导致肉眼看不到 startLocal.y += 80; zidan.setPosition(startLocal.x, startLocal.y, 0); // 提升到最上层并强制缩放,避免被遮挡/缩放过小 zidan.active = true; zidan.setSiblingIndex(zidanCoreNode.children.length - 1); zidan.scale = v3(0.6, 0.6, 0.6); const dirLocal = targetLocalFixed.clone().subtract(startLocal); dirLocal.z = 0; if (dirLocal.lengthSqr() < 0.0001) { skill.setMoveDir(v3(0, 1, 0)); zidan.angle = 0; } else { dirLocal.normalize(); // 0°=向上;你定义:45=左边,-45=右边 const rawAngle = (Math.atan2(dirLocal.x, dirLocal.y) * 180) / Math.PI; // 原始角度可能出现 ±180(目标在身后),这里强制限制在 [-90, 90],避免子弹反向飞 const clampedAngle = Math.max(-90, Math.min(90, -rawAngle)); const rad = (clampedAngle * Math.PI) / 180; // 约定:0°=向上;+45=左;-45=右(所以 x 要取 -sin) const clampedDirLocal = v3(-Math.sin(rad), Math.cos(rad), 0); // 若 zidanCore(或其父链)做了水平镜像缩放(worldScale.x < 0),本地 X 方向会与世界左右相反,需要修正 const wsx = zidanCoreNode.getWorldScale().x; const signX = wsx === 0 ? 1 : wsx > 0 ? 1 : -1; clampedDirLocal.x *= signX; skill.setMoveDir(clampedDirLocal); zidan.angle = clampedAngle * signX; } if (dbg) console.log('[sendZidan] spawnLocal/dirLocal', { i, startLocal: { x: startLocal.x, y: startLocal.y }, dir: { x: skill.moveDir.x, y: skill.moveDir.y } }); } // 一次性扣除并刷新显示 this.zhujueTakeZidanNum -= fireCount; if (this.zhujueTakeZidanNum < 0) this.zhujueTakeZidanNum = 0; if (dbg) console.log('[sendZidan] after', { remaining: this.zhujueTakeZidanNum }); const zidanNumNode = this.zhujueNode.getChildByName('zidanNum'); if (zidanNumNode) { zidanNumNode.active = true; const lab = zidanNumNode.getComponent(Label); if (lab) lab.string = this.zhujueTakeZidanNum.toString(); } } gameoverFail() { let baozha = this.gaoyaguoNode.getChildByName('爆炸4') this.gaoyaguoNode.getChildByName('锅').active = false this.gaoyaguoNode.getChildByName('光门1').active = false this.gaoyaguoNode.getChildByName('光门2').active = false gg.audio.playEffect({ name: '汽水炸弹爆炸', path: 'sound/武器音效/' }); baozha.active = true this.scheduleOnce(() => { baozha.active = false this.gameover() }, 0.5) console.log('游戏结束失败') this._sGame = false } gameover() { if (this.isGameOver) { return; } this._sGame = false this.isGameOver = true console.log('游戏结束失败') this.node.emit('_onMiniGameEnd', false); } gameoverSuccess() { if (this.isGameOver) { return; } this._sGame = false this.isGameOver = true console.log('游戏结束成功') this.node.emit('_onMiniGameEnd', true); } //发射子弹打高压锅 startGame() { this._sGame = true //this.gaoyaguoNode } beginMoveScene() { let bg1 = this.ui_center.getChildByName('bg1') let bg2 = this.ui_center.getChildByName('bg2') let zhandou = this.ui_center.getChildByName('zhandou') let menMove = this.ui_center.getChildByName('menMove') let scle = 1.1 let scle2 = 1.20 let posiy = bg1.position.y tween(bg1) .to(1, { y: -809, scale: v3(scle, scle, scle) }) .start() let posiy2 = bg2.position.y tween(bg2) .to(1, { y: 554, scale: v3(scle2, scle2, scle2) }) .start() let posiy3 = zhandou.position.y tween(zhandou) .to(1, { y: 113, scale: v3(scle, scle, scle) }) .start() let posiy4 = menMove.position.y tween(menMove) .to(1, { y: -129.5, scale: v3(scle, scle, scle) }) .call(() => { this.jiedianIndex = 3 this.zhujueTakeZidanNum = 0; const zidanNumNode = this.zhujueNode?.getChildByName('zidanNum'); if (zidanNumNode) { zidanNumNode.active = false; const lab = zidanNumNode.getComponent(Label); if (lab) lab.string = '0'; } GEvent.Ins.emit(GEvent.gaoyaguoBoom, this.jiedianIndex) tween(this.moveDoor) .to(3, { x: -270 }) .to(3, { x: 0 }) .to(3, { x: 270 }) .union() .repeatForever() .start() }) .start() } closeView() { this.node.emit('_onMiniGameClose'); } }