TeamUI.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  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. Mgr.ui.hide(UI.CurrencyUI)
  107. } else {
  108. Mgr.ui.show(UI.CurrencyUI, [GOODS.coin, GOODS.diamond])
  109. }
  110. this.showBreakRed()
  111. }
  112. onHide(): any {
  113. Mgr.event.removeAll(this)
  114. }
  115. onTop(preID: number, ...args) {
  116. this.showBreakRed()
  117. }
  118. initTeam() {
  119. //显示英雄
  120. this.teamLock.length = 0
  121. let roleNodes = ccUtils.instantChildren(cc.find('roles/item', this.node), Data.user.maxFightRoleNum)
  122. this.roleNodes = roleNodes
  123. for (let i = 0; i < Data.user.maxFightRoleNum; i++) {
  124. let node = roleNodes[i]
  125. let lockLevel = Data.user.roleSlotLv
  126. let role = cc.find('role', node)
  127. let iRole = Data.user.teamRole[i]
  128. role.active = iRole && iRole.hero.sid != ''
  129. let isLock = Data.user.level < lockLevel[i]
  130. let canAdd = !role.active && !isLock
  131. cc.find('lock', node).active = isLock
  132. cc.find('canAdd', node).active = canAdd
  133. if (isLock) {
  134. let lb = cc.find('lock/lb', node).getComponent(i18nLabel)
  135. lb.setParamByIndex(lockLevel[i].toString(), 0)
  136. }
  137. if (canAdd) {
  138. let addAni = cc.find('canAdd/add_4', node)
  139. addAni.stopAllActions()
  140. addAni.opacity = 255
  141. addAni.runAction(cc.sequence(cc.fadeTo(1, 100), cc.fadeTo(1, 255)).repeatForever())
  142. }
  143. this.teamLock.push(isLock)
  144. if (role.active) {
  145. this.loadTexImg(`Public/role/base_light_${iRole.cfg.qualityType}`, role, 'base_light')
  146. this.loadTexImg(`Public/role/role_type_${iRole.cfg.profession}`, role, 'role_type')
  147. this.loadTexImg(`Public/role/base_level_${iRole.cfg.qualityType}`, role, 'base_level')
  148. ccUtils.setLabel('lv.' + iRole.hero.lv, role, 'lv')
  149. Mgr.global.initRoleSpine(iRole, role, 'spine')
  150. ccUtils.instantChildren(cc.find('stars/star', role), iRole.grade)
  151. ccUtils.setLabel(iRole.cfg.cost.toString(), role, 'cost/lb')
  152. }
  153. node['iRole'] = iRole
  154. }
  155. ccUtils.setLabel(Mgr.global.getPowerString(), this.node, 'power')
  156. }
  157. initTeamCard() {
  158. //显示技能
  159. this.cardLock.length = 0
  160. let cardsNodes = ccUtils.instantChildren(cc.find('skills/skill', this.node), Data.user.maxFightCardNum)
  161. this.cardNodes = cardsNodes
  162. for (let i = 0; i < Data.user.maxFightCardNum; i++) {
  163. let node = cardsNodes[i]
  164. let lockLevel = Data.user.cardSlotLv
  165. let card = cc.find('card', node)
  166. let iCard = Data.user.teamCard[i]
  167. card.active = iCard && +iCard.card.sid > 0
  168. let isLock = Data.user.level < lockLevel[i]
  169. cc.find('lock', node).active = isLock
  170. if (isLock) {
  171. let lb = cc.find('lock/lb', node).getComponent(i18nLabel)
  172. lb.setParamByIndex(lockLevel[i].toString(), 0)
  173. }
  174. if (card.active) Mgr.global.initCardItem(iCard, card, this)
  175. node['iCard'] = iCard
  176. }
  177. //grocery_buy
  178. ccUtils.setLabel(Mgr.global.getPowerString(), this.node, 'power')
  179. }
  180. initToggle() {
  181. ccUtils.setTogglesChecked(this.toggleIndex, this.node, 'toggles')
  182. this.roleList.node.active = this.toggleIndex == ToggleType.role
  183. this.cardList.node.active = this.toggleIndex == ToggleType.card
  184. this.curList = this.toggleIndex == ToggleType.role ? this.roleList : this.cardList
  185. }
  186. initRoleListItem(node: cc.Node, index: number) {
  187. let iRole = Data.user.roles[index]
  188. let role = cc.find('role', node)
  189. Mgr.global.initRoleItem(iRole, role, this)
  190. let icon_battle = cc.find('icon_battle', node)
  191. icon_battle.active = Mgr.goods.roleIsUp(iRole)
  192. //升级需要资源
  193. cc.find('red_dots', node).active = icon_battle.active && Mgr.goods.checkRoleLevelUpNeed(iRole).canUp
  194. node['iRole'] = iRole
  195. this.initNodeUpTouch(node)
  196. }
  197. initCardListItem(node: cc.Node, index: number) {
  198. let isDebris = false
  199. let iCard = null
  200. let cardDebris = null
  201. if (index < this.canMergeCardDebris.length) {
  202. cardDebris = this.canMergeCardDebris[index]
  203. isDebris = true
  204. } else if (
  205. index >= this.canMergeCardDebris.length &&
  206. index < Data.user.cards.length + this.canMergeCardDebris.length
  207. ) {
  208. iCard = Data.user.cards[index - this.canMergeCardDebris.length]
  209. isDebris = false
  210. } else if (index >= Data.user.cards.length + this.canMergeCardDebris.length) {
  211. cardDebris = this.cardDebris[index - Data.user.cards.length - this.canMergeCardDebris.length]
  212. isDebris = true
  213. }
  214. let itemParent = cc.find('itemParent', node)
  215. let debris = cc.find('debris', node)
  216. debris.active = isDebris
  217. if (isDebris) {
  218. let cardDebrisNode = Mgr.global.initCardDebrisItem(cardDebris, itemParent, this)
  219. cc.find('debris', cardDebrisNode).active = false
  220. let isMax = cardDebris.num >= cardDebris.cfg.num
  221. let conflate = cc.find('conflate', debris)
  222. conflate.active = isMax
  223. conflate.stopAllActions()
  224. conflate.opacity = 0
  225. cc.tween(conflate)
  226. .then(cc.sequence(cc.fadeIn(0.5), cc.fadeOut(0.5)))
  227. .repeatForever()
  228. .start()
  229. cc.find('pb_all', debris).active = isMax
  230. cc.find('pb', debris).active = !isMax
  231. ccUtils.setLabel(`${cardDebris.num} / ${cardDebris.cfg.num}`, debris, 'num')
  232. ccUtils.setProgress(cardDebris.num / cardDebris.cfg.num, debris, 'pb')
  233. } else {
  234. Mgr.global.initCardItem(iCard, itemParent, this)
  235. }
  236. let icon_battle = cc.find('icon_battle', node)
  237. icon_battle.active = !isDebris && Mgr.goods.cardIsUp(iCard)
  238. //升级需要资源
  239. cc.find('red_dots', node).active =
  240. icon_battle.active &&
  241. iCard &&
  242. (Mgr.goods.checkCardLevelUpNeed(iCard).canUp || Mgr.goods.checkCardBreakNeed(iCard).canUp)
  243. node['iCard'] = iCard
  244. node['cardDebris'] = cardDebris
  245. node['isDebris'] = isDebris
  246. this.initNodeUpTouch(node, isDebris)
  247. }
  248. initNodeUpTouch(node, noTouch?: boolean) {
  249. node.off(cc.Node.EventType.TOUCH_START, this.onTouchUpStart, this)
  250. node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchUpMove, this)
  251. node.off(cc.Node.EventType.TOUCH_END, this.onTouchUpEnd, this)
  252. node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchUpCancel, this)
  253. node.on(cc.Node.EventType.TOUCH_START, this.onTouchUpStart, this)
  254. node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchUpMove, this)
  255. node.on(cc.Node.EventType.TOUCH_END, this.onTouchUpEnd, this)
  256. node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchUpCancel, this)
  257. }
  258. touchNodeReset() {
  259. this.touchStart = false
  260. this.touchMoveStart = false
  261. this.touchSpine.y = -1500
  262. this.touchCard.y = -1500
  263. this.curList.scrollView.enabled = true
  264. }
  265. showBreakRed() {
  266. //有英雄突破
  267. cc.find('btn_break/red_dots', this.node).active = Data.user.roles.some(
  268. role => Mgr.goods.checkRoleBreakNeed(role).canUp,
  269. )
  270. }
  271. //触发事件=======================================
  272. @render
  273. onFreshRole() {
  274. let rolesDirty = Data.user.rolesDirty
  275. this.initTeam()
  276. this.roleList.numItems = Data.user.roles.length
  277. cc.find('roleList/lb', this.node).active = Data.user.roles.length == 0
  278. }
  279. @render
  280. onFreshCard() {
  281. let cardsDirty = Data.user.cardsDirty
  282. this.initTeamCard()
  283. this.cardDebris.length = 0
  284. this.canMergeCardDebris.length = 0
  285. Data.user.cardDebris.forEach(item => {
  286. if (!Data.user.cards.find(card => card.cfg.ID - card.cfg.quality + 1 == item.cfg.card)) {
  287. if (item.num >= item.cfg.num) {
  288. this.canMergeCardDebris.push(item)
  289. } else {
  290. this.cardDebris.push(item)
  291. }
  292. }
  293. })
  294. Mgr.goods.sortCardDebris(this.cardDebris)
  295. Mgr.goods.sortCardDebris(this.canMergeCardDebris)
  296. cc.find('cardList/lb', this.node).active = Data.user.cards.length + Data.user.cardDebris.length == 0
  297. this.cardList.numItems = Data.user.cards.length + this.cardDebris.length + this.canMergeCardDebris.length
  298. }
  299. // 点击事件=======================================
  300. onToggleClick(e) {
  301. Mgr.audio.playSFX(SOUND.toggleClick)
  302. this.toggleIndex = e.target.parent.children.indexOf(e.target)
  303. this.initToggle()
  304. }
  305. onBreakClick() {
  306. Mgr.ui.show(UI.RoleBreakUI)
  307. }
  308. onTeamRoleClick(e) {
  309. if (e.target['iRole']) {
  310. Mgr.ui.show(UI.RoleUI, e.target['iRole'])
  311. }
  312. }
  313. onCardMergeClick(e) {
  314. this.cardGuide.active = false
  315. if (e.target['cardDebris']) {
  316. let cardDebris: ICardDebris = e.target['cardDebris']
  317. if (cardDebris.num >= cardDebris.cfg.num) {
  318. Mgr.net.send(msgCmd.cmd_debris_merge, {id: cardDebris.cfg.ID})
  319. }
  320. }
  321. }
  322. onTouchUpStart(e) {
  323. let node = e.target
  324. if (this.levelGuide.active) {
  325. return
  326. }
  327. if (this.touchMoveStart) return
  328. this.touchStart = true
  329. if (this.toggleIndex) {
  330. if (!node['isDebris']) {
  331. Mgr.global.initCardItem(node['iCard'], this.touchCard, this)
  332. this.curMoveICard = node['iCard']
  333. }
  334. } else {
  335. this.curMoveIRole = node['iRole']
  336. }
  337. this.touchStartPos = ccUtils.convertWorldPosToNode(this.node, ccUtils.convertTouchPosToWorld(e))
  338. }
  339. onTouchUpMove(e) {
  340. if (this.touchStart) {
  341. let node = e.target
  342. let pos = ccUtils.convertWorldPosToNode(this.node, ccUtils.convertTouchPosToWorld(e))
  343. if (pos.x < this.touchStartPos.x - e.target.width && !this.touchMoveStart) {
  344. this.curList.scrollView.enabled = false
  345. this.touchMoveStart = true
  346. }
  347. if (this.touchMoveStart) {
  348. if (this.toggleIndex) {
  349. if (!node['isDebris']) {
  350. this.touchCard.setPosition(cc.v3(pos))
  351. }
  352. } else {
  353. this.touchSpine.setPosition(cc.v3(pos))
  354. if (
  355. !this.touchSkeleton.skeletonData ||
  356. this.touchSkeleton.skeletonData.name != node['iRole'].cfg.url
  357. ) {
  358. this.touchSkeleton.skeletonData = Data.main.roleSpineMap.get(node['iRole'].cfg.url)
  359. }
  360. }
  361. }
  362. }
  363. }
  364. onTouchUpEnd(e) {
  365. if (!this.touchStart) return
  366. if (this.isUserGuide) return
  367. if (!this.touchMoveStart) {
  368. let pos = ccUtils.convertWorldPosToNode(this.node, ccUtils.convertTouchPosToWorld(e))
  369. if (pos.sub(this.touchStartPos).len() < 1) {
  370. if (this.toggleIndex) {
  371. if (e.target['isDebris']) {
  372. let cardDebris: ICardDebris = e.target['cardDebris']
  373. if (cardDebris.num >= cardDebris.cfg.num) {
  374. Mgr.net.send(msgCmd.cmd_debris_merge, {id: cardDebris.cfg.ID})
  375. }
  376. } else {
  377. }
  378. } else {
  379. Mgr.ui.show(UI.RoleUI, e.target['iRole'])
  380. }
  381. }
  382. }
  383. this.touchNodeReset()
  384. }
  385. onTouchUpCancel(e) {
  386. if (!this.touchStart) return
  387. if (this.toggleIndex && e.target['isDebris']) return
  388. this.touchNodeReset()
  389. let nodes = this.toggleIndex == ToggleType.role ? this.roleNodes : this.cardNodes
  390. for (let i = 0; i < nodes.length; i++) {
  391. if (ccUtils.containsP(nodes[i], ccUtils.convertTouchPosToWorld(e))) {
  392. console.log('上阵', i)
  393. if (this.isUserGuide) {
  394. if (i != 0) {
  395. return
  396. } else {
  397. this.guidePrevent.active = false
  398. this.guide.active = false
  399. //一级引导,回退主界面
  400. Mgr.global.tryShowUserGuide(['1_4'])
  401. }
  402. }
  403. if (cc.find('lock', nodes[i]).active) {
  404. Mgr.ui.tip(LANGUAGE_TYPE.slotLock)
  405. return
  406. }
  407. if (this.toggleIndex == ToggleType.role) {
  408. if (Data.user.teamRole.find(v => v && v.hero.sid == this.curMoveIRole.hero.sid)) {
  409. Mgr.ui.tip(LANGUAGE_TYPE.samePos)
  410. return
  411. }
  412. let sameNameIndex = Data.user.teamRole.findIndex(
  413. v => v && Math.floor(v.hero.id / 100) == Math.floor(this.curMoveIRole.hero.id / 100),
  414. )
  415. if (sameNameIndex >= 0 && sameNameIndex != i) {
  416. Mgr.ui.tip(LANGUAGE_TYPE.sameRoleOrCard)
  417. return
  418. }
  419. } else {
  420. if (Data.user.teamCard.find(v => v && v.card.sid == this.curMoveICard.card.sid)) {
  421. Mgr.ui.tip(LANGUAGE_TYPE.samePos)
  422. return
  423. }
  424. }
  425. Mgr.net.send(msgCmd.cmd_embattle_battle, {
  426. sid: this.toggleIndex == ToggleType.role ? this.curMoveIRole.hero.sid : this.curMoveICard.card.sid,
  427. pos: i + 1,
  428. skill: this.toggleIndex == ToggleType.card,
  429. })
  430. break
  431. }
  432. }
  433. }
  434. }