Player.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import { _decorator, Node, SkeletalAnimation, Tween, Vec3 } from 'cc';
  2. import { BaseExp } from '../core/base/BaseExp';
  3. import { PoolManager } from '../core/manager/PoolManager';
  4. import { uiMgr } from '../core/manager/UIManager';
  5. import { Constants } from '../data/Constants';
  6. import { userIns } from '../data/UserData';
  7. import { autoBind } from '../extend/AutoBind';
  8. import { GunBase } from '../items/base/GunBase';
  9. import { GunfightShootUI } from '../ui/GunfightShootUI';
  10. import { ResUtil } from '../utils/ResUtil';
  11. import { Game } from './Game';
  12. import MsgHints from '../utils/MsgHints';
  13. import { PlayerCamera } from './PlayerCamera';
  14. import { audioMgr } from '../core/manager/AudioManager';
  15. const { ccclass, property } = _decorator;
  16. //玩家动作类型
  17. export enum PAnimType {
  18. idle = "idle",//idle 待机状态
  19. die = "die",//die 死亡状态
  20. reload = "reload",//reload 换弹夹状态
  21. }
  22. @ccclass('Player')
  23. export class Player extends BaseExp {
  24. @autoBind({type: Node,tooltip: "创建枪的位置"})
  25. public gun_pos: Node = null!;
  26. @autoBind({type: Node,tooltip: "玩家头的位置"})
  27. public head: Node = null!;
  28. @autoBind({type: Node,tooltip: "敌人埋伏点"})
  29. public ambush: Node = null!;
  30. @autoBind({type: Node,tooltip: "玩家身子的位置"})
  31. public body: Node = null!;
  32. @autoBind({type: SkeletalAnimation,tooltip: "玩家人物动画节点"})
  33. public player_skeletal: SkeletalAnimation = null!;
  34. @autoBind({type: PlayerCamera,tooltip: "玩家摄像机抖动控制"})
  35. public mainCamera: PlayerCamera = null!;
  36. @autoBind({type: Node,tooltip: "玩家摄像机抖动控制"})
  37. public GGGGGGG: Node = null!;
  38. /**玩家的位置节点*/
  39. public playPosNodes: Node[] = []!;
  40. /**玩家当前血量*/
  41. public curHP: number = 0;
  42. /**玩家是否死亡*/
  43. public isDead: boolean = false;
  44. /**玩家拥有的枪*/
  45. public gun: GunBase = null;
  46. //玩家数据
  47. public pData:any = null
  48. //是否去设置gunfightShootUI的基础信息
  49. public isCutShoot:boolean = false;
  50. //射击ui类
  51. private _shootUI: GunfightShootUI | null = null;
  52. //懒获取射击界面
  53. public get shootUI(): GunfightShootUI {
  54. if (!this._shootUI) {
  55. this._shootUI = uiMgr.getPageComponent(Constants.popUIs.gunfightShootUI);
  56. }
  57. return this._shootUI!;
  58. }
  59. //是否是换弹夹状态
  60. public isReloadMagazine: boolean = false;
  61. //玩家打敌人爆头的个数
  62. public headShotNum:number = 0;
  63. start() {
  64. //隐藏玩家设置的位置坐标节点
  65. (this.playPosNodes = this.node.parent.getChildByName('player_points').children)
  66. .forEach(e => e.active = false);
  67. //隐藏的枪的位置节点
  68. this.gun_pos.children.forEach(e => e.active = false);
  69. this.pData = userIns.getCurUseGun();
  70. //创建玩家拥有的枪
  71. this.loadGunName(this.pData.prb_name);
  72. }
  73. /**
  74. * 加载枪
  75. * @param name 枪的名字
  76. * @param isCut 是否是切换枪
  77. */
  78. public loadGunName(name: string = this.pData.prb_name,isCut: boolean = false){
  79. //玩家待机状态
  80. this.player_skeletal.play(PAnimType.idle);
  81. this.pData = userIns.getCurUseGun();
  82. this.curHP = this.pData.hp;
  83. if(!isCut && this.gun)return;
  84. if(isCut){
  85. PoolManager.putNode(this.gun.node);
  86. }
  87. ResUtil.loadGunRes(`player/${name}`).then((gunNode: Node) => {
  88. if(!gunNode)return;
  89. this.isCutShoot = true;
  90. gunNode.parent = this.node;
  91. this.gun = gunNode.getComponent(GunBase);
  92. let pos_ui: Node = this.gun_pos.children.find(e=>e.name == this.pData.prb_name);
  93. if(!pos_ui){
  94. MsgHints.show("未找到武器没有对应的位置节点");
  95. }
  96. pos_ui = pos_ui || this.gun_pos;
  97. if(pos_ui){
  98. gunNode.worldPosition = pos_ui.worldPosition.clone();
  99. gunNode.eulerAngles = pos_ui.parent.eulerAngles.clone();
  100. gunNode.scale = pos_ui.scale.clone();
  101. }
  102. this.gun.init(this.pData,this,()=>{},this.reloadMagazine.bind(this));
  103. });
  104. }
  105. /**
  106. * 更换弹匣
  107. */
  108. public reloadMagazine(data:any){
  109. if(!data || this.isReloadMagazine)return;
  110. this.isReloadMagazine = true;
  111. const factor: number = 130;
  112. let time: number = data.reloadingSpeed / factor;
  113. //换弹匣动画
  114. ResUtil.playSkeletalAnim(this.player_skeletal,PAnimType.reload,time);
  115. this.shootUI.reloadMagazineing(time,()=>{
  116. this.isReloadMagazine = false;
  117. this.shootUI.gunDataUI();
  118. this.player_skeletal.play(PAnimType.idle);
  119. });
  120. }
  121. /**
  122. * 重置
  123. */
  124. public restart(){
  125. this.isDead = false;
  126. this.isReloadMagazine = false;
  127. this.shootUI.hpProgressBar.progress = 1;
  128. Tween.stopAllByTarget(this.shootUI.injury_blood);
  129. this.shootUI.injury_blood.active = false;
  130. this.loadGunName();
  131. this.player_skeletal.play(PAnimType.idle);
  132. }
  133. /**
  134. * 玩家发射子弹
  135. */
  136. public shoot() {
  137. if(!this.gun
  138. || this.isReloadMagazine)return;
  139. this.gun.fire();
  140. this.shootUI.crossHairStability();
  141. Game.I.player.mainCamera.shake(0.2,0,0.1);
  142. }
  143. /**
  144. * 随机切枪
  145. */
  146. public randomCutGun(){
  147. let guns = userIns.data.guns;
  148. if(guns.length > 1){
  149. let idx : number = guns.findIndex(e=>e.id == this.pData.id);
  150. let next:number = (idx + 1) % guns.length;
  151. const cutGun:any = guns[next];
  152. userIns.changeGun(cutGun.id);
  153. this.loadGunName(cutGun.prb_name,true);
  154. }
  155. }
  156. /**
  157. * 移除枪回收武器
  158. */
  159. public removeGun(){
  160. if(!this.gun)return;
  161. this.gun.endFire();
  162. PoolManager.putNode(this.gun.node);
  163. this.gun = null;
  164. }
  165. /**
  166. * 玩家扣掉血
  167. * @param hp 血
  168. * @param eData 敌人数据
  169. */
  170. public subHP(hp: number,eData:any){
  171. if(Game.I.isPause
  172. ||Game.I.isGameOver
  173. ||this.isDead
  174. ||hp <= 0){
  175. return;
  176. }
  177. this.curHP -= hp;
  178. this.curHP = this.curHP < 0 ? 0 : this.curHP;
  179. //设置血条
  180. const progress:number = this.curHP / this.pData.hp;
  181. this.shootUI.playerHurtTwinkle(progress);
  182. //敌人死亡
  183. if(this.curHP <= 0 && !this.isDead){
  184. Game.I.isGameOver = true;
  185. audioMgr.playOneShot(Constants.audios.loss);
  186. uiMgr.show(Constants.popUIs.settleUI,[{
  187. isWin: false,
  188. headShotNum: Game.I.player.headShotNum,
  189. cb: ()=>{}
  190. }]);
  191. this.isDead = true;
  192. this.recycle();
  193. this.player_skeletal.play(PAnimType.die);
  194. this.scheduleOnce(() => {
  195. this.player_skeletal.stop();
  196. this.player_skeletal.node.active = false;
  197. }, 2);
  198. }
  199. }
  200. /**
  201. * 根据关卡设置玩家的位置
  202. */
  203. public setPlayerPos(){
  204. if(!this.pData)return;
  205. let length:number = this.playPosNodes.length;
  206. const data = userIns.getCurLevelData();
  207. const safeIndex = Math.min(data.point -1, length - 1);
  208. const n: Node = this.playPosNodes[safeIndex];
  209. this.node.worldPosition = n.worldPosition.clone();
  210. }
  211. /**
  212. * 回收
  213. */
  214. public recycle(){
  215. this.removeGun();
  216. this.isReloadMagazine = false;
  217. this.headShotNum = 0;
  218. }
  219. /**
  220. * 设置枪的数据
  221. */
  222. protected update(dt: number): void {
  223. if(this.isCutShoot){
  224. //设置玩家枪的信息
  225. if(this.shootUI && this.pData){
  226. this.shootUI.gunDataUI();
  227. this.isCutShoot = false;
  228. }
  229. }
  230. }
  231. }