RoleEventProcess.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /** @format */
  2. import {
  3. EventAttack,
  4. EventBase,
  5. EventDie,
  6. EventGraphicsDraw,
  7. EventHPChange,
  8. EventRoleTip,
  9. EventSkill,
  10. EventType,
  11. } from './NodeEvent'
  12. import {ccUtils} from '../../utils/ccUtils'
  13. import FrameAnimation from '../../uiutils/FrameAnimation'
  14. import {Data} from '../../GameControl'
  15. import {IRoleConfig} from '../../config/RoleConfig'
  16. import {GAME_ROLE_TIP, MONSTER_TYPE, ROLE_TYPE} from '../../enums/Enum'
  17. import {EventProcess} from './EventProcess'
  18. import {IBuff} from './GameInterface'
  19. import {FlashColor} from './FlashColor'
  20. const {ccclass, property} = cc._decorator
  21. @ccclass
  22. export class RoleEventProcess extends EventProcess {
  23. public roleConfig: IRoleConfig
  24. public isFriend: boolean
  25. private eventDeath: EventDie
  26. private eventRoleTipMap: Map<string, EventRoleTip[]>
  27. private eventRoleTipTimeMap: Map<string, number>
  28. private frameAniNode: cc.Node
  29. private roleTipParents: Map<string, cc.Node>
  30. private roleHeight: number = 100
  31. private roleWidth: number = 60
  32. private HPNode: cc.Node
  33. private HP: cc.Node
  34. private HPS: cc.Node
  35. private HPShield: cc.Node
  36. protected onLoad() {
  37. this.HPNode = cc.find('hpNode', this.node)
  38. this.HP = cc.find('hpNode/HP', this.node)
  39. this.HPShield = cc.find('hpNode/HPshield', this.node)
  40. this.HPS = cc.find('hpNode/HPS', this.node)
  41. this.frameAniNode = cc.find('fa', this.node)
  42. this.roleTipParents = new Map()
  43. this.eventRoleTipMap = new Map()
  44. this.eventRoleTipTimeMap = new Map()
  45. for (let key in GAME_ROLE_TIP) {
  46. let parent = cc.find(`tips/${key}Parent`, this.node)
  47. if (!parent) {
  48. console.error('role预制体tips下缺少' + key + '父节点')
  49. } else {
  50. this.roleTipParents.set(key, parent)
  51. this.eventRoleTipMap.set(key, [])
  52. this.eventRoleTipTimeMap.set(key, 0)
  53. }
  54. }
  55. }
  56. onAttach(): void {
  57. this.frameAnimation = this.frameAniNode.getComponent(FrameAnimation)
  58. this._initHPNode()
  59. }
  60. onDetach(): void {}
  61. init(cfg: IRoleConfig, isFriend: boolean, width: number, height: number) {
  62. this.isFriend = isFriend
  63. this.roleConfig = cfg
  64. this.roleWidth = width
  65. this.roleHeight = height
  66. this.eventRoleTipMap.forEach((value, key) => {
  67. value.length = 0
  68. })
  69. this.node.name = this.roleConfig.url
  70. let entityLb = cc.find('entity', this.node)
  71. if (entityLb) entityLb.color = this.isFriend ? cc.Color.GREEN : cc.Color.RED
  72. this.HPNode.active = false
  73. }
  74. public syncDir(dir: cc.Vec2) {
  75. let scaleRate = 1
  76. this.frameAniNode.scaleX = dir.x >= 0 ? scaleRate : -scaleRate
  77. }
  78. processEvent(event: EventBase): void {
  79. if (!cc.isValid(this.node)) return
  80. switch (event.type) {
  81. case EventType.Enter:
  82. break
  83. case EventType.Stand:
  84. break
  85. case EventType.Run:
  86. break
  87. case EventType.Attack:
  88. let attackEvent: EventAttack = event as EventAttack
  89. this.syncDir(attackEvent.dir)
  90. break
  91. case EventType.Skill:
  92. break
  93. case EventType.RoleTip:
  94. let eventRoleTip: EventRoleTip = event as EventRoleTip
  95. let roleTips = this.eventRoleTipMap.get(eventRoleTip.tipType)
  96. roleTips.push(eventRoleTip)
  97. break
  98. case EventType.Die:
  99. this.eventDeath = event as EventDie
  100. break
  101. case EventType.HPChange:
  102. this._changeHP(event as EventHPChange)
  103. break
  104. // case EventType.BuffChange:
  105. // let eventBuff = event as EventBuffChange
  106. // this.initBuff(eventBuff.buffs)
  107. // break
  108. case EventType.GraphicsDraw:
  109. if (cc.debug.isDisplayStats()) {
  110. this.graphicsDraw(event as EventGraphicsDraw)
  111. } else {
  112. this.graphicsDraw(null)
  113. }
  114. break
  115. }
  116. }
  117. private _initHPNode() {
  118. if (!this.roleConfig) {
  119. console.warn('没有角色配置')
  120. return
  121. }
  122. let hpNode = this.HPNode
  123. let isBase = this.roleConfig.type == ROLE_TYPE.base
  124. //let hpWidth = isBase ? 200 : 100
  125. //修改为配置
  126. let hpWidth = this.roleConfig.hplength
  127. let hpHeight = isBase ? 20 : 10
  128. let roleHeight = this.roleHeight
  129. let baseHeight = 454
  130. let baseDurX = 350 - Data.game.fightSizeMaxX
  131. let baseDurY = 88 - (Data.game.fightSizeMaxY + Data.game.fightSizeMinY) / 2
  132. hpNode.x = isBase ? (this.isFriend ? -1 : 1) * baseDurX : 0
  133. hpNode.y = isBase ? baseHeight / 2 + baseDurY - hpHeight : roleHeight + hpHeight / 2
  134. cc.find('green', this.HP).active = this.isFriend
  135. cc.find('red', this.HP).active = !this.isFriend
  136. this.HP.getComponent(cc.ProgressBar).barSprite = cc
  137. .find(this.isFriend ? 'green' : 'red', this.HP)
  138. .getComponent(cc.Sprite)
  139. this.setHPPbSize(this.HP, hpWidth, hpHeight)
  140. this.setHPPbSize(this.HPShield, hpWidth, hpHeight)
  141. let baseHPbg = cc.find('castle_blood_bottom', hpNode)
  142. baseHPbg.active = isBase
  143. baseHPbg.width = hpWidth + 8
  144. baseHPbg.height = hpHeight + 8
  145. this.HPS.width = hpWidth
  146. this.HPS.x = -hpWidth / 2
  147. this.HPS.height = hpHeight
  148. this.HPS.children.forEach(v => (v.height = hpHeight))
  149. }
  150. private setHPPbSize(node: cc.Node, width: number, height: number) {
  151. node.width = width
  152. node.height = height
  153. let pb = node.getComponent(cc.ProgressBar)
  154. pb.totalLength = width
  155. pb.barSprite.node.x = -width / 2
  156. node.children.forEach(v => (v.height = height))
  157. }
  158. private _changeHP(event: EventHPChange) {
  159. //let lastAllHp = event.HP
  160. let isFriend =
  161. this.roleConfig.type == ROLE_TYPE.normal ||
  162. this.roleConfig.type == ROLE_TYPE.only ||
  163. this.roleConfig.type == ROLE_TYPE.totem
  164. let isBase = this.roleConfig.type == ROLE_TYPE.base
  165. let isBoss = this.roleConfig.type == MONSTER_TYPE.boss
  166. if (!this.HPNode.active && !isBoss && !isBase && (event.HP != event.nowHP || event.shieldHP > 0) && !isFriend)
  167. this.HPNode.active = true
  168. if (!this.HPNode.active) return
  169. let allHp = event.HP
  170. //if (event.lastHP + event.lastShieldHP > lastAllHp) lastAllHp = event.lastHP + event.lastShieldHP
  171. if (event.nowHP + event.shieldHP > allHp) allHp = event.nowHP + event.shieldHP
  172. //let from = event.lastHP / lastAllHp
  173. this.HP.getComponent(cc.ProgressBar).progress = event.nowHP / allHp
  174. //let from = (event.lastHP + event.lastShieldHP) / lastAllHp
  175. this.HPShield.getComponent(cc.ProgressBar).progress = (event.nowHP + event.shieldHP) / allHp
  176. let hpCellNum = Math.ceil(allHp / 100)
  177. //if (hpCellNum > 10) hpCellNum = 10
  178. //修改为固定10格血
  179. if (hpCellNum > 10) hpCellNum = 10
  180. if (hpCellNum != this.HPS.children.length) {
  181. ccUtils.instantChildren(cc.find('hp', this.HPS), hpCellNum)
  182. }
  183. }
  184. private _showNextRoleTip(tipType: string) {
  185. let fightCore = this.world.fightCore
  186. let roleTips = this.eventRoleTipMap.get(tipType)
  187. if (roleTips.length > 0 && this.node.isValid && fightCore.node.isValid) {
  188. let roleTip: EventRoleTip = roleTips.shift() // 取出下一个提示对象
  189. let tipNode = null
  190. let key = roleTip.tipType
  191. let pool = fightCore.roleTipPool.get(key)
  192. if (pool.size() > 0 && pool.size() < 100) {
  193. tipNode = pool.get()
  194. } else {
  195. tipNode = cc.instantiate(Data.game.gameAssetMap.get(`prefab/fight/roleTip/${key}`))
  196. }
  197. let t = cc.tween
  198. let tipX: number, tipY: number, tipOpacity: number, moveTime: number, delayTime: number, tween: cc.Tween
  199. let scale = 1
  200. let actionCallback = () => {
  201. tipNode.removeFromParent()
  202. fightCore.node.isValid && pool.put(tipNode)
  203. }
  204. let attackLbDur = 50
  205. switch (roleTip.tipType) {
  206. case GAME_ROLE_TIP.buffTip:
  207. tipX = 0
  208. tipY = this.roleHeight / 2
  209. tipOpacity = 255
  210. moveTime = 1
  211. tween = t().by(moveTime, {y: this.roleHeight / 2})
  212. let upNode = cc.find('up', tipNode)
  213. upNode.active = roleTip.num == 1
  214. let downNode = cc.find('down', tipNode)
  215. downNode.active = roleTip.num == 2
  216. let showNode = upNode.active ? upNode : downNode
  217. ccUtils.setLabel(roleTip.tip, showNode, 'lb')
  218. break
  219. case GAME_ROLE_TIP.hpTip:
  220. tipX = 0
  221. tipY = 0
  222. tipOpacity = 255
  223. moveTime = 0.5
  224. tween = t().by(moveTime, {y: this.roleHeight / 2})
  225. break
  226. case GAME_ROLE_TIP.critTip:
  227. tipX = Math.randomRangeInt(-this.roleWidth / 4, this.roleWidth / 4)
  228. let left = tipX < 0 ? -1 : 1
  229. tipY = this.roleHeight / 2 + Math.randomRangeInt(0, 20)
  230. scale = 1
  231. tipOpacity = 255
  232. moveTime = 1
  233. tween = t().by(moveTime * 0.4, {
  234. x: (left * this.roleWidth) / 8,
  235. y: this.HP.height + tipNode.height + 30,
  236. })
  237. tween = t().parallel(
  238. tween,
  239. t()
  240. .to(moveTime * 0.1, {scale: 3})
  241. .to(moveTime * 0.3, {scale: 1})
  242. .union(),
  243. )
  244. tween = t().sequence(tween, t().to(moveTime, {opacity: 0}).by(moveTime, {y: 10}).union())
  245. break
  246. case GAME_ROLE_TIP.damageTip:
  247. tipX = this.isFriend ? -attackLbDur : attackLbDur
  248. tipY = this.HP.parent.y - this.HP.height
  249. scale = 2
  250. tipOpacity = 0
  251. moveTime = 0.5
  252. delayTime = 0.5
  253. tween = t().by(moveTime, {y: 30})
  254. tween = t().parallel(tween, t().to(moveTime, {opacity: 255, scale: 1.2}).delay(delayTime))
  255. break
  256. case GAME_ROLE_TIP.missTip:
  257. tipX = this.isFriend ? -attackLbDur : attackLbDur
  258. tipY = this.HP.parent.y - this.HP.height
  259. tipOpacity = 0
  260. moveTime = 0.5
  261. delayTime = 0.5
  262. tween = t().by(moveTime, {y: 30})
  263. tween = t().parallel(tween, t().to(moveTime, {opacity: 255, scale: 1.2}).delay(delayTime))
  264. break
  265. }
  266. if (roleTip.tipType != GAME_ROLE_TIP.buffTip) ccUtils.setLabel(roleTip.tip, tipNode)
  267. this.roleTipParents.get(key).addChild(tipNode)
  268. tipNode.stopAllActions()
  269. tipNode.scale = scale
  270. tipNode.x = tipX
  271. tipNode.y = tipY
  272. tipNode.opacity = tipOpacity
  273. // 执行飘出动画效果
  274. t(tipNode).then(tween).call(actionCallback).start()
  275. }
  276. }
  277. update(dt) {
  278. this.eventRoleTipMap.forEach((roleTips, key) => {
  279. let time = this.eventRoleTipTimeMap.get(key)
  280. if (roleTips.length > 0 && time <= 0) {
  281. this._showNextRoleTip(key)
  282. time = 0.5
  283. }
  284. time -= dt
  285. if (time < 0) time = 0
  286. this.eventRoleTipTimeMap.set(key, time)
  287. })
  288. }
  289. }