| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 | 
							- import { _decorator, Animation, AnimationClip, Component, find, Node, PhysicsSystem2D, SpriteFrame, Vec2, Vec3 } from 'cc';
 
- import { RoleData } from '../../DataItem/ItemData';
 
- import { resMgr } from '../../Frames/ResourcesMgr';
 
- import { Bullet } from './GameScene/Bullet';
 
- import { LifeBar } from './GameScene/LifeBar';
 
- import { BulletPool } from './GameScene/BulletPool';
 
- import { GameInfo } from '../../GameInfo';
 
- const { ccclass, property } = _decorator;
 
- export enum RoleState {
 
-     Attack,
 
-     Move,
 
-     Idle,
 
-     Die
 
- }
 
- @ccclass('Role')
 
- export class Role extends Component {
 
-     //基础数据
 
-     hp: number = null; //血量
 
-     atk: number = null; //攻击力
 
-     atkLength: number = null; //攻击距离
 
-     moveSpeed: number = null; //移速
 
-     //向左-1 向右1
 
-     direction: number = 1;
 
-     //是否停下
 
-     isStop: boolean = false;
 
-     //攻击目标
 
-     targetNode: Node = null;
 
-     bulletLayer: Node | null = null;
 
-     //战斗系统
 
-     private _attackTimer: number = 0;
 
-     private _attackInterval: number = 3;//攻击间隔
 
-     private currentTarget: Role = null;//当前目标
 
-     //子弹
 
-     private _bullet: Node | null = null;
 
-     private _bulletPool: BulletPool = null;
 
-     //动画管理
 
-     private _animations: Map<RoleState, string> = new Map();
 
-     private _moveFrames: SpriteFrame[] = [];
 
-     private _atkFrames: SpriteFrame[] = [];
 
-     private _idleFrames: SpriteFrame[] = [];
 
-     private _dieFrames: SpriteFrame[] = [];
 
-     private _explodeframes: SpriteFrame[] = [];
 
-     private _bulletFrames: SpriteFrame[] = [];
 
-     private _animation: Animation = null;
 
-     //角色数据
 
-     private _roleData: RoleData = null;
 
-     //状态管理
 
-     _state: RoleState = null;
 
-     init(name: string, pos: Vec3, roleDatas: RoleData[], dir?: number) {
 
-         this._bulletPool = this.node.getComponent(BulletPool);
 
-         this._bulletPool.init();
 
-         this._animation = this.node.getComponent(Animation) || this.node.addComponent(Animation);
 
-         this.direction = dir;
 
-         let whichData: number = -1;
 
-         for (let i = 0; i < roleDatas.length; i++) {
 
-             if (!roleDatas[i]) {
 
-                 console.log(null)
 
-             }
 
-             if (roleDatas[i].imgName === name) {
 
-                 this._roleData = roleDatas[i];
 
-                 whichData = i;
 
-                 break;
 
-             }
 
-         }
 
-         if (whichData != -1) {
 
-             //获取move精灵帧
 
-             this._getFrames(this._roleData.moveCount, this._moveFrames, this._roleData.moveImg, 1);
 
-             //attack
 
-             this._getFrames(this._roleData.atkCount, this._atkFrames, this._roleData.atkImg, 1);
 
-             //idle
 
-             this._getFrames(this._roleData.idleCount, this._idleFrames, this._roleData.idleImg, 1)
 
-             //die
 
-             this._getFrames(this._roleData.dieCount, this._dieFrames, this._roleData.dieImg, 1)
 
-             //动画
 
-             this._collectAni();
 
-             //子弹精灵帧
 
-             this._getFrames(this._roleData.bulletCount, this._bulletFrames, this._roleData.bulletImg, 1)
 
-             //子弹爆炸精灵帧
 
-             this._getFrames(this._roleData.bulletCount, this._explodeframes, this._roleData.bulletExplodeImg, 1)
 
-             //设置基础数据
 
-             this._setRoleData(this._roleData);
 
-             this.playAnimation(RoleState.Move);
 
-         }
 
-         //位置
 
-         this.node.setWorldPosition(pos);
 
-         this.bulletLayer = find("Canvas/GameRoot/BulletLayer");
 
-     }
 
-     private _setRoleData(roleData: RoleData) {
 
-         this.hp = roleData.hp;
 
-         this.atk = roleData.atk;
 
-         this.atkLength = roleData.atkLength;
 
-         this.moveSpeed = roleData.moveSpeed;
 
-     }
 
-     //获取精灵帧组 
 
-     /*
 
-     count -> 精灵帧的数量 
 
-     imgType -> 图片类型(atk、walk、idle、die)
 
-     startIdx -> 索引起始数
 
-     */
 
-     private _getFrames(count: number, frames: SpriteFrame[], imgType: string, startIdx: number) {
 
-         for (let i = startIdx; i <= count; i++) {
 
-             if (count > 1) {
 
-                 frames.push(resMgr.getSpriteFrame(imgType + ' (' + i + ')'));
 
-             }
 
-             else {
 
-                 frames.push(resMgr.getSpriteFrame(imgType + ' (1)'));
 
-             }
 
-         }
 
-     }
 
-     update(deltaTime: number) {
 
-         
 
-         if (this._state === RoleState.Die) return;
 
-         //只有游戏结束才能执行后续操作
 
-         if(GameInfo.Instance.getIsGameOver()) return;
 
-         
 
-         if (!this.currentTarget) {
 
-             this._handleMovement(deltaTime);
 
-             
 
-             this._detectEnemies();
 
-         } else {
 
-             this._handleAttack(deltaTime);
 
-         }
 
-     }
 
-     //移动
 
-     private _handleMovement(dt: number) {
 
-         if (this._state !== RoleState.Move) return;
 
-         let x = this.node.position.x;
 
-         let y = this.node.position.y;
 
-         let z = this.node.position.z;
 
-         x = x + this.moveSpeed * this.direction * dt
 
-         this.node.setPosition(x, y, z);
 
-     }
 
-     //寻敌
 
-     private _detectEnemies() {
 
-         //节点不可用,不寻敌
 
-         if (!this.node.isValid) return;
 
-         //游戏结束,不寻敌
 
-         if(GameInfo.Instance.getIsGameOver()) return;
 
-         //const startPos = new Vec2(this.node.position.x, this.node.position.y);
 
-         const startPos = this.node.position.clone();
 
-         const endPos = new Vec2((this.direction * this.atkLength) + this.node.position.x, this.node.position.y);
 
-         const results = PhysicsSystem2D.instance.raycast(startPos, endPos);
 
-         if (results?.length) {
 
-             for (const result of results) {
 
-                 const target = result.collider.node.getComponent(Role);
 
-                 if (target && this._isValidTarget(target)) {
 
-                     this._setTarget(target);
 
-                     break;
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     //设置攻击目标
 
-     private _setTarget(target: Role) {
 
-         this.currentTarget = target;
 
-         this.playAnimation(RoleState.Attack);
 
-         // 使得第一次update就会触发attackTimer >= attackInterval条件
 
-         this._attackTimer = this._attackInterval - 0.001;
 
-         //监听目标销毁事件
 
-         target.node.once(Node.EventType.NODE_DESTROYED, this._onTargetDestroyed, this);
 
-     }
 
-     //攻击
 
-     private _handleAttack(deltaTime: number) {
 
-         //目标是否可以攻击
 
-         if (!this._validateTarget()) {
 
-             this._clearTarget();
 
-             return;
 
-         }
 
-         /*
 
-         //立即攻击判断
 
-         if (this._attackTimer === 0) {
 
-             this._createBullet();
 
-             this._attackTimer += deltaTime;
 
-             return;
 
-         }
 
-         //后续间隔攻击
 
-         this._attackTimer += deltaTime;
 
-         if (this._attackTimer >= this._attackInterval) {
 
-             this._createBullet();
 
-             this._attackTimer = 0; //重置计时器
 
-         }
 
-             */
 
-         // this._createBullet();
 
-         // this.schedule(() => {
 
-         //     this._createBullet();
 
-         // }, this.attackInterval);
 
-     }
 
-     //目标是否可以攻击 hp大于0 并且 在攻击范围内 -> 可以攻击
 
-     private _validateTarget(): boolean {
 
-         return !!this.currentTarget?.node?.isValid &&
 
-             this.currentTarget.node.getComponent(LifeBar)._curHp > 0 &&
 
-             this._getDistanceToTarget() <= this.atkLength;
 
-     }
 
-     //攻击目标与自身的距离
 
-     private _getDistanceToTarget(): number {
 
-         return Math.abs(this.node.getWorldPosition().x - this.currentTarget.node.getWorldPosition().x);
 
-     }
 
-     //销毁目标
 
-     private _onTargetDestroyed() {
 
-         this._clearTarget();
 
-         if (this.node === null) return;
 
-         this._detectEnemies();//立即检测新目标
 
-     }
 
-     //清除目标 关闭触发事件 当前目标置空 设置移动状态 播放移动动画
 
-     private _clearTarget() {
 
-         this.currentTarget?.node.off(Node.EventType.NODE_DESTROYED, this._onTargetDestroyed, this);
 
-         this.currentTarget = null;
 
-         this.playAnimation(RoleState.Move);
 
-     }
 
-     //将各个动画存储起来
 
-     private _collectAni() {
 
-         this._createClip(RoleState.Move, this._moveFrames, 8);
 
-         this._createClip(RoleState.Attack, this._atkFrames, 6);
 
-         this._createClip(RoleState.Idle, this._idleFrames, 8);
 
-         this._createClip(RoleState.Die, this._dieFrames, 9);
 
-     }
 
-     //创建动画剪辑 fps越大 速度越快
 
-     private _createClip(state: RoleState, frames: SpriteFrame[], fps: number) {
 
-         const clip: AnimationClip = AnimationClip.createWithSpriteFrames(frames, fps);
 
-         clip.name = RoleState[state];
 
-         clip.wrapMode = state === RoleState.Die ?
 
-             AnimationClip.WrapMode.Normal :
 
-             AnimationClip.WrapMode.Loop;
 
-         if (clip.name === 'Attack') {
 
-             clip.events = [{
 
-                 frame: 0.5,
 
-                 func: "onTriggered",
 
-                 params: [""] //向func传递的参数
 
-             }]
 
-         }
 
-         this._animation.addClip(clip, clip.name);
 
-         this._animations.set(state, clip.name);
 
-     }
 
-     onTriggered() {
 
-         this._createBullet();
 
-     }
 
-     //设置动画
 
-     public playAnimation(state: RoleState) {
 
-         if (!this._animation || this._state === state) return;
 
-         const clipName = this._animations.get(state);
 
-         if (!clipName) return;
 
-         //如果当前有动画正在播放,等待其完成后再切换
 
-         if (this._animation.getState(String(this._state))?.isPlaying) {
 
-             this._animation.once(Animation.EventType.FINISHED, () => {
 
-                 this._switchState(state, clipName);
 
-             });
 
-         } else {
 
-             this._switchState(state, clipName);
 
-         }
 
-     }
 
-     private _switchState(state: RoleState, clipName: string) {
 
-         this._state = state;
 
-         //this._animation.stop();
 
-         this._animation.play(clipName);
 
-         if (state === RoleState.Die) {
 
-             this.node.removeAllChildren();
 
-             this._animation.once(Animation.EventType.FINISHED, () => {
 
-                 this.node.destroy();
 
-             });
 
-         }
 
-     }
 
-     private _createBullet() {
 
-         const isEnemy = this.direction === -1;
 
-         this._bullet = this._bulletPool.getBullet(isEnemy);
 
-         this._bullet.parent = this.bulletLayer;
 
-         this._bullet.setWorldPosition(this.node.getWorldPosition());
 
-         const bulletTS = this._bullet.getComponent(Bullet);
 
-         bulletTS.reset({
 
-             pool: this._bulletPool,
 
-             isEnemy: isEnemy,
 
-             direction: this.direction,
 
-             bulletFrames: this._bulletFrames,
 
-             explodeFrames: this._explodeframes,
 
-             targetNode: this.currentTarget.node,
 
-             atk: this.atk,
 
-         })
 
-     }
 
-     //要求子类实现的碰撞分组和阵营判断方法,确保不同阵营角色可以正确交互
 
-     protected _getCollisionGroup(): number {
 
-         throw new Error("Method not implemented");
 
-     }
 
-     protected _isValidTarget(target: Role): boolean {
 
-         throw new Error("Method not implemented");
 
-     }
 
- }
 
 
  |