All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m14s
1108 lines
32 KiB
TypeScript
1108 lines
32 KiB
TypeScript
import { _decorator, Component, Prefab } from "cc";
|
||
import {
|
||
FREE_SPIN_ROLLER_RULE,
|
||
GameInfo,
|
||
ROLLER_RULE,
|
||
SLOT_BAR_EVENT,
|
||
SLOT_GAME_EVENT,
|
||
SYS_GIFT,
|
||
WIN_TYPE,
|
||
} from "./game/Define";
|
||
import { SlotBar } from "./SlotBar";
|
||
import { SlotGame } from "./SlotGame";
|
||
import { BigWinUI } from "./game/BigWinUI";
|
||
import { GameDataManager } from "../../Loading/scripts/manager/GameDataManager";
|
||
import { callGameApi, getFromUrl } from "../../Loading/scripts/comm";
|
||
import { TipPanel } from "./game/TipPanel";
|
||
import { I18nManager } from "../../Loading/scripts/manager/I18nManager";
|
||
import { TotalWin } from "./game/TotalWin";
|
||
import { AudioManager } from "../../Loading/scripts/manager/AudioManager";
|
||
import { NodePoolManager } from "../../Loading/scripts/manager/NodePoolManager";
|
||
import { FeatureBuy } from "./game/FeatureBuy";
|
||
import { FreeSpinEnter } from "./game/FreeSpinEnter";
|
||
import { FreeSpinAdd } from "./game/FreeSpinAdd";
|
||
import { SysGift } from "./game/SysGift";
|
||
import { ErrorManager } from "../../Loading/scripts/manager/ErrorManager";
|
||
import { SlotRanking } from "../SlotRanking/scripts/SlotRanking";
|
||
|
||
let { ccclass, property } = _decorator;
|
||
|
||
// 游戏状态接口
|
||
interface GameState {
|
||
isOnReconnect: boolean;
|
||
isAutoSpin: boolean;
|
||
isEliminating: boolean;
|
||
isFastSpin: boolean;
|
||
isFirstFreeSpin: boolean;
|
||
isInFreeSpin: boolean;
|
||
isOneRoundEnd: boolean;
|
||
isDebug: boolean;
|
||
isFeatureBuySpin: boolean;
|
||
}
|
||
|
||
// 自动旋转配置接口
|
||
interface AutoSpinConfig {
|
||
count: number;
|
||
delay: {
|
||
fast: number;
|
||
normal: number;
|
||
};
|
||
}
|
||
|
||
@ccclass("SlotScene")
|
||
export class SlotScene extends Component {
|
||
// 组件引用
|
||
@property(SlotGame)
|
||
public slotGame: SlotGame = null;
|
||
|
||
@property(SlotBar)
|
||
private slotBar: SlotBar = null;
|
||
|
||
@property(BigWinUI)
|
||
private BigWinUI: BigWinUI = null;
|
||
|
||
@property(TotalWin)
|
||
private TotalWin: TotalWin = null;
|
||
|
||
@property(TipPanel)
|
||
private TipPanel: TipPanel = null;
|
||
|
||
@property(Prefab)
|
||
private FeatureBuyPre: Prefab = null;
|
||
|
||
@property(FreeSpinEnter)
|
||
private FreeSpinEnter: FreeSpinEnter = null;
|
||
|
||
@property(FreeSpinAdd)
|
||
private FreeSpinAdd: FreeSpinAdd = null;
|
||
|
||
@property(SysGift)
|
||
private SysGift: SysGift = null;
|
||
|
||
@property(SlotRanking)
|
||
slotRanking: SlotRanking = null;
|
||
|
||
// 游戏数据
|
||
private gameInfo: GameInfo = null;
|
||
private spinInfo: any = null;
|
||
private lastSpinInfo: any = null;
|
||
private spinData: any = null;
|
||
private isReceiveMsg: boolean = false;
|
||
|
||
private objectId: string[] = [];
|
||
|
||
// 游戏状态管理
|
||
public gameState: GameState = {
|
||
isOnReconnect: false,
|
||
isAutoSpin: false,
|
||
isEliminating: false,
|
||
isFastSpin: false,
|
||
isFirstFreeSpin: false,
|
||
isInFreeSpin: false,
|
||
isOneRoundEnd: false,
|
||
isFeatureBuySpin: false,
|
||
isDebug: false,
|
||
};
|
||
|
||
// 自动旋转配置
|
||
private autoSpinConfig: AutoSpinConfig = {
|
||
count: 0,
|
||
delay: {
|
||
fast: 0.5,
|
||
normal: 1,
|
||
},
|
||
};
|
||
|
||
batchingTimer: number = 0;
|
||
isErr: boolean = false;
|
||
|
||
async start() {
|
||
this.slotRanking.node.active = true
|
||
this.slotRanking.setSlotScene(this);
|
||
|
||
await this.init();
|
||
// this.TotalWin.show(505000, 10)
|
||
// this.FreeSpinEnter.show(8)
|
||
// this.FreeSpinAdd.show(5)
|
||
// this.BigWinUI.show(800000, WIN_TYPE.SUPER_MEGA_WIN, 10000)
|
||
}
|
||
|
||
private async init() {
|
||
try {
|
||
// 初始化游戏数据
|
||
this.gameInfo = GameDataManager.instance.gameInfo;
|
||
this.lastSpinInfo = this.gameInfo;
|
||
this.spinData = this.gameInfo.Data;
|
||
|
||
this.slotGame.showFeatureBuy(this.gameInfo.CloseBuyGame);
|
||
|
||
// 注册事件监听
|
||
this.slotBar.node.on(
|
||
SLOT_BAR_EVENT.ON_SPIN_CLICK,
|
||
this.spinBtnClick,
|
||
this
|
||
);
|
||
// this.slotBar.node.on(SLOT_BAR_EVENT.ON_TEST_SPIN_CLICK, this.spinBtnClick2, this);
|
||
this.slotBar.node.on(SLOT_BAR_EVENT.BET_CHANGE, this.onBetChanged, this);
|
||
this.slotBar.node.on(
|
||
SLOT_BAR_EVENT.ON_MANUAL_STOP,
|
||
this.manualStop,
|
||
this
|
||
);
|
||
this.slotBar.node.on(SLOT_BAR_EVENT.FAST_SPIN, this.onFastSpin, this);
|
||
this.slotBar.node.on(
|
||
SLOT_BAR_EVENT.ON_AUTO_SPIN_CLICK,
|
||
this.onAutoSpinClick,
|
||
this
|
||
);
|
||
this.slotBar.node.on(
|
||
SLOT_BAR_EVENT.ON_EXIT_CLICK,
|
||
this.onExitClick,
|
||
this
|
||
);
|
||
|
||
this.slotGame.node.on(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_STOP,
|
||
this.allRollerStop,
|
||
this
|
||
);
|
||
this.slotGame.node.on(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_ICONS_DELETED,
|
||
this.onIconsDeleted,
|
||
this
|
||
);
|
||
this.slotGame.node.on(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_ICONS_CREATED,
|
||
this.onIconsCreated,
|
||
this
|
||
);
|
||
this.slotGame.node.on(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_ICONS_FALLEN,
|
||
this.onIconsFallen,
|
||
this
|
||
);
|
||
|
||
this.SysGift.node.on(
|
||
SYS_GIFT.CLICK_CONTINUE,
|
||
this.onSysGiftClickContinue,
|
||
this
|
||
);
|
||
this.SysGift.node.on(
|
||
SYS_GIFT.SETTLE_CONTINUE,
|
||
this.onSysGiftSettleContinue,
|
||
this
|
||
);
|
||
|
||
// 初始化SlotBar
|
||
this.slotBar.setGameInfo(this.gameInfo);
|
||
// 初始化slot
|
||
this.slotGame.initRollerWithIcon(this.gameInfo);
|
||
// 处理断线重连
|
||
this.handleReconnect();
|
||
} catch (error) {
|
||
console.error("Game initialization failed:", error);
|
||
}
|
||
}
|
||
|
||
// 处理断线重连
|
||
private async handleReconnect() {
|
||
this.gameState.isOnReconnect = true;
|
||
this.gameState.isOneRoundEnd = false;
|
||
this.slotGame.showWinScore(false, false, false, false, false);
|
||
let mode = this.gameInfo.Data.Mode;
|
||
let rollerIconRule = mode == 0 ? ROLLER_RULE : FREE_SPIN_ROLLER_RULE;
|
||
|
||
this.checkHasGame();
|
||
this.checkHasEliminate();
|
||
|
||
if (this.gameState.isInFreeSpin) {
|
||
this.slotBar.enterFreeSpin(this.spinData.Free.LeftCount);
|
||
}
|
||
this.slotBar.reconnectState(true);
|
||
this.slotGame.changeBg(this.gameState.isInFreeSpin);
|
||
// this.slotGame.rollerManager.checkNextRollerExpect(6, 1)
|
||
// this.slotGame.showScatterOnIsScroll();
|
||
|
||
if (this.gameState.isInFreeSpin) {
|
||
AudioManager.instance.playBGM("Free_Mode_BGM");
|
||
} else {
|
||
AudioManager.instance.playBGM("Normal_Mode_BGM");
|
||
}
|
||
this.slotGame.setWaysCount(this.spinData.Symbol.WaysNum);
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, this.spinData.WinInfo ? this.spinData.WinInfo.MultPos : null, this.spinData.WinInfo ? this.spinData.WinInfo.Score : null, this.spinData.Symbol.WinMulti, this.gameState.isInFreeSpin);
|
||
this.slotGame.setRollerIconRule(rollerIconRule);
|
||
|
||
let frb = GameDataManager.instance.frb;
|
||
if (frb && frb.Ongoing?.Popup) {
|
||
let frb = GameDataManager.instance.frb;
|
||
if (frb && (frb.Finished || frb.Ongoing)) {
|
||
this.slotBar.setSystemGiftContinue();
|
||
}
|
||
this.SysGift.showOngingPopup();
|
||
} else {
|
||
this.goNextReconnect(false);
|
||
}
|
||
}
|
||
|
||
goNextReconnect(isTwice: boolean) {
|
||
if (isTwice) return;
|
||
// 当前盘面有分数,有消除,则播放消除动画
|
||
if (this.spinData.AllScore != 0 && this.spinData.WinInfo != null) {
|
||
this.slotGame.deleteIconNode();
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, this.spinData.WinInfo.MultPos, this.spinData.Symbol.WinMulti, this.spinData.WinInfo.Score, this.gameState.isInFreeSpin);
|
||
|
||
this.playElemWinAnimation();
|
||
} else {
|
||
this.gameState.isInFreeSpin
|
||
? this.freeSpinStop(true)
|
||
: this.normalStop(true);
|
||
}
|
||
}
|
||
|
||
clickFeatureBuy() {
|
||
if (this.gameState.isInFreeSpin) return;
|
||
if (this.gameState.isEliminating) return;
|
||
if (!this.gameState.isOneRoundEnd) return;
|
||
if (this.slotGame.isScroll()) return;
|
||
AudioManager.instance.playSFX("Feature_Buy_Sound");
|
||
let panel = NodePoolManager.instance.getNodeFromPoolStatic(
|
||
"FeatureBuy",
|
||
this.FeatureBuyPre
|
||
);
|
||
let featureBuy = panel.getComponent(FeatureBuy);
|
||
this.node.addChild(panel);
|
||
featureBuy.show(this.slotBar.getBet(), this.gameInfo.BuyMul, () => {
|
||
this.spinBtnClick(false, true);
|
||
this.gameState.isFeatureBuySpin = true;
|
||
|
||
this.slotBar.featureBuySpin();
|
||
});
|
||
}
|
||
|
||
async spinBtnClick(
|
||
isFreeSpin: boolean = false,
|
||
isFeatureBuy: boolean = false
|
||
) {
|
||
try {
|
||
this.gameState.isOnReconnect = false;
|
||
this.isReceiveMsg = false;
|
||
|
||
this.isErr = false
|
||
this.slotGame.spin(this.gameState.isInFreeSpin);
|
||
this.gameState.isOneRoundEnd = false;
|
||
this.slotGame.changeBg(this.gameState.isInFreeSpin);
|
||
this.slotGame.hideIconMsg();
|
||
|
||
if (!isFreeSpin) {
|
||
this.slotBar.setWin(0);
|
||
}
|
||
// 如果有frb就不会扣除金额
|
||
let frb = GameDataManager.instance.frb;
|
||
if (frb && frb.Ongoing != null) {
|
||
|
||
} else {
|
||
if (!isFreeSpin) {
|
||
if (!isFeatureBuy) {
|
||
this.slotBar.setBalance(this.slotBar.getBalance() - this.slotBar.getBet());
|
||
} else {
|
||
this.slotBar.setBalance(this.slotBar.getBalance() - (this.slotBar.getBet() * this.gameInfo.BuyMul));
|
||
}
|
||
}
|
||
}
|
||
|
||
let msg = {};
|
||
if (!isFeatureBuy) {
|
||
msg = {
|
||
Bet: this.slotBar.getBet(),
|
||
};
|
||
} else {
|
||
msg = {
|
||
Bet: this.slotBar.getBet(),
|
||
IsBuy: true,
|
||
};
|
||
}
|
||
if (!this.gameState.isDebug) {
|
||
this.spinInfo = await callGameApi("spin", msg);
|
||
this.slotBar.allowClickManualStop(true)
|
||
this.slotBar.notAllowClickManualStop(false)
|
||
if (this.spinInfo.Frb.Ongoing) {
|
||
if (!isFreeSpin) {
|
||
let count = this.spinInfo.Frb.Ongoing.Frn;
|
||
if (count <= 0) {
|
||
count = 0;
|
||
}
|
||
this.SysGift.handleSysInfoFreeCount(count);
|
||
}
|
||
if (this.gameState.isAutoSpin) {
|
||
this.slotBar.closeAutoSpin();
|
||
}
|
||
}
|
||
if (this.spinInfo.Frb.Finished) {
|
||
if (!isFreeSpin) {
|
||
let count = this.spinInfo.Frb.Finished.Frn;
|
||
if (count <= 0) {
|
||
count = 0;
|
||
}
|
||
this.SysGift.handleSysInfoFreeCount(count);
|
||
}
|
||
}
|
||
|
||
GameDataManager.instance.frb = this.spinInfo.Frb;
|
||
} else {
|
||
this.spinInfo = null;
|
||
}
|
||
|
||
if (this.TipPanel.getHasTip()) {
|
||
this.TipPanel.closeTip();
|
||
}
|
||
|
||
this.lastSpinInfo = this.spinInfo;
|
||
this.isReceiveMsg = true;
|
||
await this.handleSpinResult();
|
||
} catch (error) {
|
||
this.isErr = true
|
||
let errCode = parseInt(error.message.split("#")[0]);
|
||
if (isNaN(errCode)) {
|
||
this.showErrorTip(4);
|
||
ErrorManager.instance.reportError("onSpinBtnClick: " + error.message);
|
||
} else {
|
||
this.showErrorTip(errCode);
|
||
}
|
||
this.handleErrSpin();
|
||
}
|
||
}
|
||
|
||
// 万分比
|
||
private onBetChanged(bet: number) {
|
||
if (!this.gameInfo.CloseBuyGame) {
|
||
this.slotGame.showFeatureBuy(
|
||
bet * this.gameInfo.BuyMul > this.gameInfo.MaxBuyBet
|
||
);
|
||
}
|
||
}
|
||
|
||
manualStop() {
|
||
// 没有收到消息不能手动停止
|
||
if (!this.isReceiveMsg) return;
|
||
|
||
// 免费游戏不能手动停止
|
||
// if (this.gameState.isInFreeSpin) {
|
||
// return;
|
||
// }
|
||
|
||
// 滚轮没有开始旋转的时候不能停止
|
||
if (!this.slotGame.isScroll()) return;
|
||
|
||
this.slotBar.manualStop();
|
||
this.slotGame.manualStop();
|
||
}
|
||
|
||
private handleErrSpin() {
|
||
this.spinInfo = this.lastSpinInfo;
|
||
this.spinData = this.spinInfo.Data;
|
||
this.slotGame.setRollerIconRule(
|
||
this.spinData.Mode == 0 ? ROLLER_RULE : FREE_SPIN_ROLLER_RULE
|
||
);
|
||
this.gameState.isAutoSpin = false;
|
||
this.spinData.AllScore = 0;
|
||
this.slotGame.stopScroll(this.spinData, false, null);
|
||
this.slotGame.manualStop();
|
||
this.slotBar.setBalance(this.spinInfo.Balance);
|
||
}
|
||
|
||
private async handleSpinResult() {
|
||
this.spinData = this.spinInfo.Data;
|
||
this.slotGame.stopScroll(this.spinData, false, null, null);
|
||
}
|
||
|
||
private onFastSpin(isFastSpin: boolean) {
|
||
this.gameState.isFastSpin = isFastSpin;
|
||
let tip = this.gameState.isFastSpin
|
||
? I18nManager.instance.t("AID_TIP_TURBO_ENABLED")
|
||
: I18nManager.instance.t("AID_TIP_TURBO_DISABLED");
|
||
|
||
this.slotBar.showTipSmall(tip);
|
||
if (!this.slotGame.isScroll()) {
|
||
this.slotGame.setFastSpin(isFastSpin);
|
||
}
|
||
}
|
||
|
||
private onAutoSpinClick(isAuto: boolean, isReconnect: boolean) {
|
||
this.gameState.isAutoSpin = isAuto;
|
||
this.autoSpinConfig.count = GameDataManager.instance.autoCount;
|
||
|
||
// 只有在不旋转的时候才可以设置自动旋转,所以不需要额外处理
|
||
if (isAuto) {
|
||
this.checkAutoSpin(false, isReconnect);
|
||
}
|
||
}
|
||
|
||
private checkAutoSpin(hasWin: boolean = false, isReconnect: boolean) {
|
||
// 处理自动旋转
|
||
let handleAutoSpin = () => {
|
||
this.gameState.isOneRoundEnd = true;
|
||
if (this.autoSpinConfig.count > 0) {
|
||
this.autoSpinConfig.count--;
|
||
this.slotBar.setLeftAutoCount(this.autoSpinConfig.count);
|
||
this.spinBtnClick();
|
||
|
||
if (this.autoSpinConfig.count === 0) {
|
||
this.slotBar.closeAutoSpin();
|
||
}
|
||
}
|
||
};
|
||
|
||
// 处理自动旋转已经走到最后一步了和当前一轮流程走完最后的逻辑
|
||
let handleNonAutoSpin = (hasWin: boolean, isReconnect: boolean) => {
|
||
let delay = hasWin ? 0.2 : 0;
|
||
this.scheduleOnce(() => {
|
||
let frb = GameDataManager.instance.frb;
|
||
if (frb.Finished?.Popup) {
|
||
this.SysGift.showSysFreeWinSettle();
|
||
}
|
||
|
||
if (frb.Ongoing?.Popup) {
|
||
this.SysGift.showOngingPopup();
|
||
}
|
||
|
||
if (frb.Finished == null && frb.Ongoing?.Popup == false) {
|
||
this.slotBar.resetAllState();
|
||
if (frb && (frb.Finished || frb.Ongoing)) {
|
||
this.slotBar.setSystemGiftContinue();
|
||
this.SysGift.handleSysInfoFreeWin();
|
||
}
|
||
}
|
||
|
||
if (frb.Finished == null && frb.Ongoing == null) {
|
||
this.slotBar.resetAllState();
|
||
this.gameState.isOneRoundEnd = true;
|
||
}
|
||
|
||
if (frb.Ongoing?.Popup) {
|
||
this.slotBar.resetAllState();
|
||
this.slotBar.setSystemGiftContinue();
|
||
}
|
||
|
||
this.gameState.isOnReconnect = false;
|
||
}, delay);
|
||
|
||
this.autoSpinConfig.count = 0;
|
||
};
|
||
|
||
// 进入freeSpin不检测
|
||
if (this.gameState.isFirstFreeSpin) return;
|
||
// 是否是快速旋转
|
||
let delay = this.gameState.isFastSpin
|
||
? this.autoSpinConfig.delay.fast
|
||
: this.autoSpinConfig.delay.normal;
|
||
|
||
if (this.gameState.isAutoSpin && this.autoSpinConfig.count > 0) {
|
||
this.scheduleOnce(() => {
|
||
handleAutoSpin();
|
||
}, delay);
|
||
} else {
|
||
handleNonAutoSpin(hasWin, isReconnect);
|
||
}
|
||
}
|
||
|
||
allRollerStop() {
|
||
this.slotGame.setFastSpin(this.gameState.isFastSpin);
|
||
this.checkHasGame();
|
||
// this.slotGame.rollerManager.checkNextRollerExpect(6, 1)
|
||
// this.slotGame.showScatterOnIsScroll();
|
||
// this.TotalWin.show(35, () => {
|
||
// this.slotBar.resetAllState();
|
||
// });
|
||
// return;
|
||
if (this.checkHasEliminate()) {
|
||
this.slotGame.deleteIconNode();
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, this.spinData.WinInfo.MultPos, this.spinData.Symbol.WinMulti, this.spinData.WinInfo.Score, this.gameState.isInFreeSpin);
|
||
|
||
this.playElemWinAnimation(true);
|
||
|
||
} else {
|
||
if (this.gameState.isInFreeSpin) {
|
||
if (this.gameState.isFirstFreeSpin) {
|
||
// 第一次进入免费旋转需要切换背景和展示免费次数
|
||
let isExpect = this.slotGame.rollerManager.checkNextRollerExpect(
|
||
6,
|
||
4
|
||
);
|
||
if (isExpect) {
|
||
this.slotGame.playScatterAni(() => {
|
||
this.FreeSpinEnter.show(
|
||
this.spinInfo.Data.Free.MaxCount,
|
||
() => {
|
||
this.slotGame.changeBg(true);
|
||
this.slotBar.enterFreeSpin(
|
||
this.spinInfo.Data.Free.LeftCount
|
||
);
|
||
this.scheduleOnce(() => {
|
||
this.freeSpinStop();
|
||
}, 1);
|
||
}
|
||
);
|
||
});
|
||
}
|
||
} else {
|
||
if (this.checkHasMoreScatter()) {
|
||
let isExpect = this.slotGame.rollerManager.checkNextRollerExpect(
|
||
6,
|
||
4
|
||
);
|
||
if (isExpect) {
|
||
this.slotGame.playScatterAni(() => {
|
||
this.FreeSpinAdd.show(this.spinInfo.Data.Free.GamesTimes, () => {
|
||
this.slotBar.showLeftCount(
|
||
this.spinInfo.Data.Free.LeftCount
|
||
);
|
||
this.scheduleOnce(() => {
|
||
this.freeSpinStop();
|
||
}, 1);
|
||
});
|
||
});
|
||
}
|
||
} else {
|
||
this.freeSpinStop();
|
||
}
|
||
}
|
||
} else {
|
||
this.normalStop();
|
||
}
|
||
}
|
||
}
|
||
|
||
private deletedRetryCount: number = 0;
|
||
async onIconsDeleted() {
|
||
try {
|
||
this.isReceiveMsg = false;
|
||
this.isErr = false
|
||
if (!this.gameState.isDebug) {
|
||
this.spinInfo = await callGameApi("spin", {
|
||
Bet: this.slotBar.getBet(),
|
||
});
|
||
GameDataManager.instance.frb = this.spinInfo.Frb;
|
||
} else {
|
||
this.spinInfo = {};
|
||
}
|
||
|
||
this.lastSpinInfo = this.spinInfo;
|
||
this.isReceiveMsg = true;
|
||
|
||
this.slotGame.getNewMulti(this.gameState.isInFreeSpin, this.spinData.WinInfo.MultPos)
|
||
|
||
// 处理数据
|
||
|
||
this.spinData = this.spinInfo.Data;
|
||
// 改变图标框和图标
|
||
this.slotGame.changeIconAndFrameType(this.spinData);
|
||
|
||
// 创建新图标
|
||
this.slotGame.createNewIconTop(this.spinData);
|
||
// this.slotGame.iconFallDown_Pan();
|
||
|
||
} catch (error) {
|
||
this.isErr = true
|
||
let errCode = parseInt(error.message.split("#")[0]);
|
||
if (isNaN(errCode)) {
|
||
// ErrorManager.instance.reportError("onIconsDeleted: " + error.message);
|
||
this.showErrorTip(5, () => {
|
||
this.deletedRetryCount++;
|
||
if (this.deletedRetryCount < 5) {
|
||
this.scheduleOnce(() => {
|
||
this.onIconsDeleted();
|
||
}, 0.5);
|
||
} else {
|
||
location.reload();
|
||
}
|
||
});
|
||
} else {
|
||
this.showErrorTip(errCode);
|
||
}
|
||
}
|
||
}
|
||
|
||
onIconsCreated() {
|
||
// let delay = (this.spinData.WinInfo && this.spinData.WinInfo.MultPos) ? 1 : 0
|
||
this.slotGame.iconFallDown_PanOut();
|
||
}
|
||
|
||
onIconsFallen() {
|
||
this.checkHasGame();
|
||
if (this.checkHasEliminate()) {
|
||
this.slotGame.deleteIconNode();
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, this.spinData.WinInfo.MultPos, this.spinData.Symbol.WinMulti, this.spinData.WinInfo.Score, this.gameState.isInFreeSpin);
|
||
|
||
this.playElemWinAnimation();
|
||
} else {
|
||
if (this.gameState.isInFreeSpin) {
|
||
if (this.gameState.isFirstFreeSpin) {
|
||
// 检测所有scatter
|
||
let isExpect = this.slotGame.rollerManager.checkNextRollerExpect(
|
||
6,
|
||
4
|
||
);
|
||
if (isExpect) {
|
||
this.slotGame.playScatterAni(() => {
|
||
// 第一次进入免费旋转需要切换背景和展示免费次数
|
||
this.FreeSpinEnter.show(
|
||
this.spinInfo.Data.Free.MaxCount,
|
||
() => {
|
||
this.slotGame.changeBg(true);
|
||
this.slotBar.enterFreeSpin(
|
||
this.spinInfo.Data.Free.LeftCount
|
||
);
|
||
this.scheduleOnce(() => {
|
||
this.freeSpinStop();
|
||
}, 1);
|
||
}
|
||
);
|
||
});
|
||
}
|
||
} else {
|
||
if (this.checkHasMoreScatter()) {
|
||
let isExpect = this.slotGame.rollerManager.checkNextRollerExpect(
|
||
6,
|
||
4
|
||
);
|
||
if (isExpect) {
|
||
this.slotGame.rollerManager.checkNextRollerExpect(6, 4);
|
||
this.slotGame.playScatterAni(() => {
|
||
this.FreeSpinAdd.show(this.spinInfo.Data.Free.GamesTimes, () => {
|
||
this.slotBar.showLeftCount(
|
||
this.spinInfo.Data.Free.LeftCount
|
||
);
|
||
this.scheduleOnce(() => {
|
||
this.freeSpinStop();
|
||
}, 1);
|
||
});
|
||
});
|
||
}
|
||
} else {
|
||
this.freeSpinStop();
|
||
}
|
||
}
|
||
} else {
|
||
this.normalStop();
|
||
}
|
||
}
|
||
}
|
||
|
||
playElemWinAnimation(isFirstWin: boolean = false) {
|
||
this.slotGame.showWinScore(
|
||
true,
|
||
isFirstWin,
|
||
false,
|
||
false,
|
||
false,
|
||
this.spinData.Symbol.WinMulti == 0,
|
||
this.spinData.WinInfo.Score / (this.spinData.Symbol.WinMulti != 0 ? this.spinData.Symbol.WinMulti : 1)
|
||
);
|
||
this.slotBar.setWin(this.spinData.AllScore);
|
||
}
|
||
|
||
checkHasGame() {
|
||
let freeSpinData = this.spinData.Free;
|
||
this.gameState.isInFreeSpin = freeSpinData != null;
|
||
if (this.gameState.isInFreeSpin) {
|
||
if (freeSpinData.LeftCount == freeSpinData.MaxCount) {
|
||
this.gameState.isFirstFreeSpin = true;
|
||
} else {
|
||
this.gameState.isFirstFreeSpin = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
checkHasEliminate() {
|
||
this.gameState.isEliminating = this.spinData.WinInfo != null; // 重置消除状态
|
||
this.slotGame.setIsEliminating(this.gameState.isEliminating); // 传递给 SlotGame
|
||
return this.spinData.WinInfo != null;
|
||
}
|
||
|
||
checkHasMoreScatter() {
|
||
return this.spinData.Free.GamesTimes > 0;
|
||
}
|
||
|
||
private async normalStop(isReconnect: boolean = false) {
|
||
this.slotBar.setBalance(this.spinData.Balance);
|
||
let winType = this.slotGame.checkWinType(this.spinData.AllScore);
|
||
|
||
await this.handleWinResult(winType, isReconnect, false, () => {
|
||
this.checkAutoSpin(winType !== WIN_TYPE.NONE, isReconnect);
|
||
});
|
||
}
|
||
|
||
private async freeSpinStop(isReconnect: boolean = false) {
|
||
let leftCount = this.spinData.Free.LeftCount;
|
||
|
||
if (leftCount >= 1) {
|
||
let score = 0;
|
||
if (this.spinData.RoundInfo != null) {
|
||
score = this.spinData.RoundInfo.Score;
|
||
}
|
||
let winType = this.slotGame.checkWinType(score);
|
||
await this.handleOngoingFreeSpin(leftCount, winType);
|
||
} else {
|
||
if (isReconnect) {
|
||
let allScoreWinType = this.slotGame.checkWinType(
|
||
this.spinData.AllScore
|
||
);
|
||
this.handleFreeSpinEnd(allScoreWinType, isReconnect);
|
||
} else {
|
||
let score = 0;
|
||
let time = 1;
|
||
if (this.spinData.RoundInfo != null) {
|
||
score = this.spinData.RoundInfo.Score;
|
||
time = 3;
|
||
}
|
||
let winType = this.slotGame.checkWinType(score);
|
||
|
||
this.handleWinResult(winType, false, true, () => {
|
||
setTimeout(() => {
|
||
let allScoreWinType = this.slotGame.checkWinType(
|
||
this.spinData.AllScore
|
||
);
|
||
this.handleFreeSpinEnd(allScoreWinType, isReconnect);
|
||
}, time * 1000); // 转换为毫秒
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
private handleNextFreeSpin(leftCount: number) {
|
||
this.scheduleOnce(() => {
|
||
this.slotBar.showLeftCount(leftCount - 1);
|
||
this.spinBtnClick(true, false);
|
||
}, 1);
|
||
}
|
||
|
||
private async handleOngoingFreeSpin(leftCount: number, winType: WIN_TYPE) {
|
||
|
||
this.handleWinResult(winType, false, true, () => {
|
||
this.handleNextFreeSpin(leftCount);
|
||
});
|
||
}
|
||
|
||
private async handleFreeSpinEnd(
|
||
winType: WIN_TYPE,
|
||
isReconnect: boolean = false
|
||
) {
|
||
this.gameState.isFirstFreeSpin = false;
|
||
this.gameState.isFeatureBuySpin = false;
|
||
|
||
this.gameState.isInFreeSpin = false;
|
||
this.slotBar.exitFreeSpin();
|
||
|
||
if (winType != WIN_TYPE.NONE) {
|
||
if (!isReconnect) {
|
||
if (this.isErr) {
|
||
this.slotBar.setBalance(this.spinData.Balance);
|
||
this.slotGame.showWinScore(
|
||
true,
|
||
false,
|
||
true,
|
||
isReconnect,
|
||
false,
|
||
true,
|
||
this.spinData.AllScore
|
||
);
|
||
this.slotBar.setWin(this.spinData.AllScore);
|
||
this.slotGame.changeBg(false);
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, null, null, 0, false)
|
||
this.checkAutoSpin(true, isReconnect);
|
||
AudioManager.instance.playBGM("Normal_Mode_BGM");
|
||
return
|
||
}
|
||
|
||
this.TotalWin.show(this.spinData.AllScore, this.spinInfo.Data.Free.MaxCount, () => {
|
||
this.slotBar.setBalance(this.spinData.Balance);
|
||
this.slotGame.showWinScore(
|
||
true,
|
||
false,
|
||
true,
|
||
isReconnect,
|
||
false,
|
||
true,
|
||
this.spinData.AllScore
|
||
);
|
||
this.slotBar.setWin(this.spinData.AllScore);
|
||
this.slotGame.changeBg(false);
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, null, null, 0, false)
|
||
this.checkAutoSpin(true, isReconnect);
|
||
AudioManager.instance.playBGM("Normal_Mode_BGM");
|
||
});
|
||
} else {
|
||
this.slotGame.showWinScore(
|
||
true,
|
||
false,
|
||
true,
|
||
isReconnect,
|
||
false,
|
||
true,
|
||
this.spinData.AllScore
|
||
);
|
||
this.slotBar.setWin(this.spinData.AllScore);
|
||
this.slotBar.setBalance(this.spinData.Balance);
|
||
this.slotGame.changeBg(false);
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, null, null, 0, false)
|
||
this.checkAutoSpin(true, isReconnect);
|
||
AudioManager.instance.playBGM("Normal_Mode_BGM");
|
||
}
|
||
} else {
|
||
this.checkAutoSpin(true, isReconnect);
|
||
this.slotGame.changeBg(false);
|
||
this.slotGame.setMultiLabel(this.spinData.Symbol.MultiValue, null, null, 0, false)
|
||
}
|
||
}
|
||
|
||
private async handleWinResult(
|
||
winType: WIN_TYPE,
|
||
isReconnect,
|
||
isFreeSpin: boolean,
|
||
callback: Function
|
||
) {
|
||
if (isReconnect) {
|
||
callback?.();
|
||
return;
|
||
}
|
||
|
||
// 1
|
||
if (
|
||
this.spinData.HitBlock &&
|
||
this.spinData.HitBlock.length < 5 &&
|
||
this.spinData.AllScore === 0
|
||
) {
|
||
callback?.();
|
||
return;
|
||
}
|
||
|
||
// 2
|
||
if (winType === WIN_TYPE.NONE) {
|
||
callback?.();
|
||
return;
|
||
}
|
||
|
||
// 3,4,5
|
||
let delay = 0.1
|
||
// if (this.spinData.Symbol.WinMulti != 0) {
|
||
// delay = 1.2
|
||
// }
|
||
|
||
|
||
this.scheduleOnce(() => {
|
||
|
||
let score = isFreeSpin
|
||
? this.spinData.RoundInfo.Score
|
||
: this.spinData.AllScore;
|
||
if (winType >= WIN_TYPE.BIG_WIN) {
|
||
this.BigWinUI.setCloseCallBack(() => {
|
||
this.slotGame.showWinScore(true, false, true, false, false, true, score);
|
||
this.slotBar.setWin(this.spinData.AllScore);
|
||
callback?.();
|
||
});
|
||
this.BigWinUI.show(score, winType, this.slotBar.getBet());
|
||
} else {
|
||
this.slotGame.showWinScore(true, false, false, false, true, true, score);
|
||
this.slotBar.setWin(this.spinData.AllScore);
|
||
callback?.();
|
||
}
|
||
}, delay);
|
||
}
|
||
|
||
// 错误码提示
|
||
private showErrorTip(errorCode: number, callback?) {
|
||
let title = I18nManager.instance.t("AID_ERROR_TITLE");
|
||
let msg1 = "";
|
||
let msg2 = "";
|
||
let tip = "";
|
||
switch (errorCode) {
|
||
case 1:
|
||
msg1 = I18nManager.instance.t("AID_ERROR_CONTENT_1");
|
||
msg2 = I18nManager.instance.t("AID_ERROR_CODE_1");
|
||
tip = `${msg1}\n${msg2}`;
|
||
if (!this.TipPanel.getHasTip()) {
|
||
this.TipPanel.showTip(
|
||
title,
|
||
tip,
|
||
() => {
|
||
window.close();
|
||
},
|
||
null,
|
||
I18nManager.instance.t("AID_QUIT_RIGHT_BUTTON"),
|
||
null,
|
||
false
|
||
);
|
||
}
|
||
break;
|
||
case 2:
|
||
msg1 = I18nManager.instance.t("AID_ERROR_CONTENT_2");
|
||
msg2 = I18nManager.instance.t("AID_ERROR_CODE_2");
|
||
tip = `${msg1}\n${msg2}`;
|
||
if (!this.TipPanel.getHasTip()) {
|
||
this.TipPanel.showTip(
|
||
title,
|
||
tip,
|
||
null,
|
||
null,
|
||
I18nManager.instance.t("AID_ERROR_OK_BUTTON"),
|
||
null,
|
||
false
|
||
);
|
||
}
|
||
break;
|
||
case 3:
|
||
msg1 = I18nManager.instance.t("AID_ERROR_CONTENT_3");
|
||
msg2 = I18nManager.instance.t("AID_ERROR_CODE_3");
|
||
tip = `${msg1}\n${msg2}`;
|
||
if (!this.TipPanel.getHasTip()) {
|
||
this.TipPanel.showTip(
|
||
title,
|
||
tip,
|
||
null,
|
||
null,
|
||
I18nManager.instance.t("AID_ERROR_OK_BUTTON"),
|
||
null,
|
||
false
|
||
);
|
||
}
|
||
break;
|
||
case 4:
|
||
msg1 = I18nManager.instance.t("AID_ERROR_CONTENT_4");
|
||
msg2 = I18nManager.instance.t("AID_ERROR_CODE_4");
|
||
tip = `${msg1}\n${msg2}`;
|
||
if (!this.TipPanel.getHasTip()) {
|
||
this.TipPanel.showTip(
|
||
title,
|
||
tip,
|
||
() => {
|
||
window.close();
|
||
},
|
||
null,
|
||
I18nManager.instance.t("AID_QUIT_RIGHT_BUTTON"),
|
||
null,
|
||
false
|
||
);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
private onExitClick() {
|
||
this.TipPanel.showTip(
|
||
I18nManager.instance.t("AID_QUIT_TITLE"),
|
||
I18nManager.instance.t("AID_QUIT_CONTENT"),
|
||
null,
|
||
() => {
|
||
let fromUrl = getFromUrl();
|
||
if (fromUrl.length == 0) {
|
||
window.close();
|
||
} else {
|
||
window.location.replace(fromUrl);
|
||
}
|
||
},
|
||
I18nManager.instance.t("AID_QUIT_LEFT_BUTTON"),
|
||
I18nManager.instance.t("AID_ERROR_QUIT_BUTTON")
|
||
);
|
||
}
|
||
|
||
onDestroy() {
|
||
// 清理事件监听
|
||
this.slotBar.node.off(
|
||
SLOT_BAR_EVENT.ON_SPIN_CLICK,
|
||
this.spinBtnClick,
|
||
this
|
||
);
|
||
this.slotBar.node.off(SLOT_BAR_EVENT.ON_MANUAL_STOP, this.manualStop, this);
|
||
this.slotBar.node.off(SLOT_BAR_EVENT.FAST_SPIN, this.onFastSpin, this);
|
||
this.slotBar.node.off(
|
||
SLOT_BAR_EVENT.ON_AUTO_SPIN_CLICK,
|
||
this.onAutoSpinClick,
|
||
this
|
||
);
|
||
this.slotBar.node.off(SLOT_BAR_EVENT.ON_EXIT_CLICK, this.onExitClick, this);
|
||
|
||
this.slotGame.node.off(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_STOP,
|
||
this.allRollerStop,
|
||
this
|
||
);
|
||
this.slotGame.node.off(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_ICONS_DELETED,
|
||
this.onIconsDeleted,
|
||
this
|
||
);
|
||
this.slotGame.node.off(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_ICONS_CREATED,
|
||
this.onIconsCreated,
|
||
this
|
||
);
|
||
this.slotGame.node.off(
|
||
SLOT_GAME_EVENT.ALL_ROLLER_ICONS_FALLEN,
|
||
this.onIconsFallen,
|
||
this
|
||
);
|
||
this.unscheduleAllCallbacks();
|
||
}
|
||
|
||
// -----------调试
|
||
|
||
async spinBtnClick2(args) {
|
||
try {
|
||
this.isReceiveMsg = false;
|
||
this.slotGame.spin(this.gameState.isInFreeSpin);
|
||
this.slotGame.changeBg(this.gameState.isInFreeSpin);
|
||
this.slotBar.setWin(0);
|
||
this.slotBar.setBalance(
|
||
this.slotBar.getBalance() - this.slotBar.getBet()
|
||
);
|
||
if (!this.gameState.isDebug) {
|
||
this.spinInfo = await callGameApi("spin_dev", {
|
||
Bet: this.slotBar.getBet(),
|
||
ObjectId: this.objectId[args],
|
||
});
|
||
} else {
|
||
this.spinInfo = {};
|
||
}
|
||
this.lastSpinInfo = this.spinInfo;
|
||
this.isReceiveMsg = true;
|
||
await this.handleSpinResult();
|
||
} catch (error) {
|
||
let errCode = parseInt(error.message.split("#")[0]);
|
||
this.showErrorTip(errCode);
|
||
this.handleErrSpin();
|
||
}
|
||
}
|
||
|
||
onSysGiftClickContinue(bet: number) {
|
||
this.gameState.isOnReconnect = false;
|
||
// 获取frb对象,并将其Ongoing.Popup设为false
|
||
let frb = GameDataManager.instance.frb;
|
||
if (frb && frb.Ongoing) {
|
||
frb.Ongoing.Popup = false;
|
||
}
|
||
this.goNextReconnect(false);
|
||
this.slotBar.setSystemGiftContinue();
|
||
this.slotBar.setSysGiftBet(bet * 10000);
|
||
this.slotGame.setFeatureBuyInteractable(false);
|
||
}
|
||
|
||
// 进入游戏判断
|
||
// 1.是否有免费赠送,
|
||
// 2.如果有免费赠送 ,弹出窗口,继续游戏
|
||
|
||
// 1.当前游戏正在进行中
|
||
// 2.收到赠送消息,这时候在消息的最后一步,需要弹出窗口。
|
||
|
||
onSysGiftSettleContinue() {
|
||
let frb = GameDataManager.instance.frb;
|
||
if (frb && frb.Finished) {
|
||
frb.Finished.Popup = false;
|
||
}
|
||
GameDataManager.instance.frb.Finished = null;
|
||
this.slotBar.setSystemGiftConfirm();
|
||
this.slotGame.setFeatureBuyInteractable(true);
|
||
this.slotBar.resetAllState();
|
||
this.gameState.isOneRoundEnd = true;
|
||
}
|
||
}
|