2025-04-24 17:03:28 +08:00

679 lines
22 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}