import { _decorator, Node, SkeletalAnimation, Vec3 } from 'cc'; import { BaseExp } from '../core/base/BaseExp'; import { PoolManager } from '../core/manager/PoolManager'; import { uiMgr } from '../core/manager/UIManager'; import { Constants } from '../data/Constants'; import { userIns } from '../data/UserData'; import { autoBind } from '../extend/AutoBind'; import { GunBase } from '../items/base/GunBase'; import { GunfightShootUI } from '../ui/GunfightShootUI'; import { ResUtil } from '../utils/ResUtil'; import { Game } from './Game'; import MsgHints from '../utils/MsgHints'; import { PlayerCamera } from './PlayerCamera'; import { audioMgr } from '../core/manager/AudioManager'; const { ccclass, property } = _decorator; //玩家动作类型 export enum PAnimType { idle = "idle",//idle 待机状态 die = "die",//die 死亡状态 reload = "reload",//reload 换弹夹状态 } @ccclass('Player') export class Player extends BaseExp { @autoBind({type: Node,tooltip: "创建枪的位置"}) public gun_pos: Node = null!; @autoBind({type: Node,tooltip: "玩家头的位置"}) public head: Node = null!; @autoBind({type: Node,tooltip: "敌人埋伏点"}) public ambush: Node = null!; @autoBind({type: Node,tooltip: "玩家身子的位置"}) public body: Node = null!; @autoBind({type: SkeletalAnimation,tooltip: "玩家人物动画节点"}) public player_skeletal: SkeletalAnimation = null!; @autoBind({type: PlayerCamera,tooltip: "玩家摄像机抖动控制"}) public mainCamera: PlayerCamera = null!; @autoBind({type: Node,tooltip: "玩家摄像机抖动控制"}) public GGGGGGG: Node = null!; /**玩家的位置节点*/ public playPosNodes: Node[] = []!; /**玩家当前血量*/ public curHP: number = 0; /**玩家是否死亡*/ public isDead: boolean = false; /**玩家拥有的枪*/ public gun: GunBase = null; //玩家数据 public pData:any = null //是否去设置gunfightShootUI的基础信息 public isCutShoot:boolean = false; //射击ui类 private _shootUI: GunfightShootUI | null = null; //懒获取射击界面 public get shootUI(): GunfightShootUI { if (!this._shootUI) { this._shootUI = uiMgr.getPageComponent(Constants.popUIs.gunfightShootUI); } return this._shootUI!; } //是否是换弹夹状态 public isReloadMagazine: boolean = false; //玩家打敌人爆头的个数 public headShotNum:number = 0; start() { //隐藏玩家设置的位置坐标节点 (this.playPosNodes = this.node.parent.getChildByName('player_points').children) .forEach(e => e.active = false); //隐藏的枪的位置节点 this.gun_pos.children.forEach(e => e.active = false); this.pData = userIns.getCurUseGun(); //创建玩家拥有的枪 this.loadGunName(this.pData.prb_name); } /** * 加载枪 * @param name 枪的名字 * @param isCut 是否是切换枪 */ public loadGunName(name: string,isCut: boolean = false){ //玩家待机状态 this.player_skeletal.play(PAnimType.idle); this.pData = userIns.getCurUseGun(); this.curHP = this.pData.hp; if(!isCut && this.gun)return; if(isCut){ PoolManager.putNode(this.gun.node); } ResUtil.loadGunRes(`player/${name}`).then((gunNode: Node) => { if(!gunNode)return; this.isCutShoot = true; gunNode.parent = this.node; this.gun = gunNode.getComponent(GunBase); let pos_ui: Node = this.gun_pos.children.find(e=>e.name == this.pData.prb_name); if(!pos_ui){ MsgHints.show("未找到武器没有对应的位置节点"); } pos_ui = pos_ui || this.gun_pos; if(pos_ui){ gunNode.worldPosition = pos_ui.worldPosition.clone(); gunNode.eulerAngles = pos_ui.parent.eulerAngles.clone(); gunNode.scale = pos_ui.scale.clone(); } this.gun.init(this.pData,this,()=>{},this.reloadMagazine.bind(this)); }); } /** * 更换弹匣 */ public reloadMagazine(data:any){ if(!data || this.isReloadMagazine)return; this.isReloadMagazine = true; let time: number = (data.reloadingSpeed * 4) / 1000; //换弹匣动画 this.player_skeletal.play(PAnimType.reload); //获取动画原始时长 const clip = this.player_skeletal.clips.find(c => c.name === PAnimType.reload); //计算需要设置的速度 clip.speed = clip!.duration / time; this.shootUI.reloadMagazineing(time,()=>{ this.isReloadMagazine = false; this.shootUI.gunDataUI(); this.player_skeletal.play(PAnimType.idle); }); } /** * 玩家发射子弹 */ public shoot() { if(!this.gun || this.isReloadMagazine)return; this.gun.fire(); this.shootUI.crossHairStability(); Game.I.player.mainCamera.shake(0.2,0,0.1); } /** * 随机切枪 */ public randomCutGun(){ let guns = userIns.data.guns; if(guns.length > 1){ let idx : number = guns.findIndex(e=>e.id == this.pData.id); let next:number = (idx + 1) % guns.length; const cutGun:any = guns[next]; userIns.changeGun(cutGun.id); this.loadGunName(cutGun.prb_name,true); } } /** * 移除枪回收武器 */ public removeGun(){ if(!this.gun)return; this.gun.endFire(); PoolManager.putNode(this.gun.node); this.gun = null; } /** * 玩家扣掉血 * @param hp 血 * @param eData 敌人数据 */ public subHP(hp: number,eData:any){ if(Game.I.isPause ||Game.I.isGameOver ||this.isDead ||hp <= 0){ return; } this.curHP -= hp; this.curHP = this.curHP < 0 ? 0 : this.curHP; //设置血条 const progress:number = this.curHP / this.pData.hp; this.shootUI.playerHurtTwinkle(progress); //敌人死亡 if(this.curHP <= 0 && !this.isDead){ Game.I.isGameOver = true; audioMgr.playOneShot(Constants.audios.loss); uiMgr.show(Constants.popUIs.settleUI,[{ isWin: false, headShotNum: Game.I.player.headShotNum, cb: ()=>{} }]); this.isDead = true; this.recycle(); this.player_skeletal.play(PAnimType.die); this.scheduleOnce(() => { this.player_skeletal.stop(); this.player_skeletal.node.active = false; }, 2); } } /** * 根据关卡设置玩家的位置 */ public setPlayerPos(){ if(!this.pData)return; let length:number = this.playPosNodes.length; const data = userIns.getCurLevelData(); const safeIndex = Math.min(data.point -1, length - 1); const n: Node = this.playPosNodes[safeIndex]; this.node.worldPosition = n.worldPosition.clone(); } /** * 回收 */ public recycle(){ this.removeGun(); this.isReloadMagazine = false; this.headShotNum = 0; } /** * 设置枪的数据 */ protected update(dt: number): void { if(this.isCutShoot){ //设置玩家枪的信息 if(this.shootUI && this.pData){ this.shootUI.gunDataUI(); this.isCutShoot = false; } } } }