Hero.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import { _decorator, Label,sp, UITransform, Vec2, Vec3 ,Node, isValid, tween, CCInteger} 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 { BattleEventManager } from '../base/BattleEventManager';
  9. import { BattleEventHeroAction, BattleEventTarget, HeroActionType } from '../base/BattleEventUtil';
  10. import { BattleUtil } from '../data/BattleUtil';
  11. const { ccclass, property } = _decorator;
  12. //英雄基类
  13. @ccclass('Hero')
  14. export class Hero extends BattleNodeBase {
  15. @property({ type: sp.Skeleton, tooltip: '骨骼动画' })
  16. modelSpine: sp.Skeleton = null;
  17. @property({ type: Label, tooltip: '等级' })
  18. levelLabel: Label = null;
  19. @property({ type: Node, tooltip: '枪 左右' })
  20. gunNode1: Node = null;
  21. @property({ type: Node, tooltip: '枪 下' })
  22. gunNode2: Node = null;
  23. @property({ type: Node, tooltip: '枪 上' })
  24. gunNode3: Node = null;
  25. @property({ type: UITransform, tooltip: '点击框' })
  26. clickBox: UITransform = null;
  27. @property({ type: CCInteger, tooltip: '计算类型' })
  28. calcType: number = 0;
  29. //所属格子 -1表示暂无
  30. private _posIndex = -1;
  31. private _bAttackAnimation: boolean = false;
  32. attackNode = null;
  33. //
  34. attackBone1 = null;
  35. attackBone2 = null;
  36. attackBone3 = null;
  37. attackBone4 = null;
  38. attackAngle1 = 0;
  39. attackAngle2 = 0;
  40. attackAngle3 = 0;
  41. attackAngle4 = 0;
  42. attackSlot = null;
  43. typeID: number = -1;
  44. private _raceID: number = -1;
  45. level: number = 1;
  46. radius = 1; //半径
  47. audioID:number = AudioID.Tututu
  48. battleEventManager: BattleEventManager;
  49. private _nextAnimName: string = "idle";
  50. set posIndex(posIndx:number){
  51. this._posIndex = posIndx;
  52. }
  53. get posIndex(){
  54. return this._posIndex;
  55. }
  56. get raceID(){
  57. return this._raceID;
  58. }
  59. protected onLoad(): void {
  60. this.modelSpine.setStartListener(this.actionStart.bind(this))
  61. this.modelSpine.setCompleteListener(this.actionComplete.bind(this))
  62. this.modelSpine.setEventListener(this.actionCallback.bind(this))
  63. this.battleEventManager = BattleEventManager.instance
  64. let gunName = "gun1"
  65. if(this.calcType == 1 || this.calcType == 4){
  66. gunName = "gun"
  67. }
  68. let bone1 = this.modelSpine.findBone(gunName)
  69. if(bone1){
  70. this.attackBone1= bone1
  71. let rot = this.attackBone1.rotation
  72. this.attackAngle1 = rot
  73. console.log("rot",rot)
  74. }
  75. let bone2 = this.modelSpine.findBone("gun2")
  76. if(bone2){
  77. this.attackBone2 = bone2
  78. let rot = this.attackBone2.rotation
  79. this.attackAngle2 = rot
  80. console.log("rot",rot)
  81. }
  82. let bone3 = this.modelSpine.findBone("gun3")
  83. if(bone3){
  84. this.attackBone3 = bone3
  85. let rot = this.attackBone3.rotation
  86. this.attackAngle3 = rot
  87. console.log("rot",rot)
  88. }
  89. let bone4 = this.modelSpine.findBone(gunName)
  90. if(bone4){
  91. this.attackBone4 = bone4
  92. let rot = this.attackBone4.rotation
  93. this.attackAngle4 = rot
  94. console.log("rot",rot)
  95. }
  96. if(this.calcType == 1){
  97. this.audioID = AudioID.Jian
  98. }else if(this.calcType == 3){
  99. this.audioID = AudioID.PingDiGuo
  100. }
  101. // this.clickBox.setContentSize(this.modelSpine.getComponent(UITransform).contentSize)
  102. }
  103. start() {
  104. }
  105. resetData(heroData:HeroData) {
  106. this.typeID = heroData.typeID;
  107. this._raceID = heroData.raceID;
  108. this.level = heroData.level;
  109. this.radius = heroData.attackRadius;
  110. this.levelLabel.string = heroData.level.toString();
  111. this.node.active = true;
  112. this.modelSpine.node.active = true;
  113. this.modelSpine.timeScale = 1;
  114. this.modelSpine.setAnimation(0, 'idle_right', true);
  115. this.stand()
  116. // let id: string = heroData.heroID;
  117. }
  118. clearData() {
  119. this.node.active = false;
  120. this.modelSpine.node.active = false;
  121. this._posIndex = -1;
  122. this.typeID = -1;
  123. this.level = 0;
  124. this._isLock = false;
  125. }
  126. update(deltaTime: number) {
  127. super.update(deltaTime);
  128. if(this._bAttackAnimation && isValid(this.attackNode)){
  129. let pos = this.attackNode.position;
  130. let rotationAngleDegrees = this.getRotationAngle(this.node,pos)
  131. this.attackBone1.rotation = 0
  132. this.attackBone2.rotation = 0
  133. this.attackBone3.rotation = 0
  134. this.attackBone4.rotation = 0
  135. let curAnimName = this.modelSpine.animation
  136. if(rotationAngleDegrees<67.5 || rotationAngleDegrees > 292.5){
  137. let rotationAngle = this.getRotationAngle(this.gunNode1,pos)
  138. if(this.calcType == 1 ||this.calcType == 4){
  139. this.attackBone1.rotation = -rotationAngle+this.attackAngle1
  140. }
  141. else if(this.calcType == 2){
  142. this.attackBone1.rotation = (rotationAngle+this.attackAngle1)
  143. }
  144. this._nextAnimName = "atk_right"
  145. }
  146. else if(rotationAngleDegrees < 112.5){
  147. let rotationAngle = this.getRotationAngle(this.gunNode3,pos)
  148. if(this.calcType == 1||this.calcType == 4){
  149. this.attackBone3.rotation = rotationAngle+this.attackAngle3
  150. }
  151. else if(this.calcType == 2){
  152. // this.attackBone2.rotation = rotationAngle+this.attackAngle2
  153. this.attackBone3.rotation = rotationAngle+this.attackAngle3-90
  154. }
  155. this._nextAnimName = "atk_up"
  156. }
  157. else if(rotationAngleDegrees < 247.5){
  158. let rotationAngle = this.getRotationAngle(this.gunNode1,pos)
  159. if(this.calcType == 1||this.calcType == 4){
  160. this.attackBone4.rotation = rotationAngle+this.attackAngle4+180
  161. }
  162. else if(this.calcType == 2) {
  163. this.attackBone4.rotation = 180-rotationAngle+this.attackAngle4
  164. }
  165. this._nextAnimName = "atk_left"
  166. }
  167. else if(rotationAngleDegrees < 292.5){
  168. let rotationAngle = this.getRotationAngle(this.gunNode2,pos)
  169. if(this.calcType == 1||this.calcType == 4){
  170. this.attackBone3.rotation = rotationAngle+this.attackAngle3 + 90
  171. }
  172. else if(this.calcType == 2){
  173. this.attackBone2.rotation = rotationAngle+this.attackAngle2-270
  174. }
  175. this._nextAnimName = "atk_down"
  176. }
  177. if(!curAnimName.includes("atk_") && this._nextAnimName.includes("atk_")){
  178. this.modelSpine.setAnimation(0,this._nextAnimName, true);
  179. let conf = UptypeConf.data
  180. let speedScale = conf.HeroSpeedColArr[this.level]
  181. this.modelSpine.timeScale = speedScale;
  182. }
  183. }
  184. }
  185. //屏幕坐标
  186. bTouch(pos: Vec2){
  187. return this.node.getComponent(UITransform).hitTest(pos,0);
  188. }
  189. get bAttackAnimation(): boolean{
  190. return this._bAttackAnimation;
  191. }
  192. //通过目标坐标 来确定朝向
  193. attack(attackNode:Node){
  194. if(!this.modelSpine.node.active) return;
  195. this.attackNode = attackNode;
  196. // if(this._bAttackAnimation) return;
  197. this._bAttackAnimation = true;
  198. }
  199. stand() {
  200. if(!this.modelSpine.node.active) return;
  201. this._bAttackAnimation = false;
  202. // this.gunNode.angle = 0;
  203. // this.gunNode.active = true;
  204. this.attackBone1.rotation = 0
  205. this.attackBone2.rotation = 0
  206. this.attackBone3.rotation = 0
  207. this.attackBone4.rotation = 0
  208. // this._attackCallback = null;
  209. let animationName = this.modelSpine.animation
  210. if(animationName.includes("idle")) return;
  211. switch(animationName){
  212. case "atk_right":
  213. this._nextAnimName = "atk_right";
  214. this.modelSpine.setAnimation(0, 'idle_right', true);
  215. break;
  216. case "atk_left":
  217. this._nextAnimName = "atk_left";
  218. this.modelSpine.setAnimation(0, 'idle_left', true);
  219. break;
  220. case "atk_up":
  221. this._nextAnimName = "atk_up";
  222. this.modelSpine.setAnimation(0, 'idle_up', true);
  223. break;
  224. case "atk_down":
  225. this._nextAnimName = "atk_down";
  226. this.modelSpine.setAnimation(0, 'idle_down', true);
  227. break;
  228. default:
  229. this._nextAnimName = "idk_right";
  230. this.modelSpine.setAnimation(0, 'idle_right', true);
  231. break;
  232. }
  233. this.modelSpine.timeScale = 1;
  234. // this.modelSpine.setAnimation(0, 'idle_up', true);
  235. // if(this.modelSpine.node.scale.x < 0)
  236. // this.modelSpine.node.scale = new Vec3(-this.modelSpine.node.scale.x,this.modelSpine.node.scale.y,this.modelSpine.node.scale.z);
  237. }
  238. levelUp() {
  239. this.level++;
  240. this.levelLabel.string = this.level.toString();
  241. }
  242. actionCallback(trackEntry: sp.spine.TrackEntry,ev: sp.spine.Event){
  243. // console.log("动作回调:",trackEntry.animation.name,ev)
  244. if (trackEntry.animation.name && trackEntry.animation.name.includes("atk")) {
  245. // if (this._attackCallback) {
  246. // this._attackCallback(trackEntry);
  247. // }
  248. // console.log("攻击动作完成:",trackEntry.animation.name)
  249. if(this.posIndex > BattleUtil.PosID_Init){
  250. let eventData:BattleEventHeroAction = {
  251. action: HeroActionType.Normal,
  252. posIndex: this._posIndex - BattleUtil.BagListSize
  253. }
  254. this.battleEventManager.fireEvent(BattleEventTarget.HeroAction,eventData)
  255. }
  256. }
  257. }
  258. actionStart(trackEntry:sp.spine.TrackEntry){
  259. // console.log("动作完成:",trackEntry.animation.name,this._posID)
  260. if (trackEntry.animation.name && trackEntry.animation.name.includes("atk_")) {
  261. Framework.audio.playEffect(this.audioID);
  262. }
  263. }
  264. actionComplete(trackEntry:sp.spine.TrackEntry){
  265. // console.log("动作完成:",trackEntry.animation.name,this._posID)
  266. if (trackEntry.animation.name && trackEntry.animation.name.includes("atk_")) {
  267. if( this._nextAnimName.includes("atk_")){
  268. this.modelSpine.setAnimation(0,this._nextAnimName, true);
  269. let conf = UptypeConf.data
  270. let speedScale = conf.HeroSpeedColArr[this.level]
  271. this.modelSpine.timeScale = speedScale;
  272. }
  273. // this._bAttackAnimation = false;
  274. // // this.gunNode.angle = 0;
  275. // // this.gunNode.active = false;
  276. // this.attackBone.rotation = 0
  277. // this._attackCallback = null;
  278. }
  279. }
  280. //
  281. flyTo(pos:Vec3, callback:Function){
  282. if(this._isLock){ return false; }
  283. this.isLock = true;
  284. let length = Vec3.distance(this.node.position,pos);
  285. if(length > 300){
  286. length = 300;
  287. }
  288. tween(this.node).to(length/500,{position:pos}).call(()=>{
  289. this.isLock = false;
  290. if(callback) callback();
  291. }).start();
  292. }
  293. hitTest(pos:Vec2){
  294. return this.clickBox.hitTest(pos) || this.node.getComponent(UITransform).hitTest(pos);
  295. }
  296. //根据目标位置获取旋转角度
  297. getRotationAngle(srcNode:Node,targetPos:Vec2){
  298. // 获取子节点的世界坐标
  299. let worldPosition = this.node.getComponent(UITransform).convertToWorldSpaceAR(Vec3.ZERO);
  300. // 将子节点的世界坐标转换为父节点的局部坐标
  301. let localPosition = this.node.parent.getComponent(UITransform).convertToNodeSpaceAR(worldPosition);
  302. // 计算从p0到p1的向量
  303. let deltaX: number = targetPos.x - localPosition.x;
  304. let deltaY: number = targetPos.y - localPosition.y;
  305. // 计算旋转角度(弧度)
  306. let rotationAngleRadians: number = Math.atan2(deltaY, deltaX);
  307. // 将旋转角度转换为度数
  308. let rotationAngleDegrees: number = (rotationAngleRadians * (180 / Math.PI)+360)%360;
  309. return rotationAngleDegrees;
  310. }
  311. }