Cocos 距离判断和小兵的攻击判定

 最近在学习cocos 和ts 遇到的问题和如何解决问题都会发表博客记录一下。

距离判断

let j = new Vec2(this.target.position.x - this.node.position.x, this.target.position.y - this.node.position.y);

let dis = Math.sqrt(j.x * j.x + j.y * j.y)

枚举的外部类型定义:

@property({type:Enum(HitAction)})   //外部定义枚举类型


import { _decorator, Component, debug, Enum, find, Node, Vec2, Vec3 } from 'cc';
import { HitAction } from '../Struct/GameStruct';
const { ccclass, property } = _decorator;

@ccclass('EnemyRole')
export class EnemyRole extends Component {

    target: Node;   //目标
    speed: number = 20;   //速度
    @property({type:Enum(HitAction)})   //外部定义枚举类型
    hitAction: HitAction|null = null;
    canHit: boolean = true;
    start() {
        this.target = find('Canvas/Target');
        // console.log(this.target.name);
        // console.log(this.target.position);
        this.hitAction = HitAction.one_xiaoBing;
        //this.Attack();
    }

    update(deltaTime: number) {
        // [4]
        this.node.translate(new Vec3(0, deltaTime * this.speed, 0));

        let j = new Vec2(this.target.position.x - this.node.position.x, this.target.position.y - this.node.position.y);
        let dis = Math.sqrt(j.x * j.x + j.y * j.y)
        // console.log("距离=" + dis);
        //枚举判断是哪种兵
        //移动逻辑
        switch (this.hitAction) {
            case HitAction.one_xiaoBing:
            case HitAction.one_QiShi:
            case HitAction.one_DunBing:
                if (dis <= 150) {
                    this.speed = 0;

                    //开启攻击防御塔行为
                    if (this.canHit) {
                        this.Attack();
                        this.canHit = false;
                    }

                }
                break;
            case HitAction.one_SheShou:
            case HitAction.one_PaoBing:
                if (dis <= 200) {
                    this.speed = 0;
                    //开启攻击防御塔行为
                    if (this.canHit) {
                        this.Attack();
                        this.canHit = false;
                    }
                }
                break;
            default:
                break;
        }
    }
//攻击逻辑
    Attack() {
        console.log("进");
        if (this.canHit) {
            switch (this.hitAction) {
                case HitAction.one_xiaoBing:
                case HitAction.one_QiShi:
                case HitAction.one_DunBing:
                    //每隔2秒执行一次
                    this.schedule(function () {
                        console.log("进gong!!!!!!!!!!!!!!");
                    }, 2);
                    break;
                case HitAction.one_SheShou:
                case HitAction.one_PaoBing:
                    this.schedule(function () {
                        console.log("进gong!!!!!!!!!!!!!!");
                    }, 3);
                    break;
                default:
                    break;
            }
        }
    }
}

数据存储:


import { _decorator, Component, Node, sys } from 'cc';
import BaseSingleClass from '../Single/BaseSingleClass';
const { ccclass, property } = _decorator;

//用于存储数据
@ccclass('JsonMgr')
export class JsonMgr<T> extends BaseSingleClass {

    start () {
        
    }
    //数据保存
    SetJson(name:string,item?:T){
        let str=JSON.stringify(item);  //把要改变的泛型转换为字符串(序列化)
        sys.localStorage.setItem(name,str);   //保存数据
       }
       
    SetJsonOne(name:string,str:string){
        sys.localStorage.setItem(name,str);   //保存数据
    }   
    // GetJson(name:string){
    //     sys.localStorage.getItem(name);   //获取数据
    // }
   //获取数据, 获取到Json内的值(对象)
   //let s=Object.assign(new Person(),JSON.parse(YYYY.bbb)); 
   //console.log(s.id);
   //console.log(s.age);
   //console.log(s.name);
}
export default class BaseSingleClass{
    public static getInstance<T extends{}>(this:new()=>T) :T{
        if(!(<any>this).instance)
        {
            (<any>this).instance=new this();
        }
        return (<any>this).instance
    }

    public static recycle():void{
        (<any>this).instance=null
    }
}

根据修改需求,先对小兵进行进攻,在进攻防御塔


import { _decorator, Component, Enum, find, Node, Vec2, Vec3 } from 'cc';
import { HitAction, IsTarget, IsTargetFriend, friendTimes } from '../Struct/GameStruct';
import { EnemyRole } from './EnemyRole';
import { SingleMgr } from '../Managers/SingleMgr';
const { ccclass, property } = _decorator;


@ccclass('FriendRole')
export class FriendRole extends Component {

    target: Node;   //目标
    speed: number = 30;   //行径速度
    @property({ type: Enum(HitAction) })   //外部定义枚举类型
    hitAction: HitAction | null = null;

    @property({ type: Enum(IsTargetFriend) })   //判断生成友军还是敌人
    public isTargetfriend: IsTargetFriend | null = null;

    @property({ type: Enum(IsTarget) })   //判断进攻敌人还是主城
    public isTarget: IsTarget | null = null;
    canHit: boolean = true;

    // 身体区域的坐标点
    private _bodyPolygonPoints: Array<Vec2> = [];

    private _timeID: number = 0;
    // 获取碰撞区域
    getPlayerCollider(): Array<Vec2> {
        return this._bodyPolygonPoints;
    }

    start() {
        this.isTarget = IsTarget.bigEnemy;    //初始目标为防御塔
        this.FindTarget();  //第一次初始化目标

    }

    update(deltaTime: number) {
        this.EnemyOrFriend();//持续更新,判断场景内是否有敌人进行,攻击目标的切换
        //看向防御塔位置
        this.LookIt();
        this.node.translate(new Vec3(0, deltaTime * this.speed, 0));    //移动

        //this.DisTance();

    }
    //攻击逻辑
    Attack() {
        console.log("friend进");
        if (this.canHit) {
            switch (this.hitAction) {
                case HitAction.one_xiaoBing:
                case HitAction.one_QiShi:
                case HitAction.one_DunBing:
                    //每隔2秒执行一次
                    this.schedule(friendTimes, 2);    //v是
                    break;
                case HitAction.one_SheShou:
                case HitAction.one_PaoBing:
                    //每隔3秒执行一次
                    this.schedule(function () {
                        console.log("Friend远程进gong!!!!!!!!!!!!!!");
                    }, 3);
                    break;
                default:
                    break;
            }
        }
    }

    //始终看向防御塔(通过目标进行改变)
    LookIt() {
        var dx = this.node.position.x - this.target.position.x;
        var dy = this.node.position.y - this.target.position.y;
        var dir = new Vec2(dx, dy);
        let radian = Math.atan2(dir.y, dir.x);
        var angle = radian / Math.PI * 180;
        this.node.angle = angle + 90;
    }

    //攻击目标的切换转变(防御塔和敌人AI)
    //返回目标的名称
    FindTarget(): Node {
        switch (this.isTarget) {
            case IsTarget.enemy:
                this.target = find('Canvas/enemy');  //敌人
                break;
            case IsTarget.bigEnemy:
                this.target = find('Canvas/Target');    //目标主城
                break;
            default:
                break;
        }
        return this.target;
    }

    //敌人和主城的切换
    EnemyOrFriend() {
        //let targetss= this.FindTarget();
        let n_pos = this.node.position;   //自身位置
        let pGameManager = find("Canvas/enemy"); //身上挂载EnemyRole脚本
        let tGameManager = find('Canvas/Target');
        //敌人存在时
        if (pGameManager) 
        {
            this.isTarget = IsTarget.enemy;
            this.FindTarget();
            let dis = Vec2.distance(n_pos, pGameManager.position);    //目标位置和自身位置之间的距离
            if (dis <= 60) {
                this.speed = 0;
                //进攻逻辑
            }
            else {
                this.speed = 30;
                //跟随进攻逻辑
            }
        }
        else {
            //主城存在时
            if (tGameManager) 
            {
                this.isTarget = IsTarget.bigEnemy;
                this.FindTarget();//查找目标
                //console.log("target叫"+this.target);
                this.speed = 20;
                this.DisTance();    //范围判定
            }
            else {
                //胜利
            }

        }
    }
    //距离判断
    DisTance() {
        //距离判断
        let j = new Vec2(this.target.position.x - this.node.position.x, this.target.position.y - this.node.position.y);
        //console.log()
        let dis = Math.sqrt(j.x * j.x + j.y * j.y)
        //console.log("到"+this.target.name+"距离=" + dis);
        //枚举判断是哪种兵
        //移动逻辑
        switch (this.hitAction) {
            case HitAction.one_xiaoBing:
            case HitAction.one_QiShi:
            case HitAction.one_DunBing:
                if (dis <= 100) {
                    //console.log("进了吗");
                    this.speed = 0;
                    //开启攻击防御塔行为
                    if (this.canHit) {
                        this.Attack();
                        this.canHit = false;
                    }

                }
                break;
            case HitAction.one_SheShou:
            case HitAction.one_PaoBing:
                if (dis <= 120) {
                    this.speed = 0;
                    //开启攻击防御塔行为
                    if (this.canHit) {
                        this.Attack();
                        this.canHit = false;
                    }
                }
                break;
            default:
                break;
        }
    }
}