/** @format */ import {ComCocosNode as ComCocosNode} from '../components/ComCocosNode' import {ComMovable} from '../components/ComMovable' import {ComTransform} from '../components/ComTransform' import {ECSSystem} from '../lib/ECSSystem' import {FightWorld} from '../worlds/FightWorld' import {ComDie} from '../components/ComDie' import {ComBullet} from '../components/ComBullet' import {EventProcess} from '../core/EventProcess' import {cObject} from '../../collision/Object' import {GenFilterKey} from '../lib/ECSComponent' import {ComRole} from '../components/ComRole' import {BULLET_EFFECT_TYPE, BULLET_FLY_TYPE, BULLET_TYPE} from '../../enums/Enum' import {ComBehaviorTree} from '../components/ComBehaviorTree' import {ComSkill} from '../components/ComSkill' import {GameData} from '../../data/GameData' import {Data} from '../../GameControl' const FILTER_MOVE = GenFilterKey([ComMovable, ComTransform, ComCocosNode], [ComDie]) export class SysMovable extends ECSSystem { /** 连接 */ public onAdd(world: FightWorld): void {} /** 断开连接 */ public onRemove(world: FightWorld): void {} /** 添加实体 */ public onEntityEnter(world: FightWorld, entity: number): void {} /** */ public onEntityLeave(world: FightWorld, entity: number): void {} /** 更新 */ public onUpdate(world: FightWorld, dt: number): void { let comCocosNode: ComCocosNode, comMovable: ComMovable, comTrans: ComTransform, comBullet: ComBullet, comRole: ComRole, nextPoint: cc.Vec2, offsetX: number, offsetY: number, offsetLen: number, moveLen: number world.getFilter(FILTER_MOVE).walk((entity: number) => { comCocosNode = world.getComponent(entity, ComCocosNode) if (!comCocosNode.loaded) return comMovable = world.getComponent(entity, ComMovable) comTrans = world.getComponent(entity, ComTransform) comBullet = world.getComponent(entity, ComBullet) comRole = world.getComponent(entity, ComRole) let comSpTransform = world.getComponent(comRole?.spineEntity, ComTransform) let comSpComCocosNode = world.getComponent(comRole?.spineEntity, ComCocosNode) if (comRole && world.isEnter(entity)) { return } if (comBullet && comBullet.bulletCfg.isEjection && comBullet.ejectionEnemy) { //子弹位置每帧修正 let enemyComTransform = world.getComponent(comBullet.ejectionEnemy, ComTransform) if (!world.isDie(comBullet.ejectionEnemy)) { if (comMovable.points[comMovable.points.length - 1]) { comMovable.points[comMovable.points.length - 1].x = enemyComTransform.x comMovable.points[comMovable.points.length - 1].y = enemyComTransform.y + enemyComTransform.halfHeight } } else { world.removeBulletEntity(entity) } } if (comMovable.speed <= 0 || comMovable.pointIdx >= comMovable.points.length || comMovable.pointIdx < 0) { return } moveLen = comMovable.speed * dt while (moveLen > 0 && comMovable.pointIdx < comMovable.points.length && comMovable.pointIdx >= 0) { nextPoint = comMovable.points[comMovable.pointIdx] if (!nextPoint) { comMovable.pointIdx++ break } offsetX = nextPoint.x - comTrans.x offsetY = nextPoint.y - comTrans.y offsetLen = Math.sqrt(offsetX * offsetX + offsetY * offsetY) //每次有新的移`动点改变当前方向 let newDirX = offsetX / offsetLen || comTrans.dir.x let changeDirX = Math.sign(newDirX) != Math.sign(comTrans.dir.x) comTrans.dir.x = newDirX comTrans.dir.y = offsetY / offsetLen if (changeDirX) { comCocosNode.node?.getComponent(EventProcess)?.syncDir(comTrans.dir) comSpComCocosNode?.node?.getComponent(EventProcess)?.syncDir(comTrans.dir) } if (comBullet && comBullet.bulletCfg.flyType != BULLET_FLY_TYPE.normal) { let angle = Math.atan2(comTrans.dir.y, comTrans.dir.x) comCocosNode.node.angle = cc.misc.radiansToDegrees(angle) } if (offsetLen <= moveLen) { moveLen -= offsetLen let lastX = comTrans.x comTrans.x = nextPoint.x if (comRole && comRole.group == Data.game.gFriend && lastX < 100 && comTrans.x > 100) { world.fightCore.addRightAreaFriendNum(entity) } comTrans.y = nextPoint.y //同步spine位置 if (comSpTransform) { comSpTransform.x = comTrans.x comSpTransform.y = comTrans.y } comMovable.pointIdx++ // 此处必须让所有的cObject位置更新 comCocosNode.node?.getComponents(cObject).forEach(cObject => { cObject.setPosition(cc.v3(comTrans.x, comTrans.y, 0)) }) continue } let lastX = comTrans.x comTrans.x += (moveLen * offsetX) / offsetLen if (comRole && comRole.group == Data.game.gFriend && lastX < 100 && comTrans.x > 100) { world.fightCore.addRightAreaFriendNum(entity) } comTrans.y += (moveLen * offsetY) / offsetLen //同步spine位置 if (comSpTransform) { comSpTransform.x = comTrans.x comSpTransform.y = comTrans.y } // 此处必须让所有的cObject位置更新 comCocosNode.node?.getComponents(cObject).forEach(cObject => { cObject.setPosition(cc.v3(comTrans.x, comTrans.y, 0)) }) moveLen = -1 } if (comMovable.pointIdx >= comMovable.points.length) { //是子弹的话就移除 if (comBullet) { if (comBullet.bulletCfg.type == BULLET_TYPE.skill) { world.createCardBulletSkill(comBullet, 0, cc.v3(comTrans.x, comTrans.y, 0)) } if ( (comBullet.bulletCfg.isEjection && !comBullet.ejectionEnemy) || !comBullet.bulletCfg.isEjection ) { let endPoint = comMovable.points[comMovable.points.length - 1] if (comBullet.bulletCfg.effectType.includes(BULLET_EFFECT_TYPE.skillEjection) && endPoint) { // 反弹的法线向量 let n: cc.Vec2 if (endPoint.y < Data.game.fightAreaMaxY && endPoint.y > Data.game.fightAreaMinY) { n = cc.v2(endPoint.x > 0 ? -1 : 1, 0) } else { n = cc.v2(0, endPoint.y > 0 ? -1 : 1) } let curDir = cc.v2(comTrans.dir.x, comTrans.dir.y) let bDirection = curDir.sub(n.mul(2 * curDir.dot(n))) let nextPos = world.findIntersection(endPoint, bDirection) comMovable.pointIdx = 0 comMovable.points.length = 0 comMovable.points.push(nextPos) let angle = Math.atan2(bDirection.y, bDirection.x) comCocosNode.node.angle = cc.misc.radiansToDegrees(angle) //不让速度为0 return } else { world.removeBulletEntity(entity) } } } let comSkill = world.getComponent(entity, ComSkill) if (comSkill && comMovable.speed > 0) { world.removeSkillEntity(entity) } world.changeMoveSpeed(entity, 0) } return false }) } }