import { _decorator, Animation, AnimationClip, AnimationState, BoxCollider2D, Collider2D, Component, find, instantiate, ITriggerEvent, Node, SpriteFrame, UITransform, Vec2, Vec3 } from 'cc'; import { Tools } from '../Tools/Tools'; import { RoleData } from '../../DataItem/ItemData'; import { resMgr } from '../../Frames/ResourcesMgr'; import { Bullet } from './GameScene/Bullet'; import { LifeBar } from './GameScene/LifeBar'; const { ccclass, property } = _decorator; enum State { Attack, Walk, Idle, Die } @ccclass('Role') export class Role extends Component { hp: number = null; atk: number = null; atkLength: number = null; moveSpeed: number = null; //向左0 向右1 direction: number = 1; //是否停下 isStop: boolean = true; //是否可以攻击 isAttacking: boolean = false; //攻击目标 targetNode: Node = null; //是否开火 isFire: boolean = false; //当前目标 currentTarget: Node | null = null; private _bullet: Node = null; private _bulletLayer: Node = null; private _walkFrames: SpriteFrame[] = []; private _atkFrames: SpriteFrame[] = []; private _idleFrames: SpriteFrame[] = []; private _dieFrames: SpriteFrame[] = []; private _explodeframes: SpriteFrame[] = []; private _bulletFrames: SpriteFrame[] = []; private _animations: Map = new Map(); private _roleData: RoleData = null; curState: State = State.Walk; init(name: string, pos: Vec3, roleDatas: RoleData[], dir?: number) { this.isStop = false; 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) { //获取walk精灵帧 const aniCount: number = this._roleData.aniCount; this._getFrames(aniCount, this._walkFrames, this._roleData.aniImg, 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) // //获取攻击精灵帧 // const atkCount: number = data[whichData].atkCount; // this._getFrames(atkCount, this._atkFrames, data[whichData].atkImg, 1); // //获取待机精灵帧 // const idleCount: number = data[whichData].idleCount; // this._getFrames(idleCount,this._idleFrames,data[whichData].idleImg, 1); // //获取死亡精灵帧 // const dieCount: number = data[whichData].dieCount; // this._getFrames(dieCount,this._dieFrames,data[whichData].dieImg, 1); //设置基础数据 this._setRoleData(this._roleData); // let ani = Tools.createAnimation(this._walkFrames, 20, this.node, AnimationClip.WrapMode.Loop); // ani.name = "a"; this._animations.get("walkAni").play(); } //位置 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 + 100; this.moveSpeed = roleData.moveSpeed + 20; } //获取精灵帧组 /* 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)); } } } update(deltaTime: number) { //this._collision(this.targetNode); if (this.curState == State.Walk) { //this._animations.get("walkAni").play(); if (!this.isStop) { this.move(deltaTime); } this.stop() } else if (this.curState == State.Attack) { //this._animations.get("atkAni").play(); } else if (this.curState == State.Die) { //this._animations.get("dieAni").play(); } else if (this.curState == State.Idle) { //this._animations.get("idleAni").play(); } } //移动 move(dt: number) { let x = this.node.getWorldPosition().x; let y = this.node.getWorldPosition().y; let z = this.node.getWorldPosition().z; if (this.direction) { x = x + this.moveSpeed * dt; } else { x = x - this.moveSpeed * dt; } this.node.setWorldPosition(x, y, z) } stop() { } die() { this.node.destroy(); } walk() { } //将各个动画存储起来 private _collectAni() { //const walkAni: Animation = this._createAni(this._walkFrames,20, AnimationClip.WrapMode.Loop) const walkAni: Animation = Tools.createAnimation(this._walkFrames, 20, this.node, AnimationClip.WrapMode.Loop) walkAni.name = "walkAni"; this._animations.set(walkAni.name, walkAni); const atkAni: Animation = Tools.createAnimation(this._atkFrames, 20, this.node, AnimationClip.WrapMode.Loop) atkAni.name = "atkAni"; this._animations.set(atkAni.name, atkAni); const idleAni: Animation = Tools.createAnimation(this._idleFrames, 20, this.node, AnimationClip.WrapMode.Loop) idleAni.name = "idleAni"; this._animations.set(idleAni.name, idleAni); const dieAni: Animation = Tools.createAnimation(this._dieFrames, 20, this.node, AnimationClip.WrapMode.Loop) dieAni.name = "dieAni"; this._animations.set(dieAni.name, dieAni); } //判断是否攻击 getEnemiesAhead(parent: Node) { for (const node of parent.children) { const enemyY = node.getWorldPosition().y; const enemyX = node.getWorldPosition().x; const y = this.node.getWorldPosition().y; const x = this.node.getWorldPosition().x; if (enemyY === y) { const distance = Math.abs(enemyX - x); if (distance <= this.atkLength) { //开始攻击 this.isAttacking = true; //设置攻击目标 this.targetNode = node; //停止移动 this.isStop = true; //开始开火 this.isFire = true; this.attack(this.targetNode, this.isFire); break; } } } } attack(targetNode: Node, isFire: boolean) { if (!targetNode) return; const targetNodeTS = targetNode.getComponent(Role); if (isFire && targetNodeTS.hp > 0) { this._createBullet(); this.schedule(() => { this._createBullet(); }, 3) } } //创建子弹 private _createBullet() { this._bullet = instantiate(resMgr.getPrefab("Bullet")); this._bullet.setWorldPosition(this.node.getWorldPosition()); this._bullet.parent = this._bulletLayer; //this._bullet.parent = this.node; const bulletTS = this._bullet.getComponent(Bullet); bulletTS.direction = this.direction; bulletTS.bulletFrames = this._bulletFrames; bulletTS.explodeframes = this._explodeframes; //bulletTS.atkLength = this.atkLength; bulletTS.targetNode = this.targetNode; bulletTS.atk = this.atk; } }