/** * 跟随者 */ import CMath from "../../../util/CMath"; import FSprite,{SpriteActionType} from "./FSprite"; const {ccclass, property} = cc._decorator; @ccclass export default class PSprite extends FSprite { /** * 是否跟随 */ private isFollow = false; /** * 前面的 */ public inFront: FSprite; public zt:boolean = false//暂停 /** * 行走路径记录 */ private PosList: Array = []; private RecordGap = 3; //目标移动多远记录一次距离 private StopCount = 7; //记录还剩多少时停止移动 private isFloowStart = false;//是否开始跟随 /** * 设置领队 * @param sprite */ public setLeader(sprite: FSprite) { this.inFront = sprite; this.node.x = this.inFront.node.x this.node.y = this.inFront.node.y this.isFollow = true; } /** * 开始跟随 */ public startFollow() { if (this.isFloowStart) { return; } if (!this.isFollow) { this.setShooting(false); this.isFloowStart = true; this.PosList = []; let p1 = this.ff.mainSprite.node.getPosition(); let pos = cc.v2(); pos.x = p1.x; pos.y = p1.y; this.playAction(SpriteActionType.run, true); cc.tween(this.node).sequence( cc.moveTo(0.5, pos), cc.callFunc(() => { this.playAction(SpriteActionType.stand, true); this.tmpActionType = null; this.isFollow = true; this.isFloowStart = false; }) ).start() } } /** * 结束跟随 */ public stopFollow() { this.playAction(SpriteActionType.stand, true); this.isFollow = false; } public update(dt) { if(this.zt){ return } if (this.gamePause) { return; } if(!this.inFront){ return; } if (this.PosList.length > 0) { //跟随 if (this.isFollow) { //添加当前Target位置 let fp = this.inFront.node.getPosition(); let lp = this.PosList[this.PosList.length - 1]; let distance = cc.Vec2.distance(fp, lp); if(distance > this.RecordGap){ this.PosList.push(fp); } if (this.PosList.length > this.StopCount) { let p0 = this.node.getPosition(); let p1 = this.PosList[0]; if (this.updateSpineF(p0, p1)) { // cc.log('切换了动作'); this.tmpActionType = null; } this.moveTo(p1, dt); this.isWalk = true; this.playAction(SpriteActionType.run, true); } else { this.isWalk = this.inFront.isWalk; if (this.isWalk) { this.playAction(SpriteActionType.run, true); } else { this.playAction(SpriteActionType.stand, true); } } //清除已经到达的点 while (this.PosList.length > 0) { let distance = cc.Vec2.distance(this.node.getPosition(), this.PosList[0]); if (distance <= this.RecordGap) { this.PosList.shift(); } else { break; } } } else { this.tmpActionType = null; if (!this.isFloowStart) { this.updateMove(dt) } } } else { if (!this.isFloowStart) { this.PosList.push(this.inFront.node.getPosition()); } } } /** * 更新跟随角色的方向 */ private updateSpineF(p1: cc.Vec2, p2: cc.Vec2): boolean { let tmpSpine = this.spine; //计算弧度 // let angle = Math.floor(CMath.getAngle(p1, p2) * (180 / Math.PI)); // this.updateWeaponAngle(angle); let x0 = Math.floor(p1.x); let x1 = Math.floor(p2.x); if (Math.abs(x0-x1) < 2) {//不改变方向 } else if (x0 - x1 > 0) { this.setLR(-1); } else { this.setLR(1); } if (tmpSpine == this.spine) { return false; } else { if (tmpSpine) { tmpSpine.node.active = false; } this.spine.node.active = true; } return true; } /** * 设置坐标和方向 */ public setPosition(pos) { this.node.setPosition(pos); this.PosList = []; } public removeSelf() { this.playAction2(SpriteActionType.dead, false, () => { //替换为幽灵 this.setGhost(); }); } /** * 死亡后设置为幽灵 */ private setGhost() { cc.resources.load('prefab/monter/ghost', cc.Prefab, (err, prefab: cc.Prefab) => { if (err) { cc.error(err); } else { let node = cc.instantiate(prefab); let spine = node.getComponent(sp.Skeleton); node.parent = this.node.getChildByName('juese01'); this.spine.node.active = false; this.spine = spine; for (let i = 0; i < this.mPanels.length; i++) { const element = this.mPanels[i]; element.setClose() } } }); } /** * 目标位置的切线方向移动 * @param target */ public tangentMove(target:cc.Node){ let p1 = this.node.getPosition(); let p2 = target.getPosition(); let tan = CMath.getAngle(p1,p2); let angle = tan*180/Math.PI; let rand = CMath.getRandom(0,1); if(rand > 0){ angle += 90 }else{ angle -= 90; } if(angle > 180){ angle -= 180; } if(angle < -180){ angle += 180; } let dir = this.getDir(angle); cc.tween(this.node).sequence( cc.delayTime(0.5), cc.callFunc(()=>{ this.setDir(dir); }) ).start(); } private getDir(angle){ if(angle >= -30 && angle < 30){ return {x:1.4,y:0} }else if(angle >= 30 && angle < 60){ return {x:1,y:1} }else if(angle >= 60 && angle < 120){ return {x:0,y:1.4} }else if(angle >= 120 && angle < 150){ return {x:-1,y:1} }else if(angle >= 150 && angle < 180){ return {x:-1.4,y:0} }else if(angle >= -180 && angle < -150){ return {x:-1.4,y:0} }else if(angle >= -150 && angle < -120){ return {x:-1,y:-1} }else if(angle >= -120 && angle < -60){ return {x:0,y:-1.4} }else if(angle >= -60 && angle < -30){ return {x:1,y:-1} } } }