Hero.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import { _decorator, Label,sp, UITransform, Vec2, Vec3 ,Node, isValid, tween} from 'cc';
  2. import { ObjectUtil } from '../../../../framework/util/ObjectUtil';
  3. import { BattleNodeBase } from './BattleNodeBase';
  4. import { HeroData } from '../data/HeroData';
  5. import { AudioID } from '../../../../framework/config/AudioConf';
  6. import { Framework } from '../../../../framework/Framework';
  7. import { UptypeConf } from '../conf/UptypeConf';
  8. import { HeroConf } from '../conf/HeroConf';
  9. const { ccclass, property } = _decorator;
  10. //英雄基类
  11. @ccclass('Hero')
  12. export class Hero extends BattleNodeBase {
  13. @property({ type: sp.Skeleton, tooltip: '骨骼动画' })
  14. modelSpine: sp.Skeleton = null;
  15. @property({ type: Label, tooltip: '等级' })
  16. levelLabel: Label = null;
  17. @property({ type: Node, tooltip: '枪' })
  18. gunNode: Node = null;
  19. @property({ type: UITransform, tooltip: '点击框' })
  20. clickBox: UITransform = null;
  21. //所属格子 -1表示暂无
  22. private _posID = -1;
  23. private _bAttackAnimation: boolean = false;
  24. attackNode = null;
  25. attackBone = null;
  26. attackSlot = null;
  27. typeID: number = -1;
  28. level: number = 1;
  29. radius = 1; //半径
  30. set posID(posID:number){
  31. this._posID = posID;
  32. }
  33. get posID(){
  34. return this._posID;
  35. }
  36. protected onLoad(): void {
  37. this.modelSpine.setCompleteListener(this.actionComplete.bind(this))
  38. this.modelSpine.setEventListener(this.actionCallback.bind(this))
  39. let bone = this.modelSpine.findBone("gun")
  40. if(bone){
  41. this.attackBone = bone
  42. let rot = this.attackBone.rotation
  43. }
  44. this.clickBox.setContentSize(this.modelSpine.getComponent(UITransform).contentSize)
  45. }
  46. start() {
  47. }
  48. resetData(heroData:HeroData) {
  49. this.typeID = heroData.typeID;
  50. this.level = heroData.level;
  51. this.radius = heroData.attackRadius;
  52. this.levelLabel.string = heroData.level.toString();
  53. this.node.active = true;
  54. this.modelSpine.node.active = true;
  55. let conf = UptypeConf.data
  56. let speedScale = conf.HeroSpeedColArr[this.level]
  57. this.modelSpine.timeScale = speedScale;
  58. this.stand()
  59. // let id: string = heroData.heroID;
  60. }
  61. clearData() {
  62. this.node.active = false;
  63. this.modelSpine.node.active = false;
  64. this._posID = -1;
  65. this.typeID = -1;
  66. this.level = 0;
  67. this._isLock = false;
  68. }
  69. update(deltaTime: number) {
  70. super.update(deltaTime);
  71. if(this._bAttackAnimation && isValid(this.attackNode)){
  72. let pos = this.attackNode.position;
  73. // 获取子节点的世界坐标
  74. let worldPosition = this.gunNode.getComponent(UITransform).convertToWorldSpaceAR(Vec3.ZERO);
  75. // 将子节点的世界坐标转换为父节点的局部坐标
  76. let localPosition = this.node.parent.getComponent(UITransform).convertToNodeSpaceAR(worldPosition);
  77. // 计算从p0到p1的向量
  78. let deltaX: number = pos.x - localPosition.x;
  79. let deltaY: number = pos.y - localPosition.y;
  80. // 计算旋转角度(弧度)
  81. let rotationAngleRadians: number = Math.atan2(deltaY, deltaX);
  82. // 将旋转角度转换为度数
  83. let rotationAngleDegrees: number = (rotationAngleRadians * (180 / Math.PI)+360)%360;
  84. // console.log("旋转角度:", rotationAngleDegrees);
  85. // let scaleX = this.modelSpine.node.scale.x
  86. // if(rotationAngleDegrees > 90 && rotationAngleDegrees < 270){
  87. // // if(scaleX > 0){
  88. // // scaleX= -scaleX;
  89. // // }
  90. // // this.gunNode.angle = 180 - rotationAngleDegrees;
  91. // this.attackBone.rotation = 180 - rotationAngleDegrees
  92. // }
  93. // else{
  94. // // if(scaleX < 0){
  95. // // scaleX= -scaleX;
  96. // // }
  97. // // this.gunNode.angle = rotationAngleDegrees;
  98. // this.attackBone.rotation = rotationAngleDegrees
  99. // }
  100. // this.modelSpine.node.scale = new Vec3(scaleX,this.modelSpine.node.scale.y,this.modelSpine.node.scale.z);
  101. // console.log("旋转角度:", rotationAngleDegrees);
  102. if(rotationAngleDegrees<67.5 || rotationAngleDegrees > 292.5){
  103. this.attackBone.rotation = rotationAngleDegrees
  104. if(this.modelSpine.animation != "attack_right")
  105. this.modelSpine.setAnimation(0, 'attack_right', true);
  106. }
  107. else if(rotationAngleDegrees < 112.5){
  108. this.attackBone.rotation = rotationAngleDegrees
  109. if(this.modelSpine.animation != "attack_up")
  110. this.modelSpine.setAnimation(0, 'attack_up', true);
  111. }
  112. else if(rotationAngleDegrees < 247.5){
  113. this.attackBone.rotation = rotationAngleDegrees
  114. if(this.modelSpine.animation != "attack_left")
  115. this.modelSpine.setAnimation(0, 'attack_left', true);
  116. }
  117. else if(rotationAngleDegrees < 292.5){
  118. this.attackBone.rotation = rotationAngleDegrees
  119. if(this.modelSpine.animation != "attack_down")
  120. this.modelSpine.setAnimation(0, 'attack_down', true);
  121. }
  122. }
  123. }
  124. //屏幕坐标
  125. bTouch(pos: Vec2){
  126. return this.node.getComponent(UITransform).hitTest(pos,0);
  127. }
  128. get bAttackAnimation(): boolean{
  129. return this._bAttackAnimation;
  130. }
  131. //通过目标坐标 来确定朝向
  132. attack(attackNode:Node){
  133. if(!this.modelSpine.node.active) return;
  134. // if(this._bAttackAnimation) return;
  135. this._bAttackAnimation = true;
  136. this.attackNode = attackNode;
  137. Framework.audio.playEffect(AudioID.Tututu);
  138. }
  139. stand() {
  140. if(!this.modelSpine.node.active) return;
  141. this._bAttackAnimation = false;
  142. // this.gunNode.angle = 0;
  143. this.gunNode.active = true;
  144. this.attackBone.rotation = 0
  145. // this._attackCallback = null;
  146. if(this.modelSpine.animation == "stand_right") return;
  147. this.modelSpine.setAnimation(0, 'stand_right', true);
  148. // if(this.modelSpine.node.scale.x < 0)
  149. // this.modelSpine.node.scale = new Vec3(-this.modelSpine.node.scale.x,this.modelSpine.node.scale.y,this.modelSpine.node.scale.z);
  150. }
  151. levelUp() {
  152. this.level++;
  153. this.levelLabel.string = this.level.toString();
  154. let conf = UptypeConf.data
  155. let speedScale = conf.HeroSpeedColArr[this.level]
  156. this.modelSpine.timeScale = speedScale;
  157. }
  158. actionCallback(trackEntry){
  159. // console.log("动作回调:",trackEntry.animation.name)
  160. if (trackEntry.animation.name && trackEntry.animation.name.includes("fire")) {
  161. // if (this._attackCallback) {
  162. // this._attackCallback(trackEntry);
  163. // }
  164. }
  165. }
  166. actionComplete(trackEntry:sp.spine.TrackEntry){
  167. // console.log("动作完成:",trackEntry.animation.name,this._posID)
  168. if (trackEntry.animation.name && trackEntry.animation.name.includes("fire")) {
  169. // this._bAttackAnimation = false;
  170. // // this.gunNode.angle = 0;
  171. // // this.gunNode.active = false;
  172. // this.attackBone.rotation = 0
  173. // this._attackCallback = null;
  174. }
  175. }
  176. //
  177. flyTo(pos:Vec3, callback:Function){
  178. if(this._isLock){ return false; }
  179. this.isLock = true;
  180. let length = Vec3.distance(this.node.position,pos);
  181. if(length > 300){
  182. length = 300;
  183. }
  184. tween(this.node).to(length/500,{position:pos}).call(()=>{
  185. this.isLock = false;
  186. if(callback) callback();
  187. }).start();
  188. }
  189. hitTest(pos:Vec2){
  190. return this.clickBox.hitTest(pos) || this.node.getComponent(UITransform).hitTest(pos);
  191. }
  192. }