import { _decorator, Component, EventTouch, Node, Tween, tween, UITransform, v3, Vec2, Vec3 } from 'cc'; import { gaoyaguo } from './gaoyaguo'; import { atgSkill } from './atgSkill'; import { zidanScript } from './zidanScript'; import { GEvent } from 'db://assets/mx/module/event/GEvent'; const { ccclass, property } = _decorator; @ccclass('weaponMove') export class weaponMove extends Component { @property(Node) mainNode: Node = null; yindaoNode: Node = null; zidanPosiNode: Node = null; paoguanNode: Node = null; kaihuaNode: Node = null; startTouchPos : Vec3 = v3(0, 0, 0); // 移动灵敏度 sensitivity: number = 1.1; private rightX: number = 260 private leftX: number = -260 private initialY: number =-530; //发射间隔 shootInterval: number = 0.1; //子弹速度 bulletSpeed: number = 500; isKaihuo: boolean = false; _dt: number = 0; zidanCoreNode: Node = null; curJieduanIndex = 1; //当前阶段索引 startGame: boolean = false; endPosi:Vec2 = null onDestroy(){ this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this); this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this); this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this); GEvent.Ins.off(GEvent.gaoyaguoBoom, this.onGaoyaguoBoom, this); // // 允许全屏瞄准(第二阶段) // this.mainNode?.off(Node.EventType.TOUCH_START, this.onAimTouchStart, this); // this.mainNode?.off(Node.EventType.TOUCH_MOVE, this.onAimTouchMove, this); } start() { this.yindaoNode = this.mainNode.getChildByName('ui_center').getChildByName('引导指针'); this.zidanPosiNode = this.node.getChildByName('zidanPosiNode'); this.paoguanNode = this.node.getChildByName('paoguanNode'); this.kaihuaNode = this.node.getChildByName('kaihuaNode'); this.zidanCoreNode = this.mainNode.getChildByName('ui_center').getChildByName('zidanCore'); //注册触摸移动事件 this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this); this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this); this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this); GEvent.Ins.on(GEvent.gaoyaguoBoom, this.onGaoyaguoBoom, this); // // 第二阶段需要“点屏幕任意位置”来改变子弹方向 // this.mainNode.on(Node.EventType.TOUCH_START, this.onAimTouchStart, this); // this.mainNode.on(Node.EventType.TOUCH_MOVE, this.onAimTouchMove, this); //箭头转方向 -30-30度 tween(this.yindaoNode) .to(1,{angle:30}) .to(1,{angle:-30}) .union() .repeatForever() .start() } onGaoyaguoBoom(index: number){ this.startGame = false this.isKaihuo = false this.kaihuaNode.active = false //this.paoguanNode.active = false Tween.stopAllByTarget(this.kaihuaNode); Tween.stopAllByTarget(this.paoguanNode); this.curJieduanIndex = index if(this.curJieduanIndex == 3){ this.startGame = true //this.shootInterval = 1 } } update(deltaTime: number) { if(gaoyaguo.Instance.isGameOver){ return } if(!this.startGame ){ return } //发射子弹 this._dt += deltaTime; if(this._dt >= this.shootInterval){ this._dt = 0; if(this.curJieduanIndex == 2){ this.shootBullet2(); }else{ this.shootBullet(); } } } shootBullet(){ gg.audio.playEffect({ name: '彩虹飞弹发射', path: 'sound/武器音效/' }); let zidan = this.mainNode.getComponent(gaoyaguo).zidanCore.getZidan(); this.zidanCoreNode.addChild(zidan); zidan.worldPosition = this.zidanPosiNode.worldPosition; zidan.angle = 0; zidan.scale = v3(1,1,1); const skill = zidan.getComponent(atgSkill); skill.setSkillData(this.zidanCoreNode.getComponent(zidanScript)); skill.setMoveDir(v3(0, 1, 0)); if(this.isKaihuo){ return; } this.kaihuoAni() } shootBullet2(){ gg.audio.playEffect({ name: '彩虹飞弹发射', path: 'sound/武器音效/' }); this.kaihuoAni() const zidan = this.mainNode.getComponent(gaoyaguo).zidanCore.getZidan(); this.zidanCoreNode.addChild(zidan); zidan.worldPosition = this.zidanPosiNode.worldPosition; zidan.scale = v3(1,1,1); // 按点击位置决定方向(你点哪就往哪飞) const parentTrans = this.zidanCoreNode.getComponent(UITransform); if (!parentTrans || !this.endPosi) { const skill = zidan.getComponent(atgSkill); skill.setSkillData(this.zidanCoreNode.getComponent(zidanScript)); skill.setMoveDir(v3(0, 1, 0)); return; } // getUILocation() 在本项目里可直接当作 UI 世界坐标使用(与 getBoundingBoxToWorld 匹配) const startWorld = zidan.worldPosition.clone(); const targetWorld = v3(this.endPosi.x, this.endPosi.y, startWorld.z); const dirWorld = targetWorld.subtract(startWorld); dirWorld.z = 0; dirWorld.normalize(); // 把 world 方向转换到 zidanCoreNode 的本地坐标系里移动 const startLocal = parentTrans.convertToNodeSpaceAR(startWorld); const endLocal = parentTrans.convertToNodeSpaceAR(startWorld.clone().add(dirWorld)); const dirLocal = endLocal.subtract(startLocal); dirLocal.z = 0; dirLocal.normalize(); // 限制角度在箭头范围内(-30 ~ 30,0°=向上) const rawAngle = (Math.atan2(dirLocal.x, dirLocal.y) * 180) / Math.PI; const clampedAngle = Math.max(-30, Math.min(30, rawAngle)); const rad = (clampedAngle * Math.PI) / 180; const clampedDirLocal = v3(Math.sin(rad), Math.cos(rad), 0); const skill = zidan.getComponent(atgSkill); skill.setSkillData(this.zidanCoreNode.getComponent(zidanScript)); skill.setMoveDir(clampedDirLocal); // 子弹外观也跟着旋转(0°=向上)。注意:Creator 的 angle 方向与数学 atan2 可能相反 zidan.angle = -clampedAngle; } kaihuoAni(){ if(this.isKaihuo){ return; } this.isKaihuo = true this.kaihuaNode.active = true this.paoguanNode.active = true tween(this.kaihuaNode) .to(0.05,{scale:v3(0.1,0.1,0.1)}) .to(0.05,{scale:v3(1.3,1.3,1.3)}) .union() .repeatForever() .start() tween(this.paoguanNode) .to(0.05,{scale:v3(1.1,1.1,1.1)}) .to(0.05,{scale:v3(1,1,1)}) .union() .repeatForever() .start() } onTouchStart(event: EventTouch) { console.log("onTouchStart") if(this.curJieduanIndex == 2){ return } const touchPos = event.getUILocation(); this.startTouchPos = v3(touchPos.x, touchPos.y, 0); if(this.curJieduanIndex == 1){ //第一阶段 //箭头停 Tween.stopAllByTarget(this.yindaoNode); let angle = this.yindaoNode.angle; //发射子弹根据箭头的方向发射子弹 this.curJieduanIndex = 2 gaoyaguo.Instance.jiedianIndex = 2 this.yindaoNode.active = false //子弹的初始位置节点zidan // let endPosi = touchPos // let startNodePosi = this.mainNode.getComponent(gaoyaguo).zidanCore.getZidan().worldPosition.clone(); //子弹顺这个方向发射 this.endPosi = touchPos this.shootBullet2() this.startGame = true } } // onAimTouchStart(event: EventTouch) { // if (this.curJieduanIndex !== 2) return; // this.endPosi = event.getUILocation(); // } // onAimTouchMove(event: EventTouch) { // if (this.curJieduanIndex !== 2) return; // this.endPosi = event.getUILocation(); // } onTouchMove(event: EventTouch) { if(this.curJieduanIndex == 1){ return; } // 获取当前触摸位置 const currentPos = event.getUILocation(); if( this.curJieduanIndex == 2){ this.endPosi = event.getUILocation(); return; } // 计算Y方向的移动距离 const deltaX = currentPos.x - this.startTouchPos.x; // 更新触摸起始参考点(整向量赋值,避免误改只读 Vec3) this.startTouchPos.set(currentPos.x, currentPos.y, 0); let posX = this.node.position.x + deltaX * this.sensitivity if (posX < this.leftX) posX = this.leftX if (posX > this.rightX) posX = this.rightX // 计算新位置(只改变Y坐标,X坐标保持初始值不变) // 应用新位置到玩家 this.node.position = v3(posX, this.initialY, 0); } onTouchEnd(event: EventTouch) { console.log("onTouchEnd") } }