TeamUI.ts 18 KB

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