import GameModel from "../core/GameModel"; import ItemUtil from "../core/ItemUtil"; import MsgAlert from "../game/msg/MsgAlert"; import FGUtil from "../gear_2.3.4/fgui/FGUtil"; import SKDataUtil from "../gear_2.3.4/util/SKDataUtil"; import SKUIUtil from "../gear_2.3.4/util/SKUIUtil"; const { ccclass, property } = cc._decorator; export default class TurnTable extends cc.Component { /** * 轉盤單例實例 */ public static Instance: TurnTable = null; /** * 轉盤面板 */ turnTablePanel: fgui.GComponent = null; /** * 免費次數 */ freeTimes: number = 0; /** * 寶箱數量 */ boxNum: number = 0; /** * 轉動次數 */ turnTimes: number = 0; /** * 阻止點擊 */ stopTap: boolean = false; /** * 是否顯示動畫 */ showAct: boolean = false; /** * 風雨寶箱數據 */ boxData: any = null; /** * 花費類型 0 風雨寶箱 1免費 2單次 3五連抽 */ coastType: number = -1; /** * 轉盤1次價格 */ turn1Price: number = 99999; /** * 轉盤5次價格 */ turn5Price: number = 99999; /** * 模式 */ mode: number = 0; /** * 要掉落的獎品id */ dorpId: number = -1; /** * 發送獲獎物品鍵值 */ dorpKey: number = -1; /** * 需要加載的預製體 */ prefabObject: any = {}; onLoad() { console.log("===============================", this.node.name) if (TurnTable.Instance === null) { TurnTable.Instance = this; this.loadPrefab(); } else { this.destroy(); return; } } /** * 加載預製體 */ loadPrefab() { // 加載所需的預製體 var prefabList = [ { url: "Prefabs/UIRole", name: "UIRole" }, ] this.prefabObject = {} for (let item of prefabList) { cc.loader.loadRes(item.url, cc.Prefab, (err, prefab) => { if (err) console.warn(err); else { this.prefabObject[item.name] = prefab; } }) } } /** * 打開轉盤 */ openTurnTable(refresh: boolean = false, data: any = null) { if (!this.turnTablePanel || (this.turnTablePanel && !this.turnTablePanel.node && !SKUIUtil.isValid(this.turnTablePanel.node))) { this.turnTablePanel = FGUtil.create("main_ui", "turntable2_panel"); FGUtil.root().addChild(this.turnTablePanel); this.turnTablePanel.makeFullScreen(); } // 刷新顯示數據 if (refresh) { if (data == null) { console.warn("抽獎數據錯誤") return } this.mode = data.model; // 刷新免費抽獎次數和寶箱鑰匙數量 this.onlyRefreshTimes(data) if (data.type == 1) { // 風雨寶箱 this.showBoxContent(JSON.parse(data.dialData)) } if (data.type == 2) { // 轉盤 if (this.turnTimes > 0) { var target = this.calcTarget(JSON.parse(data.dialData), 8) this.showTurnTableContent(JSON.parse(data.dialData), target) this.turnTimes--; this.runTurn(target); } } return } // 跳過動畫按鈕 let skipBtn = FGUtil.getButton(this.turnTablePanel, "alert/skip"); FGUtil.getControl(skipBtn, "selected").selectedIndex = 1; skipBtn.onClick(this.changeShowAct, this) // 關閉按鈕 let closeBtn = FGUtil.getButton(this.turnTablePanel, "alert/close") this.pushCloseEvent(closeBtn, this.turnTablePanel, () => { this.unscheduleAllCallbacks() }); // 轉一次 let turn1Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn1"); turn1Btn.onClick(this.turn1Times, this); if (this.freeTimes > 0) turn1Btn.visible = false; // 轉五次 let turn5Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn5"); turn5Btn.onClick(this.turn5Times, this); // 免費轉一次 let turn1FreeBtn = FGUtil.getButton(this.turnTablePanel, "alert/free1"); turn1FreeBtn.onClick(this.turn1TimesFree, this); if (this.freeTimes <= 0) turn1FreeBtn.visible = false; // 轉一次mode2 let turn1mode2Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn1mode2"); turn1mode2Btn.onClick(this.turn1Times, this); // 轉五次mode2 let turn5mode2Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn5mode2"); turn5mode2Btn.onClick(this.turn5Times, this); // 開啟風雨寶箱 let openBoxBtn = FGUtil.getButton(this.turnTablePanel, "alert/openbox"); openBoxBtn.onClick(this.openBox, this); // 請求風雨寶箱數據 GameModel.send("c2s_ask_dial_info", { type: 1, genre: 0 }) } // 只刷新次數顯示 onlyRefreshTimes(data) { if (this.mode == 1) { data.one && (this.turn1Price = data.one); data.five && (this.turn5Price = data.five); } else { this.turn1Price = data.one; this.turn5Price = data.five; } // 刷新轉盤價格 this.boxNum = data.dialBoxNum; if (this.mode == 1) { FGUtil.getControl(this.turnTablePanel, "alert/mode2").selectedIndex = 0; this.freeTimes = data.dialNum; let turn1Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn1"); let turn5Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn5"); let turn1FreeBtn = FGUtil.getButton(this.turnTablePanel, "alert/free1"); FGUtil.getTextField(this.turnTablePanel, "alert/free1/count").text = `次數:${this.freeTimes}`; FGUtil.getTextField(this.turnTablePanel, "alert/openbox/count").text = `鑰匙:${this.boxNum}`; if (this.freeTimes > 0) { turn1Btn.visible = false; turn1FreeBtn.visible = true; } else { turn1Btn.visible = true; turn1FreeBtn.visible = false; } turn1Btn.title = `轉一次[img]ui://main_ui/9004[/img][size=24]${this.turn1Price}[size=10]`; turn5Btn.title = `轉五次[img]ui://main_ui/9004[/img][size=24]${this.turn5Price}[size=10]`; } else { FGUtil.getControl(this.turnTablePanel, "alert/mode2").selectedIndex = 1; let turn1Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn1mode2"); let turn5Btn = FGUtil.getButton(this.turnTablePanel, "alert/turn5mode2"); turn1Btn.title = `轉一次[img]ui://main_ui/50019[/img][size=24]X1`; turn5Btn.title = `轉五次[img]ui://main_ui/50019[/img][size=24]X5`; FGUtil.getTextField(turn1Btn, "count").text = "鑰匙:" + this.turn1Price.toString(); FGUtil.getTextField(turn5Btn, "count").text = "鑰匙:" + this.turn5Price.toString(); FGUtil.getTextField(this.turnTablePanel, "alert/openbox/count").text = `鑰匙:${this.boxNum}`; } // 風雨值 FGUtil.getTextField(this.turnTablePanel, "alert/turntable/value").text = `${data.dialCount}/150`; } // 切換動畫開關 changeShowAct() { if (this.stopTap) { MsgAlert.addMsg("請稍後再試") return } this.showAct = !this.showAct; let skipBtn = FGUtil.getButton(this.turnTablePanel, "alert/skip"); FGUtil.getControl(skipBtn, "selected").selectedIndex = this.showAct ? 0 : 1; } // 顯示風雨寶箱獎勵 showBoxContent(data) { this.boxData = data; let prizeContent = FGUtil.getComponent(this.turnTablePanel, "alert/content"); var index = 0; for (let key in data) { var info = data[key] if (info.type == 0) { // 道具 let item = FGUtil.create("main_ui", "prize3"); FGUtil.getTextField(item, "name").text = info.itemName; FGUtil.getTextField(item, "num").text = info.num; var icon = ItemUtil.getItemData(info.itemId).icon FGUtil.getLoader(item, "icon").url = `ui://main_ui/${icon}` item.setPosition(index % 2 == 0 ? 40 : 200, 285 + Math.floor(index / 2 - 1) * 125) item.name = `n${index}` prizeContent.addChild(item) } if (info.type == 1) { // 寵物 let item = FGUtil.create("main_ui", "prize1"); FGUtil.getTextField(item, "name").text = info.itemName; item.setPosition(index % 2 == 0 ? 30 : 190, 100 + Math.floor(index / 2) * 160) this.addUIRole(FGUtil.getComponent(item, "role").node, info.itemId) item.name = `n${index}` prizeContent.asCom.addChild(item) } index++; } } // 顯示轉盤獎品 showTurnTableContent(data, target) { var arr = [0, 1, 2, 3, 4, 5, 6, 7] let prizeContent = FGUtil.getComponent(this.turnTablePanel, "alert/turntable"); let index = 0; arr.splice(target, 1) for (let key in data) { var r = -1 if (index != target) r = Math.floor(Math.random() * arr.length); let info = data[key]; let itemData = ItemUtil.getItemData(info.itemId); let item; if (index != target) { item = FGUtil.getButton(prizeContent, `b${arr[r]}`); arr.splice(r, 1) } else item = FGUtil.getButton(prizeContent, `b${target}`); item.icon = `ui://main_ui/${itemData.icon}`; item.title = info.num; index++; } } /** * 添加人物UI */ addUIRole(pNode, id) { if (!pNode) return; if (this.prefabObject["UIRole"] == null) { cc.loader.loadRes("Prefabs/UIRole", cc.Prefab, (err, prefab) => { if (err) console.warn(err); else { this.prefabObject["UIRole"] = prefab; this.addUIRole(pNode, id) } }) return } var roleNode: cc.Node = cc.instantiate(this.prefabObject["UIRole"]); roleNode.parent = pNode; roleNode.setPosition(0, 55) var info = ItemUtil.getItemData(id).json if (!info) { console.warn("寵物信息錯誤,寵物id:" + id) return } var key = JSON.parse(info).petid; if (SKDataUtil.hasProperty(GameModel.conf_pet, key)) { let resid = GameModel.conf_pet[key].resid; roleNode.getComponent("UIRole").setInfo({ resid: resid, name: '', petcolor: 0 }) roleNode.getComponent("UIRole").offTouchRole(); } } calcTarget(data, max) { var count = 0, rand = 0, idx = 0; for (let key in data) { count += data[key].rate; } rand = Math.random() * count; count = 0; for (let key in data) { count += data[key].rate if (rand < count) { this.dorpId = data[key].itemId this.dorpKey = parseInt(key); return idx; } idx++; } // 以防上面出錯 console.error("概率出錯") // 防止因程序錯誤抽到前兩個珍貴物品 var r = Math.floor(Math.random() * (max - 2)) + 2; this.dorpId = data[r].itemId this.dorpKey = r; return r } // 轉1次 turn1Times() { if (this.stopTap) { MsgAlert.addMsg("請稍後再試") return } if (this.mode == 1 && GameModel.player.gameData.jade < this.turn1Price) { MsgAlert.addMsg("仙玉不足") return } if (this.mode == 2 && this.turn1Price < 1) { MsgAlert.addMsg("道具不足") return } this.turnTimes = 1; this.coastType = 2; this.stopTap = true; this.sendTurnTableData() } // 轉5次 turn5Times() { if (this.stopTap) { MsgAlert.addMsg("請稍後再試") return } if (this.mode == 1 && GameModel.player.gameData.jade < this.turn5Price) { MsgAlert.addMsg("仙玉不足") return } if (this.mode == 2 && this.turn5Price < 5) { MsgAlert.addMsg("道具不足") return } this.turnTimes = 5; this.coastType = 3; this.stopTap = true; this.sendTurnTableData() } // 免費轉1次 turn1TimesFree() { if (this.stopTap) { MsgAlert.addMsg("請稍後再試") return } if (this.freeTimes <= 0) { MsgAlert.addMsg("沒有免費抽獎次數") return } this.turnTimes = 1; this.coastType = 1; this.stopTap = true; this.sendTurnTableData() } // 風雨寶箱 openBox() { if (this.stopTap) { MsgAlert.addMsg("請稍後再試") return } if (this.boxNum <= 0) { MsgAlert.addMsg("沒有風雨寶箱鑰匙") return } // 刷新免費抽獎次數和寶箱鑰匙數量 this.boxNum--; FGUtil.getTextField(this.turnTablePanel, "alert/openbox/count").text = `鑰匙:${this.boxNum}`; this.runTurnByBox(this.calcTarget(this.boxData, 6)) } sendTurnTableData() { // 請求轉盤數據 GameModel.send("c2s_ask_dial_info", { type: 2, genre: this.coastType }) } runTurn(idx) { var fastNums = 3 + Math.floor(Math.random() * 6); var target = idx; if (!this.showAct) { let table = FGUtil.getComponent(this.turnTablePanel, "alert/turntable"); // 全部隱藏 for (let n = 0; n < 8; n++) { FGUtil.getComponent(table, `n${n}`).visible = false; let item = FGUtil.getComponent(table, `b${n}`) FGUtil.getControl(item, "get").selectedIndex = 0; FGUtil.getControl(item, "light").selectedIndex = 0; } FGUtil.getControl(table, `b${target}/get`).selectedIndex = 1; FGUtil.getControl(table, `b${target}/light`).selectedIndex = 0; GameModel.send("c2s_dial_go", { id: this.dorpKey, type: 2 }) this.dorpKey = - 1 if (this.turnTimes > 0) { this.scheduleOnce(() => { this.sendTurnTableData() }, 0.3) } else { this.scheduleOnce(() => { this.coastType = -1; this.stopTap = false }, 0.2) } return } var lowNums = target - fastNums % 8 + 9; var temp = 0; if (lowNums > 4) { temp = lowNums - 4; lowNums -= temp; fastNums += temp; } if (lowNums < 2) { temp = 2 - lowNums; lowNums += temp; fastNums -= temp; } if (fastNums > 8) { fastNums -= 8 } if (fastNums > 8) { fastNums -= 8 } let count = fastNums + lowNums; let fastSpeed = 0.02 let lowAdd = 0.1 / lowNums; let lowSpeed = 0.02 + lowAdd; let time = 0; let table = FGUtil.getComponent(this.turnTablePanel, "alert/turntable"); // 全部隱藏 for (let n = 0; n < 8; n++) { FGUtil.getComponent(table, `n${n}`).visible = false; let item = FGUtil.getComponent(table, `b${n}`) FGUtil.getControl(item, "get").selectedIndex = 0; FGUtil.getControl(item, "light").selectedIndex = 0; } for (let i = 0; i < count; i++) { if (i < fastNums) time += fastSpeed else { time += lowSpeed lowSpeed += lowAdd } this.scheduleOnce(() => { FGUtil.getComponent(table, `n${(i + 7) % 8}`).visible = false; FGUtil.getControl(table, `b${(i + 7) % 8}/light`).selectedIndex = 0; FGUtil.getComponent(table, `n${i % 8}`).visible = true FGUtil.getControl(table, `b${i % 8}/light`).selectedIndex = 1 // 最終請求發放道具 if (i + 1 == count) { FGUtil.getControl(table, `b${i % 8}/get`).selectedIndex = 1; FGUtil.getControl(table, `b${i % 8}/light`).selectedIndex = 0; GameModel.send("c2s_dial_go", { id: this.dorpKey, type: 2 }) this.dorpKey = - 1 } }, time) } if (this.turnTimes > 0) { this.scheduleOnce(() => { this.sendTurnTableData() }, time + 1) } else { this.scheduleOnce(() => { this.coastType = -1; this.stopTap = false }, time + 0.2) } } runTurnByBox(idx) { let box = FGUtil.getComponent(this.turnTablePanel, "prize_box") let mask2 = FGUtil.getComponent(this.turnTablePanel, "mask2") mask2.visible = true; mask2.clearClick() box.visible = true var fastNums = 10 + Math.floor(Math.random() * 6); var target = idx; var lowNums = target - fastNums % 6 + 7; var temp = 0; if (lowNums > 8) { temp = lowNums - 8; lowNums -= temp; fastNums += temp; } if (lowNums < 4) { temp = 4 - lowNums; lowNums += temp; fastNums -= temp; } let count = fastNums + lowNums; let fastSpeed = 0.03 let lowAdd = 0.2 / lowNums; let lowSpeed = 0.03 + lowAdd; let time = 0; var maxChildeNum = 6; // 全部恢復正常並顯示數據 for (let n = 0; n < maxChildeNum; n++) { let item = FGUtil.getComponent(box, `item_${n}`); FGUtil.getControl(item, "select").selectedIndex = 0; FGUtil.getComponent(item, "effect").visible = false; var icon = ItemUtil.getItemData(this.boxData[`${n}`].itemId).icon; FGUtil.getTextField(item, "title").text = this.boxData[`${n}`].num; FGUtil.getLoader(item, "icon").url = `ui://main_ui/${icon}` } for (let i = 0; i < count; i++) { if (i < fastNums) time += fastSpeed else { time += lowSpeed lowSpeed += lowAdd } this.scheduleOnce(() => { let item1 = FGUtil.getComponent(box, `item_${i % maxChildeNum}`); FGUtil.getControl(item1, "select").selectedIndex = 1; let item2 = FGUtil.getComponent(box, `item_${(i + 5) % maxChildeNum}`); FGUtil.getControl(item2, "select").selectedIndex = 0; // 最終請求發放道具 if (i + 1 == count) { FGUtil.getControl(item1, "select").selectedIndex = 0; let effect = FGUtil.getAnim(item1, `effect`); effect.visible = true; effect.playing = true; GameModel.send("c2s_dial_go", { id: target, type: 1 }) } }, time) } this.scheduleOnce(() => { let mask2 = FGUtil.getComponent(this.turnTablePanel, "mask2") mask2.visible = true; mask2.clearClick() mask2.onClick(() => { // 全部恢復正常 for (let n = 0; n < maxChildeNum; n++) { let box = FGUtil.getComponent(this.turnTablePanel, "prize_box") let item = FGUtil.getComponent(box, `item_${n}`); FGUtil.getControl(item, "select").selectedIndex = 0; let effect = FGUtil.getAnim(item, `effect`); effect.visible = false; effect.playing = false; this.stopTap = false box.visible = false mask2.visible = false; } }, this) }, time + 0.5) } /** * 掉落物品 */ dropItemToBag() { if (this.dorpId == -1) return var t = cc.tween; var itemNode = new cc.Node("dropItem"); itemNode.addComponent(cc.Sprite).spriteFrame; var data = ItemUtil.getItemData(this.dorpId); itemNode.getComponent(cc.Sprite).spriteFrame = ItemUtil.getItemIconBy(data); itemNode.getComponent(cc.Sprite).sizeMode = cc.Sprite.SizeMode.CUSTOM itemNode.width = 50; itemNode.height = 50; itemNode.setPosition(this.turnTablePanel.node.width / 2 + 120, -this.turnTablePanel.node.height + 80) itemNode.opacity = 0; itemNode.parent = this.turnTablePanel.node; t(itemNode) .parallel( t().by(0.4, { y: 80 }), t().to(0.2, { opacity: 255 }) ) .delay(0.15) .call(() => { let bezerby = cc.bezierBy(0.5, [cc.v2(88, 10), cc.v2(130, 80), cc.v2(155, -350)]); itemNode.runAction(cc.sequence(cc.spawn(bezerby, cc.rotateBy(0.3, 90)), cc.removeSelf())); }) .start() this.dorpId = -1; } /** * 添加關閉事件 */ pushCloseEvent(item: fairygui.GComponent, target: fairygui.GComponent, call: Function = null) { item.clearClick(); item.onClick(() => { if (this.stopTap) return call && call(); FGUtil.dispose(target); }, this) } }