123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- import { _decorator, Component, Input, input, instantiate, KeyCode, macro, math, Node, Prefab, Sprite, UITransform, v3, Vec3 } from 'cc';
- import { GameMgr } from '../manager/GameMgr';
- import { ArrayUtil } from '../util/ArrayUtil';
- import { ShelveType } from '../enum/ShelveType';
- import { ShelveLocker } from './ShelveLocker';
- import { ShelveBase } from '../scriptBase/ShelveBase';
- import { CommonShelve } from './CommonShelve';
- import { SmallShelve } from './SmallShelve';
- import { UIMgr } from '../manager/UIMgr';
- import { UI } from '../enum/UI';
- import { PREVIEW } from 'cc/env';
- import { Mode, ModeName } from '../enum/Mode';
- import { cfg_level_gs, cfg_level_ls, cfg_level_tp } from '../config/cfg_level';
- import { DtoLevelCfg } from '../dto/DtoLevelCfg';
- import { DtoLevelData } from '../dto/DtoLevelData';
- import { cfg_icon_gs, cfg_icon_ls, cfg_icon_tp } from '../config/cfg_icon';
- import { DtoIconCfg } from '../dto/DtoIconCfg';
- import { ResMgr } from '../manager/ResMgr';
- import { Bundle } from '../enum/Bundle';
- import { Global } from '../Global';
- import { EventMgr } from '../manager/EventMgr';
- import { EventType } from '../enum/EventType';
- import { CoinMgr } from '../manager/CoinMgr';
- import { ComboBox } from './ComboBox';
- import { Goods } from './Goods';
- import { AudioMgr } from '../manager/AudioMgr';
- const { ccclass, property } = _decorator;
- @ccclass('Game/Stage')
- export class Stage extends Component {
- @property(Sprite)
- private bg: Sprite = null
- @property(Node)
- private shelveBox: Node = null
- @property(ComboBox)
- private comboBox: ComboBox = null
- @property(Node)
- private tip: Node = null
- @property(Prefab)
- private shelveLockerPre: Prefab = null
- @property(Prefab)
- private shelvePreArr: Prefab[] = []
- private levelCfg: DtoLevelCfg = null
- private levelData: DtoLevelData = null
- private iconCfg: DtoIconCfg = null
- private shelveArr: ShelveBase[] = []
- private doubleCoin: boolean = false
- private isBusy: boolean = false
- protected onLoad(): void {
- const bgName: string = 'bg_' + ModeName[GameMgr.mode]
- this.bg.spriteFrame = ResMgr.getSpriteFrame(Bundle.Game, bgName, 'image/')
- EventMgr.on(EventType.MergeGoods, this.onMergeGoods, this)
- EventMgr.on(EventType.TimeOut, this.onTimeOut, this)
- EventMgr.on(EventType.TimeOutAlert, this.onTimeOutAlert, this)
- EventMgr.on(EventType.UseSkillFreezeTime, this.onUseSkillFreezeTime, this)
- EventMgr.on(EventType.UseSkillDoubleCoin, this.onUseDoubleCoin, this)
- EventMgr.on(EventType.UseSkillRefreshPosition, this.onUseRefreshPos, this)
- EventMgr.on(EventType.UseSkillEraseGroup, this.onUseEraseGroup, this)
- if (PREVIEW) {
- input.on(Input.EventType.KEY_DOWN, (e) => {
- if (e.keyCode !== KeyCode.KEY_Q) return
- if (GameMgr.Pause) return
- UIMgr.open(UI.Win)
- }, this)
- }
- }
- protected onDestroy(): void {
- UIMgr.close(UI.Game)
- this.unscheduleAllCallbacks()
- EventMgr.off(EventType.MergeGoods, this.onMergeGoods, this)
- EventMgr.off(EventType.TimeOut, this.onTimeOut, this)
- EventMgr.off(EventType.TimeOutAlert, this.onTimeOutAlert, this)
- EventMgr.off(EventType.UseSkillFreezeTime, this.onUseSkillFreezeTime, this)
- EventMgr.off(EventType.UseSkillDoubleCoin, this.onUseDoubleCoin, this)
- EventMgr.off(EventType.UseSkillRefreshPosition, this.onUseRefreshPos, this)
- EventMgr.off(EventType.UseSkillEraseGroup, this.onUseEraseGroup, this)
- }
- protected start() {
- UIMgr.open(UI.Game)
- this.tip.active = GameMgr.mode === Mode.tp && GameMgr.CurLevel === 0
- this.scheduleOnce(() => {
- //Difficulty increase 难度飙升
- if (GameMgr.isHardLevel) UIMgr.open(UI.StageTip, 'Difficulty increase')
- }, 1)
- switch (GameMgr.mode) {
- case Mode.tp:
- this.levelCfg = cfg_level_tp
- this.iconCfg = cfg_icon_tp
- break;
- case Mode.gs:
- this.levelCfg = cfg_level_gs
- this.iconCfg = cfg_icon_gs
- break
- case Mode.ls:
- this.levelCfg = cfg_level_ls
- this.iconCfg = cfg_icon_ls
- break
- }
- if (GameMgr.CurLevel >= this.levelCfg.length) {
- this.levelData = ArrayUtil.pickItem(this.levelCfg)
- } else {
- this.levelData = this.levelCfg[GameMgr.CurLevel]
- }
- const shelveMap: number[][] = this.levelData.shelveMap
- const group: number = this.levelData.group
- const lockCnt: number = this.levelData.lockCnt
- const goodsTypeCnt: number = this.levelData.GoodsTypeCnt
- Global.Level_Time = this.levelData.time
- // Global.Level_Time = 10
- EventMgr.emit(EventType.TimeReset)
- this.createShelves(shelveMap)
- this.createShelveLockers(lockCnt)
- this.createGoodsArr(group, goodsTypeCnt)
- this.createGoodsData()
- this.schedule(this.onCheckWin, 0.5, macro.REPEAT_FOREVER)
- }
- private createShelves(shelveMap: number[][]): void {
- const row: number = shelveMap.length
- const col: number = shelveMap[0].length
- const uiTrans: UITransform = this.shelveBox.getComponent(UITransform)
- const spaceX: number = 0
- const spaceY: number = 0
- uiTrans.width = col * 230 + spaceX * (col - 1)
- uiTrans.height = row * 145 + spaceY * (row - 1)
- for (let i = 0; i < shelveMap.length; i++) {
- for (let j = 0; j < shelveMap[i].length; j++) {
- const type: ShelveType = shelveMap[i][j]
- const shelvePre: Prefab = this.shelvePreArr[type]
- const shelveNode: Node = instantiate(shelvePre)
- this.shelveBox.addChild(shelveNode)
- }
- }
- this.shelveArr = this.shelveBox.getComponentsInChildren(ShelveBase)
- }
- private createShelveLockers(lockCnt: number): void {
- if (lockCnt <= 0) return
- const shelves: ShelveBase[] = ArrayUtil.pickItems(this.shelveArr, lockCnt, true)
- for (let i = 0; i < shelves.length; i++) {
- const shelve: ShelveBase = shelves[i];
- const shelveLockerNode: Node = instantiate(this.shelveLockerPre)
- shelve.node.addChild(shelveLockerNode)
- const shelveLocker: ShelveLocker = shelveLockerNode.getComponent(ShelveLocker)
- shelveLocker.UnlockCnt = math.randomRangeInt(3, 6)
- }
- }
- private createGoodsArr(group: number, goodsTypeCnt: number): void {
- const idxArr: number[] = ArrayUtil.pickIndexs(this.iconCfg, goodsTypeCnt, true)
- GameMgr.goodsArr = []
- for (let i = 0; i < group; i++) {
- const goodsId: number = ArrayUtil.pickItem(idxArr) + 1
- GameMgr.goodsArr.push(goodsId, goodsId, goodsId)
- }
- ArrayUtil.shuffle(GameMgr.goodsArr)
- }
- private createGoodsData(): void {
- const commonShelveArr: CommonShelve[] = []
- const smallShelveArr: SmallShelve[] = []
- for (let i = 0; i < this.shelveArr.length; i++) {
- const shelve: ShelveBase = this.shelveArr[i];
- if (shelve instanceof CommonShelve) {
- commonShelveArr.push(shelve)
- } else if (shelve instanceof SmallShelve) {
- smallShelveArr.push(shelve)
- }
- }
- //先悬浮格子
- for (let i = 0; i < smallShelveArr.length; i++) {
- const smallShelve: SmallShelve = smallShelveArr[i];
- const smallShelveId: number = smallShelve.Id
- if (!GameMgr.goodsData.hasOwnProperty(smallShelveId)) {
- GameMgr.goodsData[smallShelveId] = {
- 0: [],
- }
- }
- // const cnt: number = math.randomRangeInt(2, 4)
- for (let j = 0; j < 3; j++) {
- const goodsId: number = GameMgr.goodsArr.shift()
- GameMgr.goodsData[smallShelveId][0].push(goodsId)
- }
- }
- const placeCnt: number = commonShelveArr.length * 3
- while (GameMgr.goodsArr.length > 0) {
- //筛选槽位
- const placeArr: number[] = []
- for (let i = 0; i < placeCnt; i++) {
- placeArr.push(i)
- }
- ArrayUtil.shuffle(placeArr)
- if (placeCnt <= 6) {
- placeArr.splice(0, math.randomRangeInt(2, 3))
- } else {
- placeArr.splice(0, math.randomRangeInt(4, 6))
- }
- for (let i = 0; i < placeCnt; i++) {
- const placeId: number = i
- const commonShelveId: number = commonShelveArr[Math.floor(placeId / 3)].Id
- const slotId: number = placeId % 3
- if (!GameMgr.goodsData.hasOwnProperty(commonShelveId)) {
- GameMgr.goodsData[commonShelveId] = {
- 0: [],
- 1: [],
- 2: [],
- }
- }
- let goodsId: number = -1
- if (GameMgr.goodsArr.length <= 0 || !placeArr.includes(placeId)) goodsId = -1
- else goodsId = GameMgr.goodsArr.shift()
- GameMgr.goodsData[commonShelveId][slotId].push(goodsId)
- }
- }
- }
- private onCheckWin(): void {
- const isWin: boolean = this.checkWin()
- if (!isWin) return
- if (this.isBusy) return
- this.unscheduleAllCallbacks()
- UIMgr.open(UI.Win)
- }
- private checkWin(): boolean {
- for (let i = 0; i < this.shelveArr.length; i++) {
- const shelve: ShelveBase = this.shelveArr[i];
- if (!shelve.isEmpty) return false
- }
- return true
- }
- private onTimeOut(): void {
- const isWin: boolean = this.checkWin()
- if (isWin) return
- UIMgr.open(UI.TimeOut)
- }
- private onTimeOutAlert(): void {
- const effectRedAlertPre: Prefab = ResMgr.getRes(Bundle.Game, 'EffectRedAlert')
- const effectRedAlertNode: Node = instantiate(effectRedAlertPre)
- this.node.addChild(effectRedAlertNode)
- }
- private onUseSkillFreezeTime(): void {
- const effectFreezePre: Prefab = ResMgr.getRes(Bundle.Game, 'EffectFreeze')
- const effectFreezeNode: Node = instantiate(effectFreezePre)
- this.node.addChild(effectFreezeNode)
- }
- private onMergeGoods(shelveWorldPos: Vec3): void {
- this.comboBox.CurCombo++
- AudioMgr.playSfx(`bomb_${this.comboBox.CurCombo}`)
- CoinMgr.CurCoin += this.doubleCoin ? this.comboBox.CurCombo * 2 : this.comboBox.CurCombo
- this.comboBox.createFloatText(shelveWorldPos)
- }
- private onUseDoubleCoin(): void {
- AudioMgr.playSfx('星星道具')
- this.doubleCoin = true
- this.scheduleOnce(this.onAfterDoubleCoin, Global.Double_Coin_Duration)
- }
- private onAfterDoubleCoin(): void {
- this.doubleCoin = false
- }
- private onUseRefreshPos(): void {
- AudioMgr.playSfx('转换道具')
- for (let i = 0; i < this.shelveArr.length; i++) {
- const shelve: ShelveBase = this.shelveArr[i]
- const goodsIdArr: number[] = shelve.GoodsIdArr
- for (let j = 0; j < goodsIdArr.length; j++) {
- const goodsId: number = goodsIdArr[j];
- GameMgr.goodsArr.push(goodsId)
- }
- }
- ArrayUtil.shuffle(GameMgr.goodsArr)
- this.createGoodsData()
- for (let i = 0; i < this.shelveArr.length; i++) {
- const shelve: ShelveBase = this.shelveArr[i]
- shelve.clear()
- this.scheduleOnce(() => {
- shelve.init()
- })
- }
- this.isBusy = true
- this.scheduleOnce(() => {
- this.isBusy = false
- }, 0.5)
- }
- private onUseEraseGroup(): void {
- AudioMgr.playSfx('灯泡道具')
- //先统计场上的物品
- const goodsMap = {}
- for (let i = 0; i < this.shelveArr.length; i++) {
- const shelve: ShelveBase = this.shelveArr[i];
- const info: Object = shelve.GoodsInfo
- for (const layer in info) {
- if (Object.prototype.hasOwnProperty.call(info, layer)) {
- for (const slot in info[layer]) {
- if (Object.prototype.hasOwnProperty.call(info[layer], slot)) {
- const goods: Goods = info[layer][slot];
- const goodsId: number = goods.Id
- if (!goodsMap.hasOwnProperty(goodsId)) {
- goodsMap[goodsId] = []
- }
- goodsMap[goodsId].push(goods)
- }
- }
- }
- }
- for (const goodsId in goodsMap) {
- if (Object.prototype.hasOwnProperty.call(goodsMap, goodsId)) {
- ArrayUtil.shuffle(goodsMap[goodsId])
- }
- }
- }
- //筛选出超过三个的物品
- const map2 = {}
- for (const goodsId in goodsMap) {
- if (Object.prototype.hasOwnProperty.call(goodsMap, goodsId)) {
- if (goodsMap[goodsId].length >= 3) {
- map2[goodsId] = goodsMap[goodsId]
- }
- }
- }
- //从中挑选三组
- const map3 = {}
- let cnt: number = 0
- for (const goodsId in map2) {
- if (Object.prototype.hasOwnProperty.call(map2, goodsId)) {
- map3[goodsId] = map2[goodsId]
- cnt++
- if (cnt >= 3) break
- }
- }
- //将这三组中随机三个物品消除
- for (const goodsId in map3) {
- if (Object.prototype.hasOwnProperty.call(map3, goodsId)) {
- const goodsArr: Goods[] = map3[goodsId];
- const pickedGoodsArr: Goods[] = ArrayUtil.pickItems(goodsArr, 3, true)
- for (let i = 0; i < pickedGoodsArr.length; i++) {
- const goods: Goods = pickedGoodsArr[i];
- const shelve: ShelveBase = goods.node.parent.parent.getComponent(ShelveBase)
- if (!shelve) {
- continue
- }
- shelve.removeGoods(goods)
- }
- }
- }
- }
- }
|