GameMgr.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { _decorator, Component, EventTouch, instantiate, isValid, Node, Prefab, Sprite, UITransform, v3, Vec2, Vec3 } from 'cc'
  2. import { ResMgr } from './ResMgr'
  3. import { Bundle } from '../enum/Bundle'
  4. import { Goods } from '../game/Goods'
  5. import { EventMgr } from './EventMgr'
  6. import { EventType } from '../enum/EventType'
  7. import { ShelveLocker } from '../game/ShelveLocker'
  8. import { ShelveBase } from '../scriptBase/ShelveBase'
  9. import { Mode, ModeName } from '../enum/Mode'
  10. import { StorageUtil } from '../util/StorageUtil'
  11. import { ObjUtil } from '../util/ObjUtil'
  12. import { AudioMgr } from './AudioMgr'
  13. import { PREVIEW } from 'cc/env'
  14. const { ccclass, property } = _decorator
  15. const PickOffset: number = 80
  16. @ccclass('Manager/GameMgr')
  17. export class GameMgr extends Component {
  18. private static _inst: GameMgr = null
  19. private static _node: Node = null
  20. private static _uiTrans: UITransform = null
  21. public static get Stage(): Node {
  22. return this._node.children[0]
  23. }
  24. private static curLevel: object = {}
  25. public static get CurLevel(): number {
  26. if (!ObjUtil.has(this.curLevel, this.mode)) return 0
  27. return this.curLevel[this.mode]
  28. }
  29. public static get CurPassedLevel(): number {
  30. let passCnt: number = 0
  31. for (const mode in this.curLevel) {
  32. if (Object.prototype.hasOwnProperty.call(this.curLevel, mode)) {
  33. const level = this.curLevel[mode]
  34. passCnt += level
  35. }
  36. }
  37. return passCnt
  38. }
  39. public static get isHardLevel(): boolean {
  40. return (this.CurLevel + 1) % 5 === 0
  41. }
  42. private static unlockedMode: Mode[] = []
  43. public static mode: Mode = Mode.tp
  44. private static _pickedGoods: Goods = null
  45. private static _holdGoods: Node = null
  46. public static shelveArr: ShelveBase[] = []
  47. public static shelveLockerArr: ShelveLocker[] = []
  48. public static goodsArr: number[] = []
  49. public static goodsData = {}
  50. private static pause: boolean = false
  51. public static get Pause(): boolean {
  52. return this.pause
  53. }
  54. public static set Pause(v: boolean) {
  55. this.pause = v;
  56. EventMgr.emit(EventType.Pause, v)
  57. }
  58. protected onLoad(): void {
  59. globalThis.GameMgr = GameMgr
  60. GameMgr._inst = this
  61. GameMgr._node = this.node
  62. GameMgr._uiTrans = this.getComponent(UITransform)
  63. this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this)
  64. this.node.on(Node.EventType.TOUCH_END, this.onTouchFinish, this)
  65. this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchFinish, this)
  66. GameMgr.unlockedMode = StorageUtil.getObj('unlockedMode', [0])
  67. GameMgr.curLevel = StorageUtil.getObj('curLevel', { 0: 0 })
  68. }
  69. public static unlockMode(mode: Mode): void {
  70. if (this.unlockedMode.includes(mode)) return
  71. this.unlockedMode.push(mode)
  72. this.unlockedMode.sort()
  73. StorageUtil.setObj('unlockedMode', this.unlockedMode)
  74. EventMgr.emit(EventType.ModeUnlocked)
  75. }
  76. private static createStage(): void {
  77. const stagePre: Prefab = ResMgr.getRes(Bundle.Game, 'Stage')
  78. const stageNode: Node = instantiate(stagePre)
  79. this._node.addChild(stageNode)
  80. }
  81. public static startGame(): void {
  82. this.reset()
  83. this._node.destroyAllChildren()
  84. this._inst.scheduleOnce(() => {
  85. this.createStage()
  86. })
  87. }
  88. public static passGame(): void {
  89. if (!ObjUtil.has(this.curLevel, this.mode)) {
  90. this.curLevel[this.mode] = 0
  91. }
  92. this.curLevel[this.mode]++
  93. StorageUtil.setObj('curLevel', this.curLevel)
  94. if (this.mode === Mode.tp && this.curLevel[this.mode] >= 15) {
  95. this.unlockMode(Mode.gs)
  96. } else if (this.mode === Mode.gs && this.curLevel[this.mode] >= 10) {
  97. this.unlockMode(Mode.ls)
  98. }
  99. }
  100. public static quitGame(): void {
  101. this._node.destroyAllChildren()
  102. this.reset()
  103. }
  104. public static pick(goods: Goods, uiPos: Vec2): void {
  105. this._pickedGoods = goods
  106. this._holdGoods = new Node()
  107. const sp: Sprite = this._holdGoods.addComponent(Sprite)
  108. sp.spriteFrame = goods.Sp.spriteFrame
  109. this._node.addChild(this._holdGoods)
  110. uiPos.y += PickOffset
  111. const localPos: Vec3 = GameMgr._uiTrans.convertToNodeSpaceAR(v3(uiPos.x, uiPos.y, 0))
  112. this._holdGoods.setPosition(localPos)
  113. AudioMgr.playSfx('点击消除物')
  114. }
  115. public static release(): void {
  116. let isSuccess: boolean = false
  117. const holdGoodsWorldPos: Vec3 = this._holdGoods.getWorldPosition()
  118. for (let i = 0; i < this.shelveArr.length; i++) {
  119. const shelve: ShelveBase = this.shelveArr[i]
  120. if (shelve.getComponentInChildren(ShelveLocker)) continue
  121. const uiTrans: UITransform = shelve.getComponent(UITransform)
  122. const shelveWorldPos: Vec3 = shelve.node.getWorldPosition()
  123. const goodsLocalPos: Vec3 = uiTrans.convertToNodeSpaceAR(holdGoodsWorldPos)
  124. const disX: number = Math.abs(shelveWorldPos.x - holdGoodsWorldPos.x)
  125. const disY: number = Math.abs(shelveWorldPos.y - holdGoodsWorldPos.y)
  126. if (disX < uiTrans.width / 2 && disY < uiTrans.height / 2) {
  127. const slotId: number = shelve.getSlot(goodsLocalPos)
  128. if (slotId < 0 || shelve.isSlotOccupied(slotId)) break
  129. const goodsId: number = this._pickedGoods.Id
  130. shelve.placeGoods(goodsId, slotId)
  131. isSuccess = true
  132. break
  133. }
  134. }
  135. if (isSuccess) {
  136. EventMgr.emit(EventType.PlaceGoods)
  137. } else {
  138. this._pickedGoods.Visible = true
  139. }
  140. this._pickedGoods = null
  141. this._holdGoods.destroy()
  142. this._holdGoods = null
  143. AudioMgr.playSfx('放下消除物')
  144. }
  145. public static get isPicking(): boolean {
  146. return !!this._pickedGoods
  147. }
  148. private onTouchMove(e: EventTouch): void {
  149. const holdGoods: Node = GameMgr._holdGoods
  150. if (!isValid(holdGoods)) return
  151. const uiPos: Vec2 = e.getUILocation()
  152. uiPos.y += PickOffset
  153. const localPos: Vec3 = GameMgr._uiTrans.convertToNodeSpaceAR(v3(uiPos.x, uiPos.y, 0))
  154. holdGoods.setPosition(localPos)
  155. }
  156. private onTouchFinish(e: EventTouch): void {
  157. if (!isValid(GameMgr._holdGoods)) return
  158. GameMgr.release()
  159. }
  160. private static reset(): void {
  161. this._pickedGoods = null
  162. this._holdGoods = null
  163. this.shelveArr = []
  164. this.shelveLockerArr = []
  165. this.goodsArr = []
  166. this.goodsData = {}
  167. }
  168. public static isModeUnlocked(mode: Mode): boolean {
  169. return this.unlockedMode.includes(mode)
  170. }
  171. public static get isModeAllUnlocked(): boolean {
  172. return this.unlockedMode.length >= ModeName.length
  173. }
  174. public static get isStucked(): boolean {
  175. for (let i = 0; i < this.shelveArr.length; i++) {
  176. const shelve: ShelveBase = this.shelveArr[i];
  177. if (!shelve.isAllSlotOccupied()) return false
  178. }
  179. return true
  180. }
  181. }
  182. if (PREVIEW) {
  183. globalThis.GameMgr = GameMgr
  184. }