123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- 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<SkillBase> = 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<SkillBase> = [];
- 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};
- }
- }
- }
|