import { _decorator, Component, EventTouch, instantiate, isValid, Node, Prefab, Sprite, UITransform, v3, Vec2, Vec3 } from 'cc' import { ResMgr } from './ResMgr' import { Bundle } from '../enum/Bundle' import { Goods } from '../game/Goods' import { EventMgr } from './EventMgr' import { EventType } from '../enum/EventType' import { ShelveLocker } from '../game/ShelveLocker' import { ShelveBase } from '../scriptBase/ShelveBase' import { Mode, ModeName } from '../enum/Mode' import { StorageUtil } from '../util/StorageUtil' import { ObjUtil } from '../util/ObjUtil' import { AudioMgr } from './AudioMgr' import { PREVIEW } from 'cc/env' import { GlobalMgr } from './GlobalMgr' import { AdvertMgr } from './AdvertMgr' const { ccclass, property } = _decorator const PickOffset: number = 80 @ccclass('Manager/GameMgr') export class GameMgr extends Component { private static _inst: GameMgr = null private static _node: Node = null private static _uiTrans: UITransform = null public static get Stage(): Node { return this._node.children[0] } private static curLevel: object = {} public static get CurLevel(): number { if (!ObjUtil.has(this.curLevel, this.mode)) return 0 return this.curLevel[this.mode] } public static get CurPassedLevel(): number { let passCnt: number = 0 for (const mode in this.curLevel) { if (Object.prototype.hasOwnProperty.call(this.curLevel, mode)) { const level = this.curLevel[mode] passCnt += level } } return passCnt } public static get isHardLevel(): boolean { return (this.CurLevel + 1) % 5 === 0 } private static unlockedMode: Mode[] = [] public static mode: Mode = Mode.ls private static _pickedGoods: Goods = null private static _holdGoods: Node = null public static shelveArr: ShelveBase[] = [] public static shelveLockerArr: ShelveLocker[] = [] public static goodsArr: number[] = [] public static goodsData = {} private static pause: boolean = false public static get Pause(): boolean { return this.pause } public static set Pause(v: boolean) { this.pause = v; EventMgr.emit(EventType.Pause, v) } protected onLoad(): void { globalThis.GameMgr = GameMgr GameMgr._inst = this GameMgr._node = this.node GameMgr._uiTrans = this.getComponent(UITransform) this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this) this.node.on(Node.EventType.TOUCH_END, this.onTouchFinish, this) this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchFinish, this) GameMgr.unlockedMode = StorageUtil.getObj('unlockedMode', [0]) GameMgr.curLevel = StorageUtil.getObj('curLevel', { 0: 0 }) GlobalMgr.instance.initilize(); AdvertMgr.instance.initilize(); AdvertMgr.instance.showInterstitial(); } public static unlockMode(mode: Mode): void { if (this.unlockedMode.includes(mode)) return this.unlockedMode.push(mode) this.unlockedMode.sort() StorageUtil.setObj('unlockedMode', this.unlockedMode) EventMgr.emit(EventType.ModeUnlocked) } private static createStage(): void { const stagePre: Prefab = ResMgr.getRes(Bundle.Game, 'Stage') const stageNode: Node = instantiate(stagePre) this._node.addChild(stageNode) } public static startGame(): void { this.reset() this._node.destroyAllChildren() this._inst.scheduleOnce(() => { this.createStage() }) } public static passGame(): void { if (!ObjUtil.has(this.curLevel, this.mode)) { this.curLevel[this.mode] = 0 } this.curLevel[this.mode]++ StorageUtil.setObj('curLevel', this.curLevel) // if (this.mode === Mode.tp && this.curLevel[this.mode] >= 15) { // this.unlockMode(Mode.gs) // } else if (this.mode === Mode.gs && this.curLevel[this.mode] >= 10) { // this.unlockMode(Mode.ls) // } } public static quitGame(): void { this._node.destroyAllChildren() this.reset() } public static pick(goods: Goods, uiPos: Vec2): void { this._pickedGoods = goods this._holdGoods = new Node() const sp: Sprite = this._holdGoods.addComponent(Sprite) sp.spriteFrame = goods.Sp.spriteFrame this._node.addChild(this._holdGoods) uiPos.y += PickOffset const localPos: Vec3 = GameMgr._uiTrans.convertToNodeSpaceAR(v3(uiPos.x, uiPos.y, 0)) this._holdGoods.setPosition(localPos) AudioMgr.playSfx('点击消除物') } public static release(): void { let isSuccess: boolean = false const holdGoodsWorldPos: Vec3 = this._holdGoods.getWorldPosition() for (let i = 0; i < this.shelveArr.length; i++) { const shelve: ShelveBase = this.shelveArr[i] if (shelve.getComponentInChildren(ShelveLocker)) continue const uiTrans: UITransform = shelve.getComponent(UITransform) const shelveWorldPos: Vec3 = shelve.node.getWorldPosition() const goodsLocalPos: Vec3 = uiTrans.convertToNodeSpaceAR(holdGoodsWorldPos) const disX: number = Math.abs(shelveWorldPos.x - holdGoodsWorldPos.x) const disY: number = Math.abs(shelveWorldPos.y - holdGoodsWorldPos.y) if (disX < uiTrans.width / 2 && disY < uiTrans.height / 2) { const slotId: number = shelve.getSlot(goodsLocalPos) if (slotId < 0 || shelve.isSlotOccupied(slotId)) break const goodsId: number = this._pickedGoods.Id shelve.placeGoods(goodsId, slotId) isSuccess = true break } } if (isSuccess) { EventMgr.emit(EventType.PlaceGoods) } else { this._pickedGoods.Visible = true } this._pickedGoods = null this._holdGoods.destroy() this._holdGoods = null AudioMgr.playSfx('放下消除物') } public static get isPicking(): boolean { return !!this._pickedGoods } private onTouchMove(e: EventTouch): void { const holdGoods: Node = GameMgr._holdGoods if (!isValid(holdGoods)) return const uiPos: Vec2 = e.getUILocation() uiPos.y += PickOffset const localPos: Vec3 = GameMgr._uiTrans.convertToNodeSpaceAR(v3(uiPos.x, uiPos.y, 0)) holdGoods.setPosition(localPos) } private onTouchFinish(e: EventTouch): void { if (!isValid(GameMgr._holdGoods)) return GameMgr.release() } private static reset(): void { this._pickedGoods = null this._holdGoods = null this.shelveArr = [] this.shelveLockerArr = [] this.goodsArr = [] this.goodsData = {} } public static isModeUnlocked(mode: Mode): boolean { return this.unlockedMode.includes(mode) } public static get isModeAllUnlocked(): boolean { return this.unlockedMode.length >= ModeName.length } public static get isStucked(): boolean { for (let i = 0; i < this.shelveArr.length; i++) { const shelve: ShelveBase = this.shelveArr[i]; if (!shelve.isAllSlotOccupied()) return false } return true } } if (PREVIEW) { globalThis.GameMgr = GameMgr }