import { Tween, tween, Vec3, _decorator } from "cc"; import { EntityManager } from "../../Base/EntityManager"; import { EntityTypeEnum, IBullet, IVec2 } from "../../Common"; import { EntityStateEnum, EventEnum } from "../../Enum"; import DataManager from "../../Global/DataManager"; import EventManager from "../../Global/EventManager"; import ObjectPoolManager from "../../Global/ObjectPoolManager"; import { rad2Angle } from "../../Utils"; import { ExplosionManager } from "../Explosion/ExplosionManager"; import { BulletStateMachine } from "./BulletStateMachine"; const { ccclass } = _decorator; @ccclass("BulletManager") export class BulletManager extends EntityManager implements IBullet { //静态数据 id: number; owner: number; type: EntityTypeEnum; //动态数据 position: IVec2; direction: IVec2; private angle: number; private tw: Tween; private targetPos: Vec3; init({ id, owner, type }: IBullet) { this.id = id; this.owner = owner; this.type = type; this.fsm = this.addComponent(BulletStateMachine); this.fsm.init(type); this.state = EntityStateEnum.Idle; this.node.active = false; this.targetPos = undefined; this.angle = undefined; EventManager.Instance.on(EventEnum.ExplosionBorn, this.handleExplosion, this); } handleExplosion(id: number, { x, y }: IVec2) { if (this.id !== id) { return; } const explosion = ObjectPoolManager.Instance.get(EntityTypeEnum.Explosion); const explosionManager = explosion.getComponent(ExplosionManager) || explosion.addComponent(ExplosionManager); explosionManager.init(EntityTypeEnum.Explosion, { x, y, }); EventManager.Instance.off(EventEnum.ExplosionBorn, this.handleExplosion, this); ObjectPoolManager.Instance.ret(this.node); DataManager.Instance.bulletMap.delete(this.id); } render(data: IBullet) { this.renderPosition(data); this.renderDirection(data); } renderPosition(data: IBullet) { const newPos = new Vec3(data.position.x, data.position.y); if (!this.targetPos) { this.node.active = true; this.node.setPosition(newPos); this.targetPos = new Vec3(newPos); } else if (!this.targetPos.equals(newPos)) { this.tw?.stop(); this.node.setPosition(this.targetPos); this.targetPos.set(newPos); this.tw = tween(this.node) .to(0.1, { position: this.targetPos, }) .start(); } // this.node.setPosition(data.position.x, data.position.y) } renderDirection(data: IBullet) { if (this.angle === undefined) { const { x, y } = data.direction; const side = Math.sqrt(x * x + y * y); this.angle = x > 0 ? rad2Angle(Math.asin(y / side)) : rad2Angle(Math.asin(-y / side)) + 180; } this.node.setRotationFromEuler(0, 0, this.angle); // let angle: number, sign: number // if (x !== 0) { // angle = x > 0 ? rad2Angle(Math.atan(y / x)) : rad2Angle(Math.atan(-y / x)) + 180 // sign = x > 0 ? 1 : -1 // } else { // angle = rad2Angle(Math.PI / 2) // sign = y > 0 ? 1 : -1 // } // this.node.setRotationFromEuler(0, 0, sign * angle) } }