CommonShelve.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import { _decorator, instantiate, macro, Node, Prefab, v3, Vec3 } from 'cc';
  2. import { GameMgr } from '../manager/GameMgr';
  3. import { ResMgr } from '../manager/ResMgr';
  4. import { Bundle } from '../enum/Bundle';
  5. import { Goods } from './Goods';
  6. import { EventMgr } from '../manager/EventMgr';
  7. import { EventType } from '../enum/EventType';
  8. import { ArrayUtil } from '../util/ArrayUtil';
  9. import { ShelveBase } from '../scriptBase/ShelveBase';
  10. import { Global } from '../Global';
  11. const { ccclass, property } = _decorator;
  12. @ccclass('Game/CommonShelve')
  13. export class CommonShelve extends ShelveBase {
  14. @property([Node])
  15. private layers: Node[] = []
  16. public get isEmpty(): boolean {
  17. for (let i = 0; i < this.layers.length; i++) {
  18. const layer: Node = this.layers[i];
  19. if (layer.children.length > 0) return false
  20. }
  21. return true
  22. }
  23. //slotId goodsId
  24. private layer0GoodsMap: Map<number, number> = new Map<number, number>()
  25. protected onLoad(): void {
  26. super.onLoad()
  27. GameMgr.shelveArr.push(this)
  28. }
  29. protected start() {
  30. super.start()
  31. this.init()
  32. this.schedule(this.onTrySupplyGoods, 0.25, macro.REPEAT_FOREVER)
  33. this.schedule(this.onCheckMerge, 0.15, macro.REPEAT_FOREVER)
  34. }
  35. public init(bounceDelay: number = 0): void {
  36. this.createLayerGoods(0, bounceDelay)
  37. this.createLayerGoods(1, bounceDelay)
  38. }
  39. public createLayerGoods(layer: number, bounceDelay: number = 0): void {
  40. const shelveData = GameMgr.goodsData[this.id]
  41. for (const slot in shelveData) {
  42. if (Object.prototype.hasOwnProperty.call(shelveData, slot)) {
  43. const goodsArr: number[] = shelveData[slot]
  44. if (goodsArr.length <= 0) continue
  45. const goodsId: number = goodsArr.shift()
  46. if (goodsId === -1) continue
  47. const goods: Goods = this.createGoods(goodsId, Number(slot), layer)
  48. goods.bounce(bounceDelay)
  49. }
  50. }
  51. }
  52. //如果第一层为空,则尝试补充新物品
  53. protected onTrySupplyGoods(): void {
  54. const layer0: Node = this.layers[0]
  55. const layer1: Node = this.layers[1]
  56. if (layer0.children.length <= 0) {
  57. //将第二层的物品前移至第一层
  58. const layer1: Node = this.layers[1]
  59. const layer1GoodsArr: Goods[] = layer1.getComponentsInChildren(Goods)
  60. for (let i = 0; i < layer1GoodsArr.length; i++) {
  61. const goods: Goods = layer1GoodsArr[i]
  62. const pos: Vec3 = goods.node.getPosition()
  63. goods.Layer = 0
  64. goods.node.setParent(layer0)
  65. pos.y -= Global.Goods_Offset
  66. goods.node.setPosition(pos)
  67. this.layer0GoodsMap.set(goods.Slot, goods.Id)
  68. goods.bounce()
  69. }
  70. // //补充第二层的物品
  71. // this.createLayerGoods(1)
  72. }
  73. if (layer1.children.length <= 0) {
  74. this.createLayerGoods(1, 0)
  75. }
  76. }
  77. public getSlot(goodsPos: Vec3): number {
  78. const disArr: any[] = []
  79. const offsetX: number = 0.5 * this.uiTrans.width / 3
  80. const posArr: Vec3[] = [
  81. v3(-offsetX, 0, 0),
  82. v3(0, 0, 0),
  83. v3(offsetX, 0, 0),
  84. ]
  85. for (let i = 0; i < posArr.length; i++) {
  86. const pos: Vec3 = posArr[i];
  87. const dis: number = Vec3.distance(goodsPos, pos)
  88. disArr.push({
  89. slotId: i,
  90. dis: dis
  91. })
  92. }
  93. disArr.sort((a, b) => {
  94. return a.dis - b.dis
  95. })
  96. for (let i = 0; i < disArr.length; i++) {
  97. const data = disArr[i];
  98. const slotId: number = data.slotId
  99. if (!this.isSlotOccupied(slotId)) return slotId
  100. }
  101. return -1
  102. }
  103. public createGoods(goodsId: number, slotId: number, layer: number): Goods {
  104. const goodsPre: Prefab = ResMgr.getRes(Bundle.Game, 'Goods')
  105. const goodsNode: Node = instantiate(goodsPre)
  106. const goods: Goods = goodsNode.getComponent(Goods)
  107. const layerNode: Node = this.layers[layer]
  108. const pos: Vec3 = v3()
  109. pos.x = (slotId - 1) * (this.uiTrans.width - 10) / 3
  110. // pos.y = layer * Global.Goods_Offset
  111. const baseY = layer * Global.Goods_Offset
  112. pos.y = slotId === 1 ? baseY + Global.Goods_Offset * 2 : baseY
  113. layerNode.addChild(goodsNode)
  114. goodsNode.setPosition(pos)
  115. goods.Id = goodsId
  116. goods.Layer = layer
  117. goods.Slot = slotId
  118. if (layer === 0) this.layer0GoodsMap.set(slotId, goodsId)
  119. return goods
  120. }
  121. public isSlotOccupied(slotId: number): boolean {
  122. return this.layer0GoodsMap.has(slotId)
  123. }
  124. public isAllSlotOccupied(): boolean {
  125. return this.layer0GoodsMap.size === 3
  126. }
  127. public placeGoods(goodsId: number, slotId: number): void {
  128. const goods: Goods = this.createGoods(goodsId, slotId, 0)
  129. goods.bounce()
  130. }
  131. protected onPlaceGoods(): void {
  132. const layer0: Node = this.layers[0]
  133. const layer0GoodsArr: Goods[] = layer0.getComponentsInChildren(Goods)
  134. for (let i = 0; i < layer0GoodsArr.length; i++) {
  135. const goods: Goods = layer0GoodsArr[i]
  136. if (goods.Visible) continue
  137. goods.node.destroy()
  138. this.layer0GoodsMap.delete(goods.Slot)
  139. }
  140. }
  141. protected onCheckMerge(): void {
  142. const goodsCnt: number = this.layer0GoodsMap.size
  143. if (goodsCnt < 3) return
  144. const layer0: Node = this.layers[0]
  145. const layer0GoodsArr: Goods[] = layer0.getComponentsInChildren(Goods)
  146. const isAllSame: boolean = ArrayUtil.isAllSame(layer0GoodsArr, 'Id')
  147. if (!isAllSame) return
  148. //合并第一层的物品
  149. for (let i = 0; i < layer0GoodsArr.length; i++) {
  150. const goods: Goods = layer0GoodsArr[i];
  151. goods.remove()
  152. }
  153. this.layer0GoodsMap.clear()
  154. EventMgr.emit(EventType.MergeGoods, this.node.getWorldPosition())
  155. }
  156. public get GoodsIdArr(): number[] {
  157. const goodsIdArr: number[] = []
  158. for (let i = 0; i < this.layers.length; i++) {
  159. const layer: Node = this.layers[i];
  160. const layerGoodsArr: Goods[] = layer.getComponentsInChildren(Goods)
  161. for (let j = 0; j < layerGoodsArr.length; j++) {
  162. const goods: Goods = layerGoodsArr[j];
  163. goodsIdArr.push(goods.Id)
  164. }
  165. }
  166. return goodsIdArr
  167. }
  168. public get GoodsInfo(): Object {
  169. const info = {}
  170. for (let i = 0; i < this.layers.length; i++) {
  171. const layer: Node = this.layers[i];
  172. if (!info.hasOwnProperty(i)) {
  173. info[i] = {}
  174. }
  175. const layerGoodsArr: Goods[] = layer.getComponentsInChildren(Goods)
  176. for (let j = 0; j < layerGoodsArr.length; j++) {
  177. const goods: Goods = layerGoodsArr[j];
  178. const { Slot, Id } = goods
  179. info[i][Slot] = goods
  180. }
  181. }
  182. return info
  183. }
  184. public clear(): void {
  185. this.layer0GoodsMap.clear()
  186. for (let i = 0; i < this.layers.length; i++) {
  187. const layer: Node = this.layers[i];
  188. layer.destroyAllChildren()
  189. }
  190. }
  191. public removeGoods(goods: Goods): void {
  192. const { Layer, Slot } = goods
  193. if (Layer === 0) {
  194. this.layer0GoodsMap.delete(Slot)
  195. }
  196. goods.remove()
  197. }
  198. }