import { Animation, Component, Node, NodePool, Prefab, Tween, Vec2, Vec3, _decorator, game, instantiate, tween, } from 'cc' import FishBase from '../../../fish/script/FishBase' import FishMover from '../../../fish/script/FishMover' import FishUI from '../../../fish/script/FishUI' import { Logger } from '../../engine/utils/Logger' import RandomUtil from '../../engine/utils/RandomUtil' import { FishConfig } from '../config/FishConfig' import { FishInfo } from '../config/FishInfo' import { FishMap } from '../config/FishMap' import { FishMapInfo } from '../config/FishMapInfo' import { FishPathConfig } from '../config/FishPathConfig' import GameMusicHelper from '../utils/GameMusicHelper' import TimeHelper from '../utils/TimeHelper' import ScoreManager from './ScoreManager' import WsManager from './WsManager' import { FishPathInfo } from '../config/FishPathInfo' const { ccclass, property } = _decorator interface dataType { fisn: Array } interface FishType { fishId: string fishInfo: FishInfo fishType: string isDead: number fishPathInfo: Array } interface fishPathInfoType { pathId: string path: Array } interface PathPoint { x: number y: number } // 鱼管理类 @ccclass('FishManager') export default class FishManager extends Component { public static instance: FishManager = null @property({ type: Node }) private fishContainer: Node | null = null @property({ type: [Prefab] }) public fishPrefabList: Array = [] private fishPool: Array = [] private fishList: Map = new Map() private nextRandomFishTime: number = 0 private minRandomTime: number = 2 * (game.frameRate as number) private maxRandomTime: number = 5 * (game.frameRate as number) private isFishMap: boolean = false private mapCount: number = 0 private _fishPosCache: Vec3 onLoad() { WsManager.instance.on(100, this.randomFish, this) FishManager.instance = this this._fishPosCache = new Vec3() Logger.log('maxRandomTime=', this.minRandomTime, this.maxRandomTime, game.frameRate) } start() { // this.randomFish() } update() { // this.checkRandomFish() this.checkFishMoveEnd() // this.checkFishMap() } private checkFishMap() { if (!this.isFishMap) { if (this.mapCount > 0) { this.mapCount-- if (this.mapCount <= 0) FishUI.instance.playWaveEffect() } } } // 检测是否随机鱼 private checkRandomFish() { if (!this.isFishMap) { if (this.nextRandomFishTime > 0) { this.nextRandomFishTime-- // if (this.nextRandomFishTime === 0) this.randomFish() } } } // 检测鱼是否移动结束 private checkFishMoveEnd() { this.fishList.forEach(async (item: FishBase, key: string) => { if (this.isFishMap) { // 鱼阵回收 if (item.isDead === 2) { item.node.getPosition(this._fishPosCache) this._fishPosCache.x -= 2 item.node.setPosition(this._fishPosCache) if (this._fishPosCache.x <= -screen.width / 2) { // winSize.width await WsManager.instance.onSend({ type: 102, fish_id: item.fishId, }) // this.fishList.splice(index, 1) this.destroyFish(item) // this.fishList.delete(item.fishId) this.checkEndFishMap() } } } else if (!item.getComponent(FishMover).isMoving) { // 普通鱼回收 await WsManager.instance.onSend({ type: 102, fish_id: item.fishId, }) // this.fishList.splice(index, 1) this.destroyFish(item) // this.fishList.delete(item.fishId) } }) } private checkEndFishMap() { // Logger.log('checkEndFishMap==', this.isFishMap, this.fishList) if (this.isFishMap && this.fishList.size <= 0) { this.isFishMap = false // this.randomFish() } } /** * 原:本地随机生成鱼 * 新:服务端生成鱼 */ private async randomFish(data: dataType) { const arr = data.fisn const paths: Array = [] if (!Array.isArray(arr) || this.isFishMap) return for (let i = 0; i < arr.length; i++) { const fish: FishBase = this.createFishByType(arr[i]) for (let k = 0; k < arr[i].fishPathInfo.length; k++) { const path: Array = [] for (let j = 0; j < arr[i].fishPathInfo[k].path.length; j++) { const p: Vec2 = new Vec2( arr[i].fishPathInfo[k].path[j].x, arr[i].fishPathInfo[k].path[j].y, ) path.push(p) } paths.push(new FishPathInfo(arr[i].fishPathInfo[k].pathId, path)) } fish.fishPathInfo = paths[0] this._fishPosCache.z = 0 this._fishPosCache.x = fish.fishPathInfo.path[0].x this._fishPosCache.y = fish.fishPathInfo.path[0].y fish.node.setPosition(this._fishPosCache) fish.getComponent(FishMover).bezierPList = fish.fishPathInfo.path fish.getComponent(FishMover).startMove() // this.fishList.push(fish) this.fishList.set(fish.fishId, fish) // this.fishContainer.addChild(fish.node) this.fishContainer.addChild(this.fishList.get(fish.fishId).node) } } // 创建鱼类 public createFishByType(data: FishType | any): FishBase { let fishNode: Node const fishType: number = Number(data.fishType) if (this.fishPool[fishType - 1] && this.fishPool[fishType - 1].size() > 0) { fishNode = this.fishPool[fishType - 1].get() } else { fishNode = instantiate(this.fishPrefabList[fishType - 1]) } TimeHelper.exeNextFrame(fishNode, () => fishNode.getComponent(Animation).play()) const fishInfo: FishInfo = FishConfig.getFishInfoByType(fishType) fishNode.getComponent(FishBase).fishInfo = fishInfo fishNode.getComponent(FishBase).fishType = fishType fishNode.getComponent(FishBase).fishId = data.fishId fishNode.getComponent(FishBase).isDead = 2 return fishNode.getComponent(FishBase) } // 销毁鱼类 public killFish(res: any) { const fishCheck = this.fishList.get(res.fish_id) // console.log('正在执行销毁=', fishCheck.fishId, res.fish_id, res.fish_status, fishCheck.isDead) if (fishCheck) { fishCheck.isDead = 1 setTimeout(() => { GameMusicHelper.playFishDead(fishCheck.fishType) fishCheck.node.getPosition(this._fishPosCache) const vec2 = new Vec2(this._fishPosCache.x, this._fishPosCache.y) ScoreManager.instance.addScore(Number(res.fish_number), vec2) this.destroyFish(fishCheck) // console.log('killFish=', fishCheck.fishId, fishCheck.fishInfo.name) this.checkEndFishMap() }, 500) tween(fishCheck.node) .repeatForever(tween().by(0.6, { angle: -360 })) .start() // this.fishList.splice(index, 1) } } private destroyFish(fish: FishBase) { const f = this.fishList.get(fish.fishId) if (!f) return if (!this.fishPool[f.fishType - 1]) { this.fishPool[f.fishType - 1] = new NodePool() } this.fishPool[f.fishType - 1].put(f.node) this.fishList.delete(f.fishId) } public playFishMap() { this.isFishMap = true this.fishList.forEach((fish: FishBase, key: string) => { this.destroyFish(fish) }) } public startFishMap() { const map: FishMap = FishPathConfig.randomFishMap() const fishMapInfoList: Array = map.fishMapInfoList Logger.log('startFishMap==', this.isFishMap, this.fishList, map) for (let i = 0; i < fishMapInfoList.length; i++) { const fishMapInfo: FishMapInfo = fishMapInfoList[i] // 暂时屏蔽 // @ts-ignore const fish: FishBase = this.createFishByType(fishMapInfo.fishType) fish.node.angle = 0 this.fishContainer.addChild(fish.node) fish.node.setPosition(fishMapInfo.x + screen.width, fishMapInfo.y) this.fishList.set(fish.fishId, fish) } } onDestroy() { FishManager.instance = null WsManager.instance.off(100) } protected onDisable(): void {} }