SysMovable.ts 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /** @format */
  2. import {ComCocosNode as ComCocosNode} from '../components/ComCocosNode'
  3. import {ComMovable} from '../components/ComMovable'
  4. import {ComTransform} from '../components/ComTransform'
  5. import {ECSSystem} from '../lib/ECSSystem'
  6. import {FightWorld} from '../worlds/FightWorld'
  7. import {ComDie} from '../components/ComDie'
  8. import {ComBullet} from '../components/ComBullet'
  9. import {EventProcess} from '../core/EventProcess'
  10. import {cObject} from '../../collision/Object'
  11. import {GenFilterKey} from '../lib/ECSComponent'
  12. import {ComRole} from '../components/ComRole'
  13. import {BULLET_EFFECT_TYPE, BULLET_FLY_TYPE, BULLET_TYPE} from '../../enums/Enum'
  14. import {ComBehaviorTree} from '../components/ComBehaviorTree'
  15. import {ComSkill} from '../components/ComSkill'
  16. import {GameData} from '../../data/GameData'
  17. import {Data} from '../../GameControl'
  18. const FILTER_MOVE = GenFilterKey([ComMovable, ComTransform, ComCocosNode], [ComDie])
  19. export class SysMovable extends ECSSystem {
  20. /** 连接 */
  21. public onAdd(world: FightWorld): void {}
  22. /** 断开连接 */
  23. public onRemove(world: FightWorld): void {}
  24. /** 添加实体 */
  25. public onEntityEnter(world: FightWorld, entity: number): void {}
  26. /** */
  27. public onEntityLeave(world: FightWorld, entity: number): void {}
  28. /** 更新 */
  29. public onUpdate(world: FightWorld, dt: number): void {
  30. let comCocosNode: ComCocosNode,
  31. comMovable: ComMovable,
  32. comTrans: ComTransform,
  33. comBullet: ComBullet,
  34. comRole: ComRole,
  35. nextPoint: cc.Vec2,
  36. offsetX: number,
  37. offsetY: number,
  38. offsetLen: number,
  39. moveLen: number
  40. world.getFilter(FILTER_MOVE).walk((entity: number) => {
  41. comCocosNode = world.getComponent(entity, ComCocosNode)
  42. if (!comCocosNode.loaded) return
  43. comMovable = world.getComponent(entity, ComMovable)
  44. comTrans = world.getComponent(entity, ComTransform)
  45. comBullet = world.getComponent(entity, ComBullet)
  46. comRole = world.getComponent(entity, ComRole)
  47. let comSpTransform = world.getComponent(comRole?.spineEntity, ComTransform)
  48. let comSpComCocosNode = world.getComponent(comRole?.spineEntity, ComCocosNode)
  49. if (comRole && world.isEnter(entity)) {
  50. return
  51. }
  52. if (comBullet && comBullet.bulletCfg.isEjection && comBullet.ejectionEnemy) {
  53. //子弹位置每帧修正
  54. let enemyComTransform = world.getComponent(comBullet.ejectionEnemy, ComTransform)
  55. if (!world.isDie(comBullet.ejectionEnemy)) {
  56. if (comMovable.points[comMovable.points.length - 1]) {
  57. comMovable.points[comMovable.points.length - 1].x = enemyComTransform.x
  58. comMovable.points[comMovable.points.length - 1].y =
  59. enemyComTransform.y + enemyComTransform.halfHeight
  60. }
  61. } else {
  62. world.removeBulletEntity(entity)
  63. }
  64. }
  65. if (comMovable.speed <= 0 || comMovable.pointIdx >= comMovable.points.length || comMovable.pointIdx < 0) {
  66. return
  67. }
  68. moveLen = comMovable.speed * dt
  69. while (moveLen > 0 && comMovable.pointIdx < comMovable.points.length && comMovable.pointIdx >= 0) {
  70. nextPoint = comMovable.points[comMovable.pointIdx]
  71. if (!nextPoint) {
  72. comMovable.pointIdx++
  73. break
  74. }
  75. offsetX = nextPoint.x - comTrans.x
  76. offsetY = nextPoint.y - comTrans.y
  77. offsetLen = Math.sqrt(offsetX * offsetX + offsetY * offsetY)
  78. //每次有新的移`动点改变当前方向
  79. let newDirX = offsetX / offsetLen || comTrans.dir.x
  80. let changeDirX = Math.sign(newDirX) != Math.sign(comTrans.dir.x)
  81. comTrans.dir.x = newDirX
  82. comTrans.dir.y = offsetY / offsetLen
  83. if (changeDirX) {
  84. comCocosNode.node?.getComponent(EventProcess)?.syncDir(comTrans.dir)
  85. comSpComCocosNode?.node?.getComponent(EventProcess)?.syncDir(comTrans.dir)
  86. }
  87. if (comBullet && comBullet.bulletCfg.flyType != BULLET_FLY_TYPE.normal) {
  88. let angle = Math.atan2(comTrans.dir.y, comTrans.dir.x)
  89. comCocosNode.node.angle = cc.misc.radiansToDegrees(angle)
  90. }
  91. if (offsetLen <= moveLen) {
  92. moveLen -= offsetLen
  93. let lastX = comTrans.x
  94. comTrans.x = nextPoint.x
  95. if (comRole && comRole.group == Data.game.gFriend && lastX < 100 && comTrans.x > 100) {
  96. world.fightCore.addRightAreaFriendNum(entity)
  97. }
  98. comTrans.y = nextPoint.y
  99. //同步spine位置
  100. if (comSpTransform) {
  101. comSpTransform.x = comTrans.x
  102. comSpTransform.y = comTrans.y
  103. }
  104. comMovable.pointIdx++
  105. // 此处必须让所有的cObject位置更新
  106. comCocosNode.node?.getComponents(cObject).forEach(cObject => {
  107. cObject.setPosition(cc.v3(comTrans.x, comTrans.y, 0))
  108. })
  109. continue
  110. }
  111. let lastX = comTrans.x
  112. comTrans.x += (moveLen * offsetX) / offsetLen
  113. if (comRole && comRole.group == Data.game.gFriend && lastX < 100 && comTrans.x > 100) {
  114. world.fightCore.addRightAreaFriendNum(entity)
  115. }
  116. comTrans.y += (moveLen * offsetY) / offsetLen
  117. //同步spine位置
  118. if (comSpTransform) {
  119. comSpTransform.x = comTrans.x
  120. comSpTransform.y = comTrans.y
  121. }
  122. // 此处必须让所有的cObject位置更新
  123. comCocosNode.node?.getComponents(cObject).forEach(cObject => {
  124. cObject.setPosition(cc.v3(comTrans.x, comTrans.y, 0))
  125. })
  126. moveLen = -1
  127. }
  128. if (comMovable.pointIdx >= comMovable.points.length) {
  129. //是子弹的话就移除
  130. if (comBullet) {
  131. if (comBullet.bulletCfg.type == BULLET_TYPE.skill) {
  132. world.createCardBulletSkill(comBullet, 0, cc.v3(comTrans.x, comTrans.y, 0))
  133. }
  134. if (
  135. (comBullet.bulletCfg.isEjection && !comBullet.ejectionEnemy) ||
  136. !comBullet.bulletCfg.isEjection
  137. ) {
  138. let endPoint = comMovable.points[comMovable.points.length - 1]
  139. if (comBullet.bulletCfg.effectType.includes(BULLET_EFFECT_TYPE.skillEjection) && endPoint) {
  140. // 反弹的法线向量
  141. let n: cc.Vec2
  142. if (endPoint.y < Data.game.fightAreaMaxY && endPoint.y > Data.game.fightAreaMinY) {
  143. n = cc.v2(endPoint.x > 0 ? -1 : 1, 0)
  144. } else {
  145. n = cc.v2(0, endPoint.y > 0 ? -1 : 1)
  146. }
  147. let curDir = cc.v2(comTrans.dir.x, comTrans.dir.y)
  148. let bDirection = curDir.sub(n.mul(2 * curDir.dot(n)))
  149. let nextPos = world.findIntersection(endPoint, bDirection)
  150. comMovable.pointIdx = 0
  151. comMovable.points.length = 0
  152. comMovable.points.push(nextPos)
  153. let angle = Math.atan2(bDirection.y, bDirection.x)
  154. comCocosNode.node.angle = cc.misc.radiansToDegrees(angle)
  155. //不让速度为0
  156. return
  157. } else {
  158. world.removeBulletEntity(entity)
  159. }
  160. }
  161. }
  162. let comSkill = world.getComponent(entity, ComSkill)
  163. if (comSkill && comMovable.speed > 0) {
  164. world.removeSkillEntity(entity)
  165. }
  166. world.changeMoveSpeed(entity, 0)
  167. }
  168. return false
  169. })
  170. }
  171. }