Player.ts 7.8 KB

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