ZombieUI.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. import { _decorator, instantiate, Node, Prefab, Size, Tween, tween, UITransform, Vec2, Vec3 ,Animation, EventTouch, Button, sp, Enum, Label, Toggle, Sprite, SpriteFrame, v3} from 'cc';
  2. import { BaseView } from '../../../framework/layer/BaseView';
  3. import { Framework } from '../../../framework/Framework';
  4. import { FrameworkConf } from '../../../framework/config/FrameworkConf';
  5. import { AudioID } from '../../../framework/config/AudioConf';
  6. import { AsyncQueue, NextFunction } from '../../../framework/queue/AsyncQueue';
  7. import { Hero } from './node/Hero';
  8. import { Enemy } from './node/Enemy';
  9. import { Hurt } from './node/Hurt';
  10. import { BattleNodeBase } from './node/BattleNodeBase';
  11. import { BattleControl } from './control/BattleControl';
  12. import { BattleUtil } from './data/BattleUtil';
  13. import { BattleEventManager } from './base/BattleEventManager';
  14. import { BattleEventData_EnemyBorn, BattleEventData_EnemyBuff, BattleEventData_EnemyDie, BattleEventData_EnemyHurt, BattleEventData_EnemyMove, BattleEventData_HeroAttack, BattleEventData_Over, BattleEventTarget, BattleEventType } from './base/BattleEventUtil';
  15. import { isValid } from 'cc';
  16. import { ZombieBattleControl } from '../zombie/control/ZombieBattleControl';
  17. import { ZombieMapConf } from '../zombie/conf/ZombieMapConf';
  18. import { ZombieHeroData, ZombieHeroDataPool } from '../zombie/data/ZombieHeroData';
  19. //地图比例尺 1:70
  20. let mapScaleX = 72;
  21. let mapScaleY = 15;
  22. let basePoint = {x:-325,y:-70}
  23. let baseOffset = {x:0,y:0}
  24. //地图格子转坐标
  25. let MapDataPosToView = (x:number,y:number) => {
  26. let XX = (x+baseOffset.x) * mapScaleX + basePoint.x;
  27. let YY = (y+baseOffset.y) * mapScaleY + basePoint.y;
  28. return new Vec3(XX, YY, 0);
  29. //return new Vec3(x * mapScale + basePoint.x, y * mapScale + basePoint.y, 0);
  30. }
  31. //地图速度转换
  32. let MapDataSpeedToView = (x:number,y:number) => {
  33. let XX = x * mapScaleX * BattleUtil.FrameRate;
  34. let YY = y * mapScaleY * BattleUtil.FrameRate;
  35. return new Vec2(XX, YY,);
  36. //return new Vec3(x * mapScale + basePoint.x, y * mapScale + basePoint.y, 0);
  37. }
  38. const { ccclass, property } = _decorator;
  39. export interface PosData {
  40. node: Node,
  41. hero: Node,
  42. bLock: boolean,
  43. posID: number,
  44. pos: Vec3,
  45. posNumber: number
  46. }
  47. @ccclass('ZombieUI')
  48. export class ZombieUI extends BaseView {
  49. @property({ type: Sprite, tooltip: "地图" })
  50. mapSprite: Sprite = null;
  51. @property({ type: Node, tooltip: "攻击位" })
  52. attackNode: Node = null;
  53. @property({ type: Node, tooltip: "背包位" })
  54. bagNode: Node = null;
  55. @property({ type: Node, tooltip: "减血数字根节点" })
  56. hurtNode: Node = null;
  57. // 攻击位
  58. attackPosList: PosData[] = [];
  59. //根据posID获取做的索引
  60. attackPosMap: Map<number,PosData> = new Map();
  61. //背包位
  62. bagPosList: PosData[] = [];
  63. mapID = 1;
  64. @property({ type: [Prefab], tooltip: "英雄" })
  65. heroModelList: Prefab[] = [];
  66. heroPool: Map<number,Node[]> = new Map();
  67. heroList: Node[] = [];
  68. @property({type:[Node],tooltip:"升级效果"})
  69. levelUpEffect:Node[] = []
  70. @property({ type: [Prefab], tooltip: "敌人" })
  71. ememyModelList: Prefab[] = [];
  72. enemyPool: Node[] = [];
  73. enemyMap: Map<number,Node> = new Map();
  74. enemyWaitTime: number = 0;
  75. @property({ type: [Prefab], tooltip: "受伤数字" })
  76. hurtModelList: Prefab[] = [];
  77. hurtPool: Node[] = [];
  78. hurtList: Node[] = [];
  79. @property({ type:Node, tooltip: "所有角色根节点" })
  80. roleNode: Node = null;
  81. @property({ type:Node, tooltip: "攻击范围" })
  82. radiusNode: Node = null;
  83. bStart = false;
  84. waitTime = 5;
  85. touchStart: Node = null;
  86. gameTime = 0;
  87. battleControl: ZombieBattleControl = null;
  88. //当前动画下标
  89. levelUpEffectIndex = 0;
  90. //是否自动合成
  91. isAutoMerge = true;
  92. protected onLoad() {
  93. super.onLoad();
  94. this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this)
  95. this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
  96. this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
  97. this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
  98. for (let i = 0; i < this.levelUpEffect.length; i++) {
  99. this.levelUpEffect[i].getComponent(sp.Skeleton).setCompleteListener(()=>{
  100. this.levelUpEffect[i].active = false;
  101. })
  102. }
  103. this.battleControl = ZombieBattleControl.GetInstance()
  104. BattleEventManager.instance.addEvent(BattleEventTarget.Update, this.updateDataEvent.bind(this), -1);
  105. this.initPool()
  106. }
  107. protected start(): void {
  108. this.battleControl.init(this.mapID)
  109. this.init();
  110. }
  111. protected onDestroy() {
  112. }
  113. protected update(dt: number): void {
  114. this.updateSiblingIndex()
  115. if(this.bStart){
  116. this.gameTime += dt;
  117. let nowFrame = Math.floor(this.gameTime/BattleUtil.FrameTime)
  118. if(nowFrame > this.battleControl.map.curTurn){
  119. //
  120. while(nowFrame > this.battleControl.map.curTurn+1){
  121. //需要移动的对象做瞬时计算 //目前只有敌人,以后会有子弹或者其他会移动的
  122. this.enemyMap.forEach(element => {
  123. element.getComponent(Enemy).battleUpdate(BattleUtil.FrameTime)
  124. });
  125. this.battleControl.update();
  126. if(this.battleControl.isBattleEnd){
  127. break;
  128. }
  129. }
  130. this.enemyMap.forEach(element => {
  131. element.getComponent(Enemy).battleUpdate(BattleUtil.FrameTime)
  132. });
  133. this.battleControl.update();
  134. }
  135. }
  136. else{
  137. if(this.waitTime > 0){
  138. this.waitTime -= dt;
  139. }
  140. else{
  141. this.bStart = true;
  142. }
  143. }
  144. }
  145. private updateDataEvent(event){
  146. if(this.battleControl.isBattleEnd && event.eventType!=BattleEventType.Over){
  147. console.log("结束")
  148. return
  149. }
  150. switch(event.eventType){
  151. case BattleEventType.EnemyBorn:{
  152. let enemyData = event as BattleEventData_EnemyBorn;
  153. this.addEnemy(enemyData);
  154. break;
  155. }
  156. case BattleEventType.EnemyMove:{
  157. let enemyData = event as BattleEventData_EnemyMove;
  158. // console.log("移动",enemyData.ID,enemyData.speedVector.x,enemyData.speedVector.y)
  159. if(this.enemyMap.has(enemyData.ID)){
  160. let enemy = this.enemyMap.get(enemyData.ID);
  161. enemy.getComponent(Enemy).speedVector = MapDataSpeedToView(enemyData.speedVector.x, enemyData.speedVector.y);
  162. }
  163. break;
  164. }
  165. case BattleEventType.EnemyHurt:{
  166. let enemyData = event as BattleEventData_EnemyHurt;
  167. //console.log("移动",enemyData.ID,enemyData.hurt,enemyData.status)
  168. if(this.enemyMap.has(enemyData.targetID)){
  169. let enemy = this.enemyMap.get(enemyData.targetID);
  170. enemy.getComponent(Enemy).hurt(enemyData.hurt);
  171. this.addHurt(enemy.position,enemyData.hurt)
  172. }
  173. break;
  174. }
  175. case BattleEventType.EnemyDie:{
  176. // console.log("死亡",event)
  177. let enemyData = event as BattleEventData_EnemyDie;
  178. if(this.enemyMap.has(enemyData.ID)){
  179. let enemy = this.enemyMap.get(enemyData.ID);
  180. enemy.getComponent(Enemy).die(()=>{
  181. this.enemyMap.delete(enemyData.ID);
  182. this.enemyPool.push(enemy);
  183. }
  184. );
  185. }
  186. break;
  187. }
  188. case BattleEventType.EnemyBuff:{
  189. let enemyData = event as BattleEventData_EnemyBuff;
  190. if(this.enemyMap.has(enemyData.ID)){
  191. let enemy = this.enemyMap.get(enemyData.ID);
  192. //enemy.getComponent(Enemy).addbuff(enemyData.buff);
  193. }
  194. break;
  195. }
  196. case BattleEventType.HeroAttack:{
  197. // console.log("攻击",event)
  198. let attackData = event as BattleEventData_HeroAttack;
  199. if(this.attackPosMap.has(attackData.posID)){
  200. let posData = this.attackPosMap.get(attackData.posID);
  201. let enemy = this.enemyMap.get(attackData.targetID);
  202. if( posData && posData.hero){
  203. if(enemy){
  204. posData.hero.getComponent(Hero).attack(enemy)
  205. enemy.getComponent(Enemy).hurt(attackData.hurt);
  206. this.addHurt(enemy.position,attackData.hurt)
  207. }
  208. else{
  209. posData.hero.getComponent(Hero).stand()
  210. }
  211. }
  212. }
  213. break;
  214. }
  215. case BattleEventType.Over:{
  216. let attackData = event as BattleEventData_Over;
  217. this.attackPosMap.forEach((posData, posID) => {
  218. if(posData.hero){
  219. posData.hero.getComponent(Hero).stand()
  220. }
  221. })
  222. this.enemyMap.forEach((enemy, enemyID) => {
  223. enemy.getComponent(Enemy).stand()
  224. })
  225. let winStr = attackData.bWin ? "胜利" : "失败";
  226. console.log(winStr)
  227. tween(this.node).delay(3).call(()=>{
  228. this.enemyMap.forEach((enemy, enemyID) => {
  229. enemy.getComponent(Enemy).clearData();
  230. this.enemyMap.delete(enemyID);
  231. this.enemyPool.push(enemy);
  232. })
  233. // this.mapID = this.mapID %2+1;
  234. this.battleControl.reset(this.mapID)
  235. this.reset()
  236. for(let index = 0; index < this.attackPosList.length; index++){
  237. let hero = this.attackPosList[index].hero;
  238. if(hero){
  239. hero.position = this.attackPosList[index].pos;
  240. let heroObj = hero.getComponent(Hero)
  241. this.battleControl.addHeroInPos(heroObj.typeID,heroObj.level,index)
  242. }
  243. }
  244. }).start();
  245. break;
  246. }
  247. }
  248. }
  249. onTouchStart(event: EventTouch) {
  250. if (this.touchStart) {
  251. this.resetHeroPos(this.touchStart)
  252. }
  253. // 获取触点对应节点
  254. let posData = this.getItemBaseByPosition(event.getLocation());
  255. if(posData && posData.hero){
  256. let hero = posData.hero.getComponent(Hero);
  257. if(hero.isLock){
  258. return;
  259. }
  260. Framework.audio.playEffect(AudioID.Click);
  261. this.touchStart = posData.hero;
  262. hero.stand()
  263. this.touchStart.setSiblingIndex(30);
  264. let index = posData.posID - this.bagPosList.length
  265. if(index >= 0){
  266. this.battleControl.removeHeroInPos(index)
  267. }
  268. }
  269. }
  270. // 触摸移动
  271. onTouchMove(event: EventTouch) {
  272. if (this.touchStart ) {
  273. this.touchStart .setPosition(this.roleNode.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(event.getUILocation().x, event.getUILocation().y)))
  274. let posData = this.getItemBaseByPosition(event.getLocation());
  275. if(posData&&(posData.posID >= this.bagPosList.length)){
  276. this.radiusNode.position = v3(this.touchStart.position.x,this.touchStart.position.y);
  277. this.radiusNode.active = true;
  278. this.setRadius(this.touchStart.getComponent(Hero).radius)
  279. }
  280. else{
  281. this.radiusNode.active = false;
  282. }
  283. }
  284. else{
  285. this.radiusNode.active = false;
  286. }
  287. }
  288. onTouchEnd(event: EventTouch) {
  289. this.radiusNode.active = false;
  290. if (this.touchStart) {
  291. let posData = this.getItemBaseByPosition(event.getLocation());
  292. let touchEnd:Node = null
  293. if(posData && posData.hero != this.touchStart){
  294. if(posData.hero){
  295. let hero = posData.hero.getComponent(Hero);
  296. if(hero && hero.isLock){
  297. this.resetHeroPos(this.touchStart)
  298. this.touchStart = null;
  299. return;
  300. }
  301. }
  302. touchEnd = posData.hero;
  303. }
  304. else{
  305. this.resetHeroPos(this.touchStart)
  306. this.touchStart = null;
  307. return
  308. }
  309. if(touchEnd){
  310. let endHero = touchEnd.getComponent(Hero)
  311. let startHero = this.touchStart.getComponent(Hero)
  312. if(endHero.typeID == startHero.typeID && endHero.level == startHero.level){
  313. this.mergeHero(this.touchStart, touchEnd)
  314. }
  315. else{
  316. this.changeHeroPos(this.touchStart, touchEnd)
  317. }
  318. }
  319. else{
  320. this.setHeroPos(this.touchStart, posData.posID)
  321. }
  322. this.touchStart = null;
  323. }
  324. }
  325. onTouchCancel(event: EventTouch) {
  326. this.radiusNode.active = false;
  327. if (this.touchStart) {
  328. this.resetHeroPos(this.touchStart)
  329. this.touchStart = null;
  330. }
  331. }
  332. //根据世界坐标获取item 排除手上的
  333. private getItemBaseByPosition(pos: Vec2):PosData {
  334. let FindArr = this.bagPosList
  335. let bag = FindArr.find(t => {
  336. if(t.hero && t.hero != this.touchStart){
  337. return t.hero.getComponent(Hero).hitTest(pos)
  338. }
  339. return t.node.getComponent(UITransform).hitTest(pos)
  340. });
  341. if (bag ) return bag
  342. FindArr = this.attackPosList
  343. let attack = FindArr.find(t => {
  344. if(t.hero && t.hero != this.touchStart){
  345. return t.hero.getComponent(Hero).hitTest(pos)
  346. }
  347. return t.node.getComponent(UITransform).hitTest(pos)
  348. });
  349. return attack;
  350. }
  351. //炸弹效果播放结束
  352. bombSpineOver() {
  353. }
  354. //UI开打时会调用,如果有初始化代码应该放到此函数
  355. onOpen(args) {
  356. }
  357. //UI关闭时会调用,该函数在onDestroy前调用
  358. onClose() {
  359. }
  360. //框架管理UI层级时会调用,可根据UI情况修改
  361. onShow() {
  362. super.onShow();
  363. }
  364. //框架管理UI层级时会调用,可根据UI情况修改
  365. onHide() {
  366. super.onHide();
  367. }
  368. init() {
  369. this.bStart = false;
  370. this.waitTime = 5;
  371. this.gameTime = 0;
  372. this.radiusNode.active = false;
  373. let posID = 0;
  374. let roleTransform = this.roleNode.getComponent(UITransform)
  375. let mapConf = ZombieMapConf.data[this.mapID.toString()]
  376. if(!mapConf){
  377. console.log("地图配置错误")
  378. return
  379. }
  380. let offset = mapConf.OffsetArray
  381. if(offset){
  382. baseOffset.x = offset[0]
  383. baseOffset.y = offset[1]
  384. }
  385. else{
  386. baseOffset.x = 0
  387. baseOffset.y = 0
  388. }
  389. let path = "texture/tower/"+mapConf.Background+"/spriteFrame"
  390. this.load("package",path, SpriteFrame, (res: SpriteFrame) => {
  391. this.mapSprite.spriteFrame = res
  392. })
  393. let bagChildren = this.bagNode.children
  394. for (let i = 0; i < 10; i++) {
  395. let node = bagChildren[i];
  396. let pos = roleTransform.convertToNodeSpaceAR(node.getWorldPosition())
  397. let posData: PosData = {
  398. node: node,
  399. hero: null,
  400. bLock: false,
  401. posID: posID,
  402. pos: pos,
  403. posNumber: -1
  404. }
  405. this.bagPosList.push(posData);
  406. posID++;
  407. }
  408. let attackChildren = this.attackNode.children
  409. for (let i = 0; i < attackChildren.length; i++) {
  410. let node = attackChildren[i];
  411. let posNumber = this.battleControl.getPosIDByIndex(i)
  412. if(posNumber != -1){
  413. node.active = true;
  414. let mapDataPos = this.battleControl.getPosition(posNumber)
  415. let posXX = MapDataPosToView(mapDataPos.x,mapDataPos.y)
  416. node.position = posXX
  417. let posData: PosData = {
  418. node: node,
  419. hero: null,
  420. bLock: false,
  421. posID: posID,
  422. pos: new Vec3(posXX.x, posXX.y, 0),
  423. posNumber: posNumber
  424. }
  425. this.attackPosList.push(posData);
  426. this.attackPosMap.set(posNumber, posData);
  427. posID++;
  428. }
  429. else {
  430. node.active = false;
  431. }
  432. }
  433. }
  434. reset(){
  435. let mapConf = ZombieMapConf.data[this.mapID.toString()]
  436. if(!mapConf){
  437. console.log("地图配置错误")
  438. return
  439. }
  440. let offset = mapConf.OffsetArray
  441. if(offset){
  442. baseOffset.x = offset[0]
  443. baseOffset.y = offset[1]
  444. }
  445. else{
  446. baseOffset.x = 0
  447. baseOffset.y = 0
  448. }
  449. let attackChildren = this.attackNode.children
  450. for (let i = 0; i < attackChildren.length; i++) {
  451. let node = attackChildren[i];
  452. let posNumber = this.battleControl.getPosIDByIndex(i)
  453. if(posNumber != -1){
  454. node.active = true;
  455. let mapDataPos = this.battleControl.getPosition(posNumber)
  456. let posXX = MapDataPosToView(mapDataPos.x,mapDataPos.y)
  457. node.position = posXX
  458. let posData: PosData = this.attackPosList[i]
  459. if(!posData){
  460. posData = {
  461. node: node,
  462. hero: null,
  463. bLock: false,
  464. posID: this.bagPosList.length+i,
  465. pos: new Vec3(posXX.x, posXX.y, 0),
  466. posNumber: posNumber
  467. }
  468. this.attackPosList.push(posData);
  469. }
  470. else{
  471. posData.posID = this.bagPosList.length+i;
  472. posData.pos = new Vec3(posXX.x, posXX.y, 0);
  473. posData.posNumber = posNumber;
  474. if(posData.hero){
  475. posData.hero.position = posData.pos;
  476. }
  477. }
  478. this.attackPosMap.set(posNumber, posData);
  479. }
  480. else {
  481. node.active = false;
  482. }
  483. }
  484. let path = "texture/tower/"+mapConf.Background+"/spriteFrame"
  485. this.load("package",path, SpriteFrame, (res: SpriteFrame) => {
  486. this.mapSprite.spriteFrame = res
  487. })
  488. this.bStart = false;
  489. this.waitTime = 5;
  490. this.gameTime = 0;
  491. this.radiusNode.active = false;
  492. }
  493. private initPool() {
  494. //初始化池
  495. let queue = new AsyncQueue();
  496. queue.pushMulti("InitPool", async (next: NextFunction, params: any, args: any) => {
  497. Framework.tips.setTipsNode("package", "prefab/ui/tips/tips_flash", "Label", () => {
  498. next && next();
  499. });
  500. });
  501. queue.complete = () => {
  502. //this._loginEx();
  503. };
  504. queue.play();
  505. //this._loginEx();
  506. }
  507. addHero() {
  508. let posID = -1;
  509. for (let i = 0; i < this.bagPosList.length; i++) {
  510. if(this.bagPosList[i].hero == null){
  511. posID = this.bagPosList[i].posID;
  512. break;
  513. }
  514. }
  515. if(posID == -1) {
  516. console.log("没有空位了");
  517. return;
  518. }
  519. //添加英雄
  520. let heroID = Math.floor(Math.random() * this.heroModelList.length)%this.heroModelList.length + 1;
  521. let heroData = ZombieHeroDataPool.getObject();
  522. heroData.init(heroID,1,posID)
  523. let node:Node = null;
  524. if(this.heroPool[heroID] == null){
  525. this.heroPool[heroID] = [];
  526. }
  527. else {
  528. if(this.heroPool[heroID].length > 0){
  529. node = this.heroPool[heroID].pop();
  530. }
  531. }
  532. if(node == null){
  533. node = instantiate(this.heroModelList[heroID-1]);
  534. node.parent = this.roleNode;
  535. this.heroList.push(node);
  536. }
  537. let hero = node.getComponent(Hero);
  538. hero.resetData(heroData);
  539. //用完就还
  540. ZombieHeroDataPool.putObject(heroData);
  541. hero.posIndex = posID;
  542. let posData = this.bagPosList[posID];
  543. if(!posData){
  544. return;
  545. }
  546. posData.hero = node;
  547. node.position = posData.pos;
  548. console.log("添加英雄", node.position);
  549. this.checkMerge(node);
  550. }
  551. checkMerge(node:Node) {
  552. let hero = node.getComponent(Hero);
  553. if(!hero) {
  554. return;
  555. }
  556. let bFind = false;
  557. if(this.isAutoMerge && !hero.isLock && hero.posIndex < this.bagPosList.length){
  558. for (let i = 0; i < this.attackPosList.length; i++) {
  559. let dstPosData = this.attackPosList[i];
  560. if(dstPosData.hero != null && dstPosData.hero != node){
  561. let dstHero = dstPosData.hero.getComponent(Hero);
  562. if((!dstHero.isLock) && dstHero.typeID == hero.typeID && dstHero.level == hero.level){
  563. if(this.mergeHero(node, dstPosData.hero)){
  564. bFind = true;
  565. break;
  566. }
  567. }
  568. }
  569. }
  570. if(!bFind){
  571. for (let i = 0; i < this.bagPosList.length; i++) {
  572. let dstPosData = this.bagPosList[i];
  573. if(dstPosData.hero != null && dstPosData.hero != node){
  574. let dstHero = dstPosData.hero.getComponent(Hero);
  575. if((!dstHero.isLock) && dstHero.typeID == hero.typeID && dstHero.level == hero.level){
  576. if(this.mergeHero(node, dstPosData.hero))
  577. break;
  578. }
  579. }
  580. }
  581. }
  582. }
  583. }
  584. //合并英雄
  585. mergeHero(srcNode:Node, dstNode:Node) {
  586. let dstHero = dstNode.getComponent(Hero);
  587. if(dstHero.isLock){
  588. return false;
  589. }
  590. dstHero.isLock = true;
  591. // srcNode.setSiblingIndex(this.bagPosList.length+this.attackPosList.length)
  592. srcNode.getComponent(Hero).flyTo(dstNode.position,()=>{
  593. if(isValid(dstHero)){
  594. dstHero.isLock = false;
  595. dstHero.levelUp()
  596. if(dstHero.posIndex >= this.bagPosList.length){
  597. let index = dstHero.posIndex - this.bagPosList.length;
  598. this.battleControl.levelUp(index)
  599. }
  600. this.levelUpEffectIndex = this.levelUpEffectIndex++%this.levelUpEffect.length;
  601. this.levelUpEffect[this.levelUpEffectIndex].position = dstNode.position
  602. this.levelUpEffect[this.levelUpEffectIndex].active = true
  603. this.levelUpEffect[this.levelUpEffectIndex].getComponent(sp.Skeleton).setAnimation(0, "animation", false)
  604. this.removeHeroPos(srcNode)
  605. this.checkMerge(dstNode)
  606. }
  607. })
  608. return true;
  609. }
  610. addEnemy(eventData: BattleEventData_EnemyBorn) {
  611. //添加敌人
  612. let node:Node = null;
  613. if(this.enemyPool.length > 0){
  614. node = this.enemyPool.pop();
  615. }
  616. else {
  617. node = instantiate(this.ememyModelList[0]);
  618. node.parent = this.roleNode;
  619. }
  620. node.setSiblingIndex(0)
  621. node.getComponent(Enemy).resetData(eventData.typeID,eventData.ID,MapDataPosToView(eventData.position.x,eventData.position.y),eventData.life,eventData.lifeMax)
  622. node.getComponent(Enemy).startMove("move1")
  623. this.enemyMap.set(eventData.ID,node);
  624. }
  625. onClickStart() {
  626. this.bStart = true;
  627. }
  628. onClickStop() {
  629. this.bStart = false;
  630. }
  631. onClickAddHero() {
  632. Framework.audio.playEffect(AudioID.Click);
  633. this.addHero();
  634. }
  635. //重置坐标
  636. resetHeroPos(heroNode:Node) {
  637. let hero = heroNode.getComponent(Hero)
  638. if(!hero) {
  639. return;
  640. }
  641. let posID = hero.posIndex;
  642. if(posID != -1){
  643. if(posID < this.bagPosList.length)
  644. heroNode.position = this.bagPosList[posID].pos;
  645. else if(posID < this.bagPosList.length + this.attackPosList.length){
  646. heroNode.position = this.attackPosList[posID - this.bagPosList.length].pos;
  647. this.battleControl.addHeroInPos(hero.typeID,hero.level,posID - this.bagPosList.length)
  648. }
  649. }
  650. }
  651. //设置新坐标
  652. setHeroPos(hero:Node,newPosID:number) {
  653. let posID = hero.getComponent(Hero).posIndex;
  654. if(posID != -1){
  655. if(posID < this.bagPosList.length)
  656. this.bagPosList[posID].hero = null;
  657. else if(posID < this.bagPosList.length + this.attackPosList.length){
  658. this.attackPosList[posID - this.bagPosList.length].hero = null;
  659. }
  660. }
  661. if(newPosID != -1){
  662. if(newPosID < this.bagPosList.length){
  663. this.bagPosList[newPosID].hero = hero;
  664. hero.position = this.bagPosList[newPosID].pos;
  665. }
  666. else if(newPosID < this.bagPosList.length + this.attackPosList.length){
  667. let index = newPosID - this.bagPosList.length;
  668. this.attackPosList[index].hero = hero;
  669. hero.position = this.attackPosList[index].pos;
  670. let heroObj = hero.getComponent(Hero)
  671. this.battleControl.addHeroInPos(heroObj.typeID,heroObj.level,index)
  672. }
  673. hero.getComponent(Hero).posIndex = newPosID
  674. }
  675. }
  676. removeHeroPos(hero:Node) {
  677. let posID = hero.getComponent(Hero).posIndex;
  678. if(posID != -1){
  679. this.heroList.splice(this.heroList.indexOf(hero), 1)
  680. this.heroPool[hero.getComponent(Hero).typeID].push(hero)
  681. hero.getComponent(Hero).clearData();
  682. if(posID < this.bagPosList.length)
  683. this.bagPosList[posID].hero = null;
  684. else if(posID < this.bagPosList.length + this.attackPosList.length){
  685. this.attackPosList[posID - this.bagPosList.length].hero = null;
  686. this.battleControl.removeHeroInPos(posID - this.bagPosList.length)
  687. }
  688. }
  689. }
  690. changeHeroPos(hero1:Node,hero2:Node) {
  691. let posID1 = hero1.getComponent(Hero).posIndex;
  692. let posID2 = hero2.getComponent(Hero).posIndex;
  693. hero1.getComponent(Hero).posIndex = posID2
  694. hero2.getComponent(Hero).posIndex = posID1
  695. if(posID1 != -1){
  696. if(posID1 < this.bagPosList.length){
  697. hero2.position = this.bagPosList[posID1].pos;
  698. this.bagPosList[posID1].hero = hero2;
  699. }
  700. else if(posID1 < this.bagPosList.length + this.attackPosList.length){
  701. hero2.position = this.attackPosList[posID1 - this.bagPosList.length].pos;
  702. let index = posID1 - this.bagPosList.length;
  703. this.attackPosList[index].hero = hero2;
  704. let heroObj = hero2.getComponent(Hero)
  705. this.battleControl.addHeroInPos(heroObj.typeID,heroObj.level,index)
  706. }
  707. hero2.getComponent(Hero).stand()
  708. }
  709. if(posID2 != -1){
  710. if(posID2 < this.bagPosList.length){
  711. hero1.position = this.bagPosList[posID2].pos;
  712. this.bagPosList[posID2].hero = hero1;
  713. }
  714. else if(posID2 < this.bagPosList.length + this.attackPosList.length){
  715. hero1.position = this.attackPosList[posID2 - this.bagPosList.length].pos;
  716. let index = posID2 - this.bagPosList.length;
  717. this.attackPosList[index].hero = hero1;
  718. let heroObj = hero1.getComponent(Hero)
  719. this.battleControl.addHeroInPos(heroObj.typeID,heroObj.level,index)
  720. }
  721. hero1.getComponent(Hero).stand()
  722. }
  723. }
  724. addHurt(pos:Vec3,value:number){
  725. let node:Node = null;
  726. if(this.hurtPool.length > 0){
  727. node = this.hurtPool.pop();
  728. }
  729. else {
  730. node = instantiate(this.hurtModelList[0]);
  731. node.parent = this.roleNode;
  732. }
  733. node.position = pos;
  734. this.hurtList.push(node);
  735. node.getComponent(Hurt).hurt(value,()=>{
  736. this.hurtList.splice(this.hurtList.indexOf(node), 1)
  737. this.hurtPool.push(node)
  738. })
  739. }
  740. updateSiblingIndex() {
  741. let children = this.roleNode.children
  742. children.sort((a, b) => {
  743. let battleNodeA = a.getComponent(BattleNodeBase);
  744. let battleNodeB = b.getComponent(BattleNodeBase);
  745. if (!battleNodeA || !battleNodeB) {
  746. return 0;
  747. }
  748. let priorityA = battleNodeA.priority
  749. let priorityB = battleNodeB.priority
  750. if (priorityA != priorityB) {
  751. return priorityA - priorityB;
  752. }
  753. if(this.touchStart == b){
  754. return -1;
  755. }
  756. if(this.touchStart == a){
  757. return 1;
  758. }
  759. //特殊状态
  760. if(battleNodeB.isLock){
  761. return -1;
  762. }
  763. if(battleNodeA.isLock){
  764. return 1;
  765. }
  766. if (a.position.y != b.position.y) {
  767. return b.position.y - a.position.y;
  768. }
  769. else {
  770. a.position.x - b.position.x
  771. }
  772. });
  773. for (let i = 0; i < children.length; i++) {
  774. children[i].setSiblingIndex(i);
  775. }
  776. }
  777. setRadius(radius:number){
  778. this.radiusNode.scale = v3(0.4*radius,0.4*radius,1)
  779. }
  780. }