CommonShelve.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. let 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 - 20
  113. layerNode.addChild(goodsNode)
  114. goodsNode.setScale(0.6, 0.6, 0.6)
  115. goodsNode.setPosition(pos)
  116. goods.Id = goodsId
  117. goods.Layer = layer
  118. goods.Slot = slotId
  119. if (layer === 0) this.layer0GoodsMap.set(slotId, goodsId)
  120. return goods
  121. }
  122. public isSlotOccupied(slotId: number): boolean {
  123. return this.layer0GoodsMap.has(slotId)
  124. }
  125. public isAllSlotOccupied(): boolean {
  126. return this.layer0GoodsMap.size === 3
  127. }
  128. public placeGoods(goodsId: number, slotId: number): void {
  129. const goods: Goods = this.createGoods(goodsId, slotId, 0)
  130. goods.bounce()
  131. }
  132. protected onPlaceGoods(): void {
  133. const layer0: Node = this.layers[0]
  134. const layer0GoodsArr: Goods[] = layer0.getComponentsInChildren(Goods)
  135. for (let i = 0; i < layer0GoodsArr.length; i++) {
  136. const goods: Goods = layer0GoodsArr[i]
  137. if (goods.Visible) continue
  138. goods.node.destroy()
  139. this.layer0GoodsMap.delete(goods.Slot)
  140. }
  141. }
  142. protected onCheckMerge(): void {
  143. const goodsCnt: number = this.layer0GoodsMap.size
  144. if (goodsCnt < 3) return
  145. const layer0: Node = this.layers[0]
  146. const layer0GoodsArr: Goods[] = layer0.getComponentsInChildren(Goods)
  147. const isAllSame: boolean = ArrayUtil.isAllSame(layer0GoodsArr, 'Id')
  148. if (!isAllSame) return
  149. //合并第一层的物品
  150. for (let i = 0; i < layer0GoodsArr.length; i++) {
  151. const goods: Goods = layer0GoodsArr[i];
  152. goods.remove()
  153. }
  154. this.layer0GoodsMap.clear()
  155. EventMgr.emit(EventType.MergeGoods, this.node.getWorldPosition())
  156. }
  157. public get GoodsIdArr(): number[] {
  158. const goodsIdArr: number[] = []
  159. for (let i = 0; i < this.layers.length; i++) {
  160. const layer: Node = this.layers[i];
  161. const layerGoodsArr: Goods[] = layer.getComponentsInChildren(Goods)
  162. for (let j = 0; j < layerGoodsArr.length; j++) {
  163. const goods: Goods = layerGoodsArr[j];
  164. goodsIdArr.push(goods.Id)
  165. }
  166. }
  167. return goodsIdArr
  168. }
  169. public get GoodsInfo(): Object {
  170. const info = {}
  171. for (let i = 0; i < this.layers.length; i++) {
  172. const layer: Node = this.layers[i];
  173. if (!info.hasOwnProperty(i)) {
  174. info[i] = {}
  175. }
  176. const layerGoodsArr: Goods[] = layer.getComponentsInChildren(Goods)
  177. for (let j = 0; j < layerGoodsArr.length; j++) {
  178. const goods: Goods = layerGoodsArr[j];
  179. const { Slot, Id } = goods
  180. info[i][Slot] = goods
  181. }
  182. }
  183. return info
  184. }
  185. public clear(): void {
  186. this.layer0GoodsMap.clear()
  187. for (let i = 0; i < this.layers.length; i++) {
  188. const layer: Node = this.layers[i];
  189. layer.destroyAllChildren()
  190. }
  191. }
  192. public removeGoods(goods: Goods): void {
  193. const { Layer, Slot } = goods
  194. if (Layer === 0) {
  195. this.layer0GoodsMap.delete(Slot)
  196. }
  197. goods.remove()
  198. }
  199. }