TeamUI.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /** @format */
  2. import {BaseUI} from './BaseUI'
  3. import {Data, Mgr} from '../GameControl'
  4. import {ccUtils} from '../utils/ccUtils'
  5. import {list, node, observer, render} from '../mobx/observer'
  6. import {msgCmd} from '../proto/msg_cmd'
  7. import {i18nLabel} from '../uiutils/i18nLabel'
  8. import List from '../uiutils/List'
  9. import {UI} from '../enums/UI'
  10. import {card} from '../proto/typedef'
  11. import {GOODS, LANGUAGE_TYPE, PROFESSION} from '../enums/Enum'
  12. import {ICard, ICardDebris, IRole} from '../interface/GlobalInterface'
  13. import {SOUND} from '../enums/Sound'
  14. import {RoleQualityConfig} from '../config/RoleQualityConfig'
  15. import {RoleConfig} from '../config/RoleConfig'
  16. const {ccclass, property} = cc._decorator
  17. enum ToggleType {
  18. role = 0,
  19. card = 1,
  20. }
  21. @ccclass
  22. @observer
  23. export class TeamUI extends BaseUI {
  24. toggleIndex: ToggleType = ToggleType.role
  25. @list('roleList')
  26. roleList: List
  27. @list('cardList')
  28. cardList: List
  29. @node('touchSpine')
  30. touchSpine: cc.Node
  31. @node('touchCard')
  32. touchCard: cc.Node
  33. @node('guidePrevent')
  34. guidePrevent: cc.Node
  35. @node('guide')
  36. guide: cc.Node
  37. @node('levelGuide')
  38. levelGuide: cc.Node
  39. @node('cardGuide')
  40. cardGuide: cc.Node
  41. teamLock: boolean[] = []
  42. cardLock: boolean[] = []
  43. touchStart: boolean = false
  44. touchMoveStart: boolean = false
  45. touchStartPos: cc.Vec2
  46. roleNodes: cc.Node[] = []
  47. cardNodes: cc.Node[] = []
  48. curList: List
  49. curMoveIRole: IRole
  50. curMoveICard: ICard
  51. cardDebris: ICardDebris[] = []
  52. canMergeCardDebris: ICardDebris[] = []
  53. touchSkeleton: sp.Skeleton
  54. isUserGuide: boolean = false
  55. curProfessionChoose: PROFESSION = PROFESSION.all
  56. roles: IRole[] = []
  57. onLoad() {
  58. this.touchSkeleton = cc.find('spine', this.touchSpine).getComponent(sp.Skeleton)
  59. }
  60. onShow(args, fromUI: number) {
  61. Mgr.ui.showTop(this, [GOODS.coin, GOODS.diamond])
  62. Mgr.ui.showFoot(this)
  63. this.toggleIndex = ToggleType.role
  64. this.initToggle()
  65. this.touchNodeReset()
  66. this.onFreshRole()
  67. //this.onFreshCard()
  68. //一级引导,拖入上阵
  69. let showOneGuide = Mgr.global.tryShowUserGuide(['1_3'])
  70. //打完第一关后引导,第二个英雄图标
  71. this.levelGuide.active = false
  72. if (Data.user.roles.length >= 2) {
  73. this.scheduleOnce(() => {
  74. this.levelGuide.active = Mgr.global.tryShowUserGuide(['2_2'], () => {
  75. Mgr.ui.show(UI.RoleUI, Data.user.roles[1])
  76. })
  77. })
  78. }
  79. //卡牌技能引导
  80. if (Data.user.cardDebris.length > 0 && Data.user.cardDebris[0].cfg.num <= Data.user.cardDebris[0].num) {
  81. this.cardGuide['cardDebris'] = Data.user.cardDebris[0]
  82. this.cardGuide.active = Mgr.global.tryShowUserGuide(['24_3', '24_4'])
  83. }
  84. this.isUserGuide = showOneGuide
  85. this.guidePrevent.active = showOneGuide
  86. this.guide.active = showOneGuide
  87. if (showOneGuide) {
  88. let finger = cc.find('guide_finger', this.guide)
  89. finger.stopAllActions()
  90. let startPos = cc.v2(381, 110)
  91. finger.setPosition(startPos)
  92. let endPos = cc.v2(startPos.x - 1000, startPos.y)
  93. let height = 50 // 抛物线高度
  94. let bezier = [startPos, cc.v2(startPos.x - 500, startPos.y + height), endPos]
  95. // 创建一个缓动动作
  96. cc.tween(finger)
  97. .then(cc.fadeIn(0.5))
  98. .then(cc.bezierTo(2, bezier))
  99. .then(cc.fadeOut(0.5))
  100. .delay(2)
  101. .call(() => {
  102. finger.setPosition(startPos)
  103. })
  104. .union()
  105. .repeatForever()
  106. .start()
  107. }
  108. this.showBreakRed()
  109. }
  110. onHide(): any {
  111. Mgr.event.removeAll(this)
  112. }
  113. onTop(preID: number, ...args) {
  114. this.showBreakRed()
  115. }
  116. initTeam() {
  117. //显示英雄
  118. this.teamLock.length = 0
  119. let roleNodes = cc.find('roles', this.node).children
  120. this.roleNodes = roleNodes
  121. for (let i = 0; i < roleNodes.length; i++) {
  122. let node = roleNodes[i]
  123. let lockLevel = Data.user.roleSlotLv
  124. let role = cc.find('role', node)
  125. let iRole = Data.user.teamRole[PROFESSION[node.name] - 1]
  126. role.active = iRole && iRole.hero.sid != ''
  127. let isLock = Data.user.level < lockLevel[i]
  128. let canAdd = !role.active && !isLock
  129. cc.find('lock', node).active = isLock
  130. cc.find('canAdd', node).active = canAdd
  131. if (isLock) {
  132. let lb = cc.find('lock/lb', node).getComponent(i18nLabel)
  133. lb.setParamByIndex(lockLevel[i].toString(), 0)
  134. }
  135. if (canAdd) {
  136. let addAni = cc.find('canAdd/add_1', node)
  137. addAni.stopAllActions()
  138. addAni.opacity = 255
  139. addAni.runAction(cc.sequence(cc.fadeTo(1, 100), cc.fadeTo(1, 255)).repeatForever())
  140. }
  141. this.teamLock.push(isLock)
  142. if (role.active) {
  143. //ccUtils.setLabel('lv.' + iRole.hero.lv, role, 'lv')
  144. Mgr.global.initRoleSpine(iRole, role, 'spine')
  145. //ccUtils.instantChildren(cc.find('stars/star', role), iRole.grade)
  146. }
  147. node['iRole'] = iRole
  148. }
  149. ccUtils.setLabel(Mgr.global.getPowerString(), this.node, 'power')
  150. }
  151. initTeamCard() {
  152. //显示技能
  153. this.cardLock.length = 0
  154. let cardsNodes = ccUtils.instantChildren(cc.find('skills/skill', this.node), Data.user.maxFightCardNum)
  155. this.cardNodes = cardsNodes
  156. for (let i = 0; i < Data.user.maxFightCardNum; i++) {
  157. let node = cardsNodes[i]
  158. let lockLevel = Data.user.cardSlotLv
  159. let card = cc.find('card', node)
  160. let iCard = Data.user.teamCard[i]
  161. card.active = iCard && +iCard.card.sid > 0
  162. let isLock = Data.user.level < lockLevel[i]
  163. cc.find('lock', node).active = isLock
  164. if (isLock) {
  165. let lb = cc.find('lock/lb', node).getComponent(i18nLabel)
  166. lb.setParamByIndex(lockLevel[i].toString(), 0)
  167. }
  168. if (card.active) Mgr.global.initCardItem(iCard, card, this)
  169. node['iCard'] = iCard
  170. }
  171. //grocery_buy
  172. ccUtils.setLabel(Mgr.global.getPowerString(), this.node, 'power')
  173. }
  174. initToggle() {
  175. ccUtils.setTogglesChecked(this.toggleIndex, this.node, 'toggles')
  176. ccUtils.setTogglesChecked(this.curProfessionChoose, this.roleList.node, 'toggles')
  177. this.roleList.node.active = this.toggleIndex == ToggleType.role
  178. this.cardList.node.active = this.toggleIndex == ToggleType.card
  179. this.curList = this.toggleIndex == ToggleType.role ? this.roleList : this.cardList
  180. //装备需要解锁才能开启
  181. let equipToggleNode = cc.find('toggles/toggle2', this.node)
  182. ccUtils.setTogglesInteract(false, equipToggleNode)
  183. cc.find('lock', equipToggleNode).active = true
  184. }
  185. initRoleListItem(node: cc.Node, index: number) {
  186. let iRole = this.roles[index]
  187. this.loadTexImg(`TeamUI/card_bottom_${iRole.cfg.quality}`, node, 'card_bottom')
  188. ccUtils.setLabel(iRole.cfg.name, node, 'name')
  189. Mgr.global.initRoleSpine(iRole, node, 'spine')
  190. let icon_battle = cc.find('icon_battle', node)
  191. icon_battle.active = Mgr.goods.roleIsUp(iRole)
  192. //升级需要资源
  193. cc.find('red_dot', node).active = icon_battle.active && Mgr.goods.checkRoleLevelUpNeed(iRole).canUp
  194. node['iRole'] = iRole
  195. this.initNodeUpTouch(node)
  196. let nextRoleConfig = RoleConfig[iRole.cfg.ID + 1]
  197. ccUtils.setLabel(nextRoleConfig ? `${iRole.hero.num}/${nextRoleConfig.consume}` : 'MAX', node, 'numPb/num')
  198. ccUtils.setProgress(nextRoleConfig ? iRole.hero.num / nextRoleConfig.consume : 1, node, 'numPb/pb')
  199. ccUtils.setLabel(`${iRole.hero.lv}`, node, 'lv')
  200. cc.find('arrow_1', node).active = Mgr.goods.checkRoleBreakNeed(iRole).canUp
  201. cc.tween(cc.find('arrow_1', node))
  202. .then(cc.tween().to(1, {y: -93}).to(1, {y: -103}))
  203. .repeatForever()
  204. .start()
  205. }
  206. initCardListItem(node: cc.Node, index: number) {
  207. let isDebris = false
  208. let iCard = null
  209. let cardDebris = null
  210. if (index < this.canMergeCardDebris.length) {
  211. cardDebris = this.canMergeCardDebris[index]
  212. isDebris = true
  213. } else if (
  214. index >= this.canMergeCardDebris.length &&
  215. index < Data.user.cards.length + this.canMergeCardDebris.length
  216. ) {
  217. iCard = Data.user.cards[index - this.canMergeCardDebris.length]
  218. isDebris = false
  219. } else if (index >= Data.user.cards.length + this.canMergeCardDebris.length) {
  220. cardDebris = this.cardDebris[index - Data.user.cards.length - this.canMergeCardDebris.length]
  221. isDebris = true
  222. }
  223. let itemParent = cc.find('itemParent', node)
  224. let debris = cc.find('debris', node)
  225. debris.active = isDebris
  226. if (isDebris) {
  227. let cardDebrisNode = Mgr.global.initCardDebrisItem(cardDebris, itemParent, this)
  228. cc.find('debris', cardDebrisNode).active = false
  229. let isMax = cardDebris.num >= cardDebris.cfg.num
  230. let conflate = cc.find('conflate', debris)
  231. conflate.active = isMax
  232. conflate.stopAllActions()
  233. conflate.opacity = 0
  234. cc.tween(conflate)
  235. .then(cc.sequence(cc.fadeIn(0.5), cc.fadeOut(0.5)))
  236. .repeatForever()
  237. .start()
  238. cc.find('pb_all', debris).active = isMax
  239. cc.find('pb', debris).active = !isMax
  240. ccUtils.setLabel(`${cardDebris.num} / ${cardDebris.cfg.num}`, debris, 'num')
  241. ccUtils.setProgress(cardDebris.num / cardDebris.cfg.num, debris, 'pb')
  242. } else {
  243. Mgr.global.initCardItem(iCard, itemParent, this)
  244. }
  245. let icon_battle = cc.find('icon_battle', node)
  246. icon_battle.active = !isDebris && Mgr.goods.cardIsUp(iCard)
  247. //升级需要资源
  248. cc.find('red_dot', node).active =
  249. icon_battle.active &&
  250. iCard &&
  251. (Mgr.goods.checkCardLevelUpNeed(iCard).canUp || Mgr.goods.checkCardBreakNeed(iCard).canUp)
  252. node['iCard'] = iCard
  253. node['cardDebris'] = cardDebris
  254. node['isDebris'] = isDebris
  255. this.initNodeUpTouch(node, isDebris)
  256. }
  257. initNodeUpTouch(node, noTouch?: boolean) {
  258. node.off(cc.Node.EventType.TOUCH_START, this.onTouchUpStart, this)
  259. node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchUpMove, this)
  260. node.off(cc.Node.EventType.TOUCH_END, this.onTouchUpEnd, this)
  261. node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchUpCancel, this)
  262. node.on(cc.Node.EventType.TOUCH_START, this.onTouchUpStart, this)
  263. node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchUpMove, this)
  264. node.on(cc.Node.EventType.TOUCH_END, this.onTouchUpEnd, this)
  265. node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchUpCancel, this)
  266. }
  267. touchNodeReset() {
  268. this.touchStart = false
  269. this.touchMoveStart = false
  270. this.touchSpine.y = -1500
  271. this.touchCard.y = -1500
  272. this.curList.scrollView.enabled = true
  273. }
  274. showBreakRed() {
  275. //有英雄突破
  276. cc.find('btn_break/red_dot', this.node).active = Data.user.roles.some(
  277. role => Mgr.goods.checkRoleBreakNeed(role).canUp,
  278. )
  279. }
  280. //触发事件=======================================
  281. @render
  282. onFreshRole() {
  283. let rolesDirty = Data.user.rolesDirty
  284. this.initTeam()
  285. this.roles = Data.user.roles.filter(
  286. role => role.cfg.profession == this.curProfessionChoose || !this.curProfessionChoose,
  287. )
  288. this.roleList.numItems = this.roles.length
  289. cc.find('roleList/lb', this.node).active = Data.user.roles.length == 0
  290. }
  291. @render
  292. onFreshCard() {
  293. return
  294. let cardsDirty = Data.user.cardsDirty
  295. this.initTeamCard()
  296. this.cardDebris.length = 0
  297. this.canMergeCardDebris.length = 0
  298. Data.user.cardDebris.forEach(item => {
  299. if (!Data.user.cards.find(card => card.cfg.ID - card.cfg.quality + 1 == item.cfg.card)) {
  300. if (item.num >= item.cfg.num) {
  301. this.canMergeCardDebris.push(item)
  302. } else {
  303. this.cardDebris.push(item)
  304. }
  305. }
  306. })
  307. Mgr.goods.sortCardDebris(this.cardDebris)
  308. Mgr.goods.sortCardDebris(this.canMergeCardDebris)
  309. cc.find('cardList/lb', this.node).active = Data.user.cards.length + Data.user.cardDebris.length == 0
  310. this.cardList.numItems = Data.user.cards.length + this.cardDebris.length + this.canMergeCardDebris.length
  311. }
  312. // 点击事件=======================================
  313. onToggleClick(e) {
  314. Mgr.audio.playSFX(SOUND.toggleClick)
  315. this.toggleIndex = e.target.parent.children.indexOf(e.target)
  316. this.initToggle()
  317. }
  318. onProfessionToggleClick(e) {
  319. Mgr.audio.playSFX(SOUND.toggleClick)
  320. this.curProfessionChoose = PROFESSION[e.target.name as string]
  321. this.onFreshRole()
  322. }
  323. onBreakClick() {
  324. Mgr.ui.show(UI.RoleBreakUI)
  325. }
  326. onTeamRoleClick(e) {
  327. if (e.target['iRole']) {
  328. Mgr.ui.show(UI.RoleUI, e.target['iRole'])
  329. }
  330. }
  331. onCardMergeClick(e) {
  332. this.cardGuide.active = false
  333. if (e.target['cardDebris']) {
  334. let cardDebris: ICardDebris = e.target['cardDebris']
  335. if (cardDebris.num >= cardDebris.cfg.num) {
  336. Mgr.net.send(msgCmd.cmd_debris_merge, {id: cardDebris.cfg.ID})
  337. }
  338. }
  339. }
  340. onTouchUpStart(e) {
  341. let node = e.target
  342. if (this.levelGuide.active) {
  343. return
  344. }
  345. if (this.touchMoveStart) return
  346. this.touchStart = true
  347. if (this.toggleIndex) {
  348. if (!node['isDebris']) {
  349. Mgr.global.initCardItem(node['iCard'], this.touchCard, this)
  350. this.curMoveICard = node['iCard']
  351. }
  352. } else {
  353. this.curMoveIRole = node['iRole']
  354. }
  355. this.touchStartPos = ccUtils.convertWorldPosToNode(this.node, ccUtils.convertTouchPosToWorld(e))
  356. }
  357. onTouchUpMove(e) {
  358. if (this.touchStart) {
  359. let node = e.target
  360. let pos = ccUtils.convertWorldPosToNode(this.node, ccUtils.convertTouchPosToWorld(e))
  361. if (pos.y > this.touchStartPos.y + e.target.height / 2 && !this.touchMoveStart) {
  362. this.curList.scrollView.enabled = false
  363. this.touchMoveStart = true
  364. }
  365. if (this.touchMoveStart) {
  366. if (this.toggleIndex) {
  367. if (!node['isDebris']) {
  368. this.touchCard.setPosition(cc.v3(pos))
  369. }
  370. } else {
  371. this.touchSpine.setPosition(cc.v3(pos))
  372. if (
  373. !this.touchSkeleton.skeletonData ||
  374. this.touchSkeleton.skeletonData.name != node['iRole'].cfg.url
  375. ) {
  376. this.touchSkeleton.skeletonData = Data.main.roleSpineMap.get(node['iRole'].cfg.url)
  377. }
  378. }
  379. }
  380. }
  381. }
  382. onTouchUpEnd(e) {
  383. if (!this.touchStart) return
  384. if (this.isUserGuide) return
  385. if (!this.touchMoveStart) {
  386. let pos = ccUtils.convertWorldPosToNode(this.node, ccUtils.convertTouchPosToWorld(e))
  387. if (pos.sub(this.touchStartPos).len() < 1) {
  388. if (this.toggleIndex) {
  389. if (e.target['isDebris']) {
  390. let cardDebris: ICardDebris = e.target['cardDebris']
  391. if (cardDebris.num >= cardDebris.cfg.num) {
  392. Mgr.net.send(msgCmd.cmd_debris_merge, {id: cardDebris.cfg.ID})
  393. }
  394. } else {
  395. }
  396. } else {
  397. Mgr.ui.show(UI.RoleUI, e.target['iRole'])
  398. }
  399. }
  400. }
  401. this.touchNodeReset()
  402. }
  403. onTouchUpCancel(e) {
  404. if (!this.touchStart) return
  405. if (this.toggleIndex && e.target['isDebris']) return
  406. this.touchNodeReset()
  407. let nodes = this.toggleIndex == ToggleType.role ? this.roleNodes : this.cardNodes
  408. for (let i = 0; i < nodes.length; i++) {
  409. if (ccUtils.containsP(nodes[i], ccUtils.convertTouchPosToWorld(e))) {
  410. console.log('上阵', i)
  411. if (this.isUserGuide) {
  412. if (i != 0) {
  413. return
  414. } else {
  415. this.guidePrevent.active = false
  416. this.guide.active = false
  417. //一级引导,回退主界面
  418. Mgr.global.tryShowUserGuide(['1_4'])
  419. }
  420. }
  421. if (cc.find('lock', nodes[i]).active) {
  422. Mgr.ui.tip(LANGUAGE_TYPE.slotLock)
  423. return
  424. }
  425. if (this.toggleIndex == ToggleType.role) {
  426. if (Data.user.teamRole.find(v => v && v.hero.sid == this.curMoveIRole.hero.sid)) {
  427. Mgr.ui.tip(LANGUAGE_TYPE.samePos)
  428. return
  429. }
  430. if (PROFESSION[nodes[i].name] != this.curMoveIRole.cfg.profession) {
  431. Mgr.ui.tip(LANGUAGE_TYPE.professionError)
  432. return
  433. }
  434. } else {
  435. if (Data.user.teamCard.find(v => v && v.card.sid == this.curMoveICard.card.sid)) {
  436. Mgr.ui.tip(LANGUAGE_TYPE.samePos)
  437. return
  438. }
  439. }
  440. Mgr.net.send(msgCmd.cmd_embattle_battle, {
  441. sid: this.toggleIndex == ToggleType.role ? this.curMoveIRole.hero.sid : this.curMoveICard.card.sid,
  442. pos: PROFESSION[nodes[i].name],
  443. skill: this.toggleIndex == ToggleType.card,
  444. })
  445. break
  446. }
  447. }
  448. }
  449. }