import { _decorator, Component, Node, Prefab, instantiate, SpriteFrame } from 'cc'; import { ActorManager } from '../Entity/Actor/ActorManager'; import DataManager from '../Global/DataManager'; import { JoyStickManager } from '../UI/JoyStickManager'; import { ResourceManager } from '../Global/ResourceManager'; import { PrefabPathEnum, TexturePathEnum } from '../Enum'; import NetworkManager from '../Global/NetworkManager'; import ObjectPoolManager from '../Global/ObjectPoolManager'; import { BulletManager } from '../Entity/Bullet/BulletManager'; import { ApiMsgEnum, EntityTypeEnum, IMsgServerSync, InputTypeEnum } from '../Common'; import { toFixed } from '../Utils'; const { ccclass } = _decorator; @ccclass('BattleManager') export class BattleManager extends Component { stage: Node ui: Node isInited = false onLoad() { this.stage = DataManager.Instance.stage = this.node.getChildByName("Stage") this.ui = this.node.getChildByName("UI") } async start() { this.clearGame() await this.loadRes() this.initScene() await this.connectServer() NetworkManager.Instance.listenMsg(ApiMsgEnum.MsgServerSync, this.handleSync); this.isInited = true } clearGame() { this.stage.destroyAllChildren() this.ui.destroyAllChildren() } async loadRes() { const list = [] for (const type in PrefabPathEnum) { const p = ResourceManager.Instance.loadRes(PrefabPathEnum[type], Prefab).then((prefab) => { DataManager.Instance.prefabMap.set(type, prefab) }) list.push(p) } for (const type in TexturePathEnum) { const p = ResourceManager.Instance.loadDir(TexturePathEnum[type], SpriteFrame).then((spriteFrames) => { DataManager.Instance.textureMap.set(type, spriteFrames) }) list.push(p) } await Promise.all(list) } async initScene() { this.initJoyStick() this.initShoot() this.initMap() } async connectServer() { if (!await NetworkManager.Instance.connect().catch(() => false)) { await new Promise((resolve) => setTimeout(resolve, 1000)) await this.connectServer() } } initJoyStick() { const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.JoyStick) const joySitck = instantiate(prefab) joySitck.setParent(this.ui) const jm = DataManager.Instance.jm = joySitck.getComponent(JoyStickManager) jm.init() } initShoot() { const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.Shoot) const shoot = instantiate(prefab) shoot.setParent(this.ui) } initMap() { const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.Map1) const map = instantiate(prefab) map.setParent(this.stage) } handleSync({ inputs }: IMsgServerSync) { for (const input of inputs) { DataManager.Instance.applyInput(input) } } update(dt: number) { if (!this.isInited) { return } this.render() this.tick(dt) } tick(dt: number) { this.tickPlayer(dt) this.tickGlobal(dt) } tickPlayer(dt: number) { for (const p of DataManager.Instance.state.players) { const playerManager = DataManager.Instance.actorMap.get(p.id) if (!playerManager) { return } playerManager.tick(dt) } } tickGlobal(dt: number) { NetworkManager.Instance.sendMsg(ApiMsgEnum.MsgClientSync, { input: { type: InputTypeEnum.TimePast, dt: toFixed(dt), } }) } render() { this.renderPlayer() this.renderBullet() } renderPlayer() { for (const p of DataManager.Instance.state.players) { let playerManager = DataManager.Instance.actorMap.get(p.id) if (!playerManager) { const playerPrefab = DataManager.Instance.prefabMap.get(p.type) const player = instantiate(playerPrefab) player.setParent(this.stage) playerManager = player.addComponent(ActorManager) DataManager.Instance.actorMap.set(p.id, playerManager) playerManager.init(p) } else { playerManager.render(p) } } } renderBullet() { for (const b of DataManager.Instance.state.bullets) { let bulletManager = DataManager.Instance.bulletMap.get(b.id) if (!bulletManager) { const bullet = ObjectPoolManager.Instance.get(b.type) bulletManager = bullet.getComponent(BulletManager) || bullet.addComponent(BulletManager) DataManager.Instance.bulletMap.set(b.id, bulletManager) bulletManager.init(b) } else { bulletManager.render(b) } } } }