import CMath from "../../../../util/CMath"; import FSprite, { SpriteActionType } from "../FSprite"; import SkillBase from "../skill/SkillBase"; /** * 基础AI */ const {ccclass, property} = cc._decorator; /** * 基础AI设定 * 1.范围巡逻 * 2.攻击进入范围内的敌人 * 3.距离超出后脱离战斗 */ @ccclass export default class AIBase extends cc.Component { /** * AI灵敏度 * 发现敌人后多久开始行动 */ @property({ displayName: '灵敏度(毫秒)' }) public AI_CD:number = 1000; /** * 移动速度 */ @property({ displayName: '角色移动速度' }) public speed = 50; /** * 当前AI拥有的全部技能 */ public skills:Array = null; /** * 当前AI控制的精灵 */ public sprite:FSprite; /** * 攻击目标 */ public target:FSprite; /** * 最后一次执行AI事件 */ public AI_Time = 0; /** * 最后一次执行攻击事件 */ public atk_Time = 0; /** * 是否可以释放技能 */ public canSkill = true; onLoad () { this.sprite = this.node.getComponent(FSprite); this.sprite.SPEED_WALK = this.speed; this.skills = this.node.getComponents(SkillBase); } public setTarget(target:FSprite){ if(target != this.target){ this.target = target; } } /** * 查询目标 */ public checkTarget():FSprite{ if(this.target){ if(this.target.isValid && this.target.hp > 0){ }else{ //死亡或者销毁后查询新的目标 this.target = this.sprite.findEnemy(500).sprite; } }else{ this.target = this.sprite.findEnemy(500).sprite; } return this.target; } update (dt) { if(this.sprite && this.sprite.isActive){ if(this.sprite.gamePause){ return; } this.AI(); } } public AI(){ //查询是否有可攻击目标 //查询是否有可用技能 //查询可用技能是否在当前技能攻击范围以内 //超出范围,执行AI移动 //执行巡逻任务 if(!this.canSkill){ return; } let target = this.checkTarget(); if(target){ if(this.skills.length > 0){ let skill:SkillBase = this.checkSkill(target); if(skill){ if(this.speed <= 0){ this.canSkill = false; skill.exe(target,()=>{ this.canSkill = true; // cc.log('技能使用结束 :',skill) }); }else{ let p1 = this.sprite.node.getPosition() let p2 = target.node.getPosition() let dis = CMath.getDistance(p1,p2); if(dis < skill.range){ this.canSkill = false; skill.exe(target,()=>{ this.canSkill = true; // cc.log('技能使用结束 :',skill) }); }else{ this.walk(skill.range); // this.moveToTarget(target) } } } } } // else{ // if(this.AI_Time == 0){ // this.AI_Time = time; // }else if(time - this.AI_Time > this.AI_CD){ // this.AI_Time = time; // this.walk(0); // } // } } /** * 查询可用技能 */ public checkSkill(target:FSprite):SkillBase{ let lists:Array = []; for (let i = 0; i < this.skills.length; i++) { const element = this.skills[i]; if(element.ready()){ lists.push(element); } } if(lists.length <= 0){ return null; }else{ let index = CMath.getRandom(0,lists.length-1); return lists[index]; // let p1 = this.node.getPosition(); // let p2 = target.node.getPosition(); // let dis = cc.Vec2.distance(p1,p2); // let fList = []; // for (let i = 0; i < lists.length; i++) { // const element = lists[i]; // if(dis < element.range){ // fList.push(element); // } // } // if(fList.length <= 0){ // this.moveToTarget(target); // return null; // }else{ // this.sprite.playAction(SpriteActionType.stand,true) // let index = CMath.getRandom(0,fList.length-1); // return fList[index]; // } } } /** * 向目标移动 * @param target */ private moveToTarget(target:FSprite){ this.sprite.playAction(SpriteActionType.move,true) let p1 = target.node.getPosition(); let p2 = this.sprite.node.getPosition(); this.atk_Time = 0; let tmp = { x:0, y:0 } let px1 = p1.x - p2.x; if(Math.abs(px1) < 50){ tmp.x = 0; }else if(px1 > 0){ tmp.x = 1; }else{ tmp.x = -1; } let py1 = p1.y - p2.y; if(Math.abs(py1) < 50){ tmp.y = 0; }else if(py1 > 0){ tmp.y = 1; }else{ tmp.y = -1; } this.sprite.setDir(tmp); } /** * 远程怪物的闲逛 */ public walk(distance){ if(this.speed > 0){ this.canSkill = false; this.sprite.setDir(this.getRandState(distance)); this.sprite.playAction(SpriteActionType.move,true) cc.tween(this).delay(0.5).call(()=>{ this.sprite.setDir({x:0,y:0}); this.sprite.playAction(SpriteActionType.stand,true) }).delay(1).call(()=>{ this.canSkill = true; }).start() }else{ this.canSkill = true; this.sprite.setDir({x:0,y:0}); this.sprite.playAction(SpriteActionType.stand,true) } } public getRandState(distance){ if(this.target && this.target.isValid && this.target.hp > 0){//如果有目标 let p1 = this.target.node.getPosition(); let p2 = this.sprite.node.getPosition(); let dis = CMath.getDistance(p1,p2); if(dis > distance){ let tmp = { x:0, y:0 } let px1 = p1.x - p2.x; if(Math.abs(px1) < 50){ tmp.x = 0; }else if(px1 > 0){ tmp.x = 1; }else{ tmp.x = -1; } let py1 = p1.y - p2.y; if(Math.abs(py1) < 50){ tmp.y = 0; }else if(py1 > 0){ tmp.y = 1; }else{ tmp.y = -1; } return tmp; } // else if(dis < 100){ // let tmp = { // x:0, // y:0 // } // let px1 = p1.x - p2.x; // if(Math.abs(px1) < 50){ // tmp.x = 0; // }else if(px1 > 0){ // tmp.x = -1; // }else{ // tmp.x = 1; // } // let py1 = p1.y - p2.y; // if(Math.abs(py1) < 50){ // tmp.y = 0; // }else if(py1 > 0){ // tmp.y = -1; // }else{ // tmp.y = 1; // } // return tmp; // } } let rand = CMath.getRandom(1,80); if(rand < 10){ return {x:1,y:0}; }else if(rand < 20){ return {x:1,y:1}; }else if(rand < 30){ return {x:1,y:-1}; }else if(rand < 40){ return {x:0,y:1}; }else if(rand < 50){ return {x:0,y:-1}; }else if(rand < 60){ return {x:-1,y:0}; }else if(rand < 70){ return {x:-1,y:1}; }else{ return {x:-1,y:1}; } } }