/* eslint-disable */ // @ts-nocheck import { _decorator, Component, Prefab, Node, Label, Animation, Color, Button, Sprite, Tween, tween, v3, UIOpacity, Vec3, UITransform, Size, view, Layout, sp, AsyncDelegate } from 'cc'; import { SLOT_BAR_EVENT } from './game/Define'; import { AutoSpinPanel } from './game/AutoSpinPanel'; import { NodePoolManager } from '../../Loading/scripts/manager/NodePoolManager'; import { webView } from './game/WebView'; import { getHistoryUrl, getOddsUrl, getSupportUrl, gold2cash } from '../../Loading/scripts/comm'; import { GameDataManager } from '../../Loading/scripts/manager/GameDataManager'; import { I18nManager } from '../../Loading/scripts/manager/I18nManager'; import { LocalizedSprite } from '../../Loading/scripts/i18n/LocalizedSprite'; import { AudioManager } from '../../Loading/scripts/manager/AudioManager'; import { SpinAni } from './game/SpinAni'; const { ccclass, property } = _decorator; @ccclass('SlotBar') export class SlotBar extends Component { @property({ type: Prefab }) private webViewPre: Prefab = null; @property({ type: Prefab }) private autoSpinPanel: Prefab = null; @property(Node) private tipSmall: Node = null; @property(Node) private manualStopNode: Node = null; private MaskNode: Node = null; private balanceLabel: Label = null; private betLabel: Label = null; private winLabel: Label = null; private btns1: Node = null; private btns2: Node = null; private btns3: Node = null; private autoBtn: Node = null; private turboBtn: Node = null; private subBtn: Button = null; private addBtn: Button = null; private menuBtn: Button = null; spinNode: Node = null; grayBtn: Node = null; spinBtn: Button = null; spinAni: SpinAni = null; stopAutoBtn: Button = null; private leftAutoCount: Label = null; private autoBtnAni: Animation = null; private turboBtnAni: Animation = null; private freeSpinBg: Node = null; private left_1: Node = null; private leftCount: sp.Skeleton = null; private left_2: Node = null; private Msg: Node = null; private gameInfo: any = null; // 初始信息 private betGrade: number[] = []; // 下注区间 private curBalance: number = 0; // 当前剩余金币 private curBet: number = 0; // 当前下注区间 private curWin: number = 0; // 当前赢分 private betIndex: number = 0; // 下注区间下标 private thisRotateTime: number = 0; // 当前次滚动已经持续的时间 private tweenIsEnd: boolean = true; // 动画是否完成 isAuto: boolean = false; isFastSpin: boolean = false; private btnPositions: Map = new Map(); private isAnimating: boolean = false; private readonly DURATION = 0.1; private readonly OFFSET_Y = -200; private hasClickSpin: boolean = false; private hasClickManualStop: boolean = false; protected onLoad(): void { this.MaskNode = this.node.parent.parent; this.Msg = this.node.getChildByName('Msg'); let Labels = this.Msg.getChildByName('Labels'); this.balanceLabel = Labels.getChildByName('balance').getComponent(Label); this.betLabel = Labels.getChildByName('bet').getComponent(Label); this.winLabel = Labels.getChildByName('win').getComponent(Label); this.spinNode = this.node.getChildByName('SpinNode'); this.grayBtn = this.spinNode.getChildByName('grayBtn'); this.spinAni = this.spinNode.getComponent(SpinAni); this.spinBtn = this.spinNode.getChildByName('spinBtn').getComponent(Button); this.stopAutoBtn = this.spinNode.getChildByName('BtnStopAuto').getComponent(Button); this.leftAutoCount = this.stopAutoBtn.node.getChildByName('count').getComponent(Label); this.btns1 = this.node.getChildByName('Btns1'); this.autoBtn = this.btns1.getChildByName('Auto'); this.turboBtn = this.btns1.getChildByName('Turbo'); this.subBtn = this.btns1.getChildByName('ic_subChips').getComponent(Button); this.addBtn = this.btns1.getChildByName('ic_addChips').getComponent(Button); this.menuBtn = this.btns1.getChildByName('ic_menu').getComponent(Button); this.freeSpinBg = this.node.getChildByName('FreeSpinBg'); this.left_1 = this.freeSpinBg.getChildByName('left_1'); this.left_2 = this.freeSpinBg.getChildByName('left_2'); this.leftCount = this.left_1.getChildByName('leftCount').getComponent(sp.Skeleton); this.autoBtnAni = this.autoBtn.getComponent(Animation); this.turboBtnAni = this.turboBtn.getComponent(Animation); this.btns2 = this.node.getChildByName('Btns2'); this.btns3 = this.node.getChildByName('Btns3'); // 保存初始位置 ['SpinNode', 'Btns1', 'Btns2', 'Btns3'].forEach(name => { const node = this.node.getChildByName(name); if (node) this.btnPositions.set(name, node.position.clone()); }); } protected onDestroy(): void { this.node.targetOff(this); } // spinBtn有两个动画,idle状态循环旋转一圈,spin状态速度加快 setGameInfo(gameInfo: any) { this.gameInfo = gameInfo; this.betGrade = gameInfo.BetGrade; this.curBalance = gameInfo.Balance; this.curBet = gameInfo.Data.Bet; this.curWin = gameInfo.Data.AllScore; // 非空处理 this.betIndex = this.betGrade.indexOf(this.curBet); if (this.betIndex == -1) { this.betIndex = 0; } this.setBalance(this.curBalance); this.setBet(this.curBet); this.setWin(this.curWin); } async openMenu() { if (this.isAnimating) return; AudioManager.instance.playSFX('Common_Button_Click'); this.isAnimating = true; const [spinBtn, btns1, btns2, btns3] = ['SpinNode', 'Btns1', 'Btns2', 'Btns3'] .map(name => this.node.getChildByName(name)); // 设置btns2,3初始位置 [btns2, btns3].forEach(btn => { btn.active = true; btn.position = v3(btn.position.x, btn.position.y + this.OFFSET_Y, 0); }); // 移出btns1和spinBtn await this.moveButtons([spinBtn, btns1], true); // 移入btns2和btns3 await this.moveButtons([btns2, btns3], false); this.isAnimating = false; } async closeMenu() { if (this.isAnimating) return; AudioManager.instance.playSFX('Common_Button_Click'); this.isAnimating = true; const [spinBtn, btns1, btns2, btns3] = ['SpinNode', 'Btns1', 'Btns2', 'Btns3'] .map(name => this.node.getChildByName(name)); // 移出btns2和btns3 await this.moveButtons([btns2, btns3], true); // 准备btns1和spinBtn [spinBtn, btns1].forEach(btn => { btn.active = true; btn.position = v3(btn.position.x, btn.position.y + this.OFFSET_Y, 0); }); // 移入btns1和spinBtn await this.moveButtons([spinBtn, btns1], false); this.isAnimating = false; } moveButtons(buttons: Node[], isOut: boolean): Promise { return new Promise(resolve => { const tweens = buttons.map(btn => { const targetPos = isOut ? v3(btn.position.x, btn.position.y + this.OFFSET_Y, 0) : this.btnPositions.get(btn.name); return tween(btn) .to(this.DURATION, { position: targetPos }, { easing: isOut ? 'cubicOut' : 'cubicOut' }) .call(() => { if (isOut) btn.active = false; }); }); tween(this.node) .parallel(...tweens) .call(() => resolve()) .start(); }); } protected update(dt: number): void { if (this.hasClickSpin) { this.thisRotateTime += dt } else { this.thisRotateTime = 0 } } onBtnSpin() { // 第一次点击 旋转 if (!this.hasClickSpin && !this.hasClickManualStop) { AudioManager.instance.playSFX('Spin_Button_Click'); this.hasClickSpin = true; this.manualStopNode.active = true this.node.emit(SLOT_BAR_EVENT.ON_SPIN_CLICK); this.spinAni.startSpin(this.isFastSpin); this.setBtnEnable(this.subBtn, false); this.setBtnEnable(this.addBtn, false); this.setBtnEnable(this.autoBtn, false); this.setBtnEnable(this.menuBtn, false); } // 第二次点击 手动停止 else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime < 0.5) { this.scheduleOnce(() => { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); }, 0.3) } else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime >= 0.5) { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); } } featureBuySpin() { // 第一次点击 旋转 if (!this.hasClickSpin && !this.hasClickManualStop) { // AudioManager.instance.playSFX('Spin_Button_Click'); this.hasClickSpin = true; this.manualStopNode.active = true this.setBtnEnable(this.subBtn, false); this.setBtnEnable(this.addBtn, false); this.setBtnEnable(this.autoBtn, false); this.setBtnEnable(this.menuBtn, false); } // 第二次点击 手动停止 else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime < 0.8) { this.scheduleOnce(() => { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); }, 0.5) } else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime >= 0.8) { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); } } onBtnTestSpin(event, args) { // 第一次点击 旋转 if (!this.hasClickSpin && !this.hasClickManualStop) { this.hasClickSpin = true; this.node.emit(SLOT_BAR_EVENT.ON_TEST_SPIN_CLICK, args); this.setBtnEnable(this.subBtn, false); this.setBtnEnable(this.addBtn, false); this.setBtnEnable(this.autoBtn, false); this.setBtnEnable(this.menuBtn, false); } // 第二次点击 手动停止 else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime < 0.8) { this.scheduleOnce(() => { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); }, 0.5) } else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime >= 0.8) { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); } } onBtnManualStop() { if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime < 0.8) { this.scheduleOnce(() => { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); }, 0.5) } else if (this.hasClickSpin && !this.hasClickManualStop && this.thisRotateTime >= 0.8) { this.node.emit(SLOT_BAR_EVENT.ON_MANUAL_STOP); } } manualStop() { this.hasClickManualStop = true; this.spinAniStop() this.setBtnEnable(this.spinBtn, false); } // 打开规则界面 openRules() { if (!this.tweenIsEnd) return; // let url = getSupportUrl(); // window.open(url, '_blank'); // return; AudioManager.instance.playSFX('Common_Button_Click'); let param = "rule"; let view = NodePoolManager.instance.getNodeFromPoolStatic(param, this.webViewPre); this.MaskNode.addChild(view); view.getComponent(webView).open(param, this.curBet); } // 打开赔率界面 openPaytable() { if (!this.tweenIsEnd) return; // let url = getOddsUrl(); // window.open(url, '_blank'); // return; AudioManager.instance.playSFX('Common_Button_Click'); let param = "paytable"; let view = NodePoolManager.instance.getNodeFromPoolStatic(param, this.webViewPre); this.MaskNode.addChild(view); view.getComponent(webView).open(param, this.curBet); } openHistory() { if (!this.tweenIsEnd) return; // let url = getHistoryUrl(); // window.open(url, '_blank'); // return; AudioManager.instance.playSFX('Common_Button_Click'); let param = "history"; let viewNode = NodePoolManager.instance.getNodeFromPoolStatic(param, this.webViewPre); viewNode.setPosition(v3(0, -view.getVisibleSize().height, 0)); this.MaskNode.addChild(viewNode); viewNode.getComponent(webView).open(param, this.curBet); } isON = true; onBtnSound() { AudioManager.instance.playSFX('Common_Button_Click'); let btns2 = this.node.getChildByName('Btns2'); let sound = btns2.getChildByName('ic_sound'); let on = sound.getChildByName('on'); let off = sound.getChildByName('off'); this.isON = !this.isON; on.active = this.isON; off.active = !this.isON; AudioManager.instance.setMute(off.active); } onBtnAddChips() { AudioManager.instance.playSFX('Common_Button_Click'); this.betIndex += 1; this.setBtnEnable(this.addBtn, this.betIndex != this.betGrade.length); this.setBtnEnable(this.subBtn, this.betIndex > 0); if (this.betIndex == this.betGrade.length) { let tip = I18nManager.instance.t('AID_TIP_MAX_BET'); this.showTipSmall(tip); // 显示提示 this.betIndex = this.betGrade.length - 1; // 确保 betIndex 不超出范围 return; } this.setBet(this.betGrade[this.betIndex]); } onBtnSubChips() { AudioManager.instance.playSFX('Common_Button_Click'); this.betIndex -= 1; this.setBtnEnable(this.subBtn, this.betIndex > 0); this.setBtnEnable(this.addBtn, this.betIndex != this.betGrade.length); if (this.betIndex < 0) { let tip = I18nManager.instance.t('AID_TIP_MIN_BET'); this.showTipSmall(tip); // 显示提示 this.betIndex = 0; // 确保 betIndex 不低于0 return; } this.setBet(this.betGrade[this.betIndex]); } private currentTipTween: Tween = null; private hideTimer: number = null; showTipSmall(str: string) { // 清理之前的计时器和动画 this.clearTipTimers(); // 设置提示内容 this.tipSmall.getChildByName('Label').getComponent(Label).string = str; let label = this.tipSmall.getChildByName('Label').getComponent(Label); label.updateRenderData(true); let tipWidth = this.tipSmall.getChildByName('Label').getComponent(UITransform).width; let frame = this.tipSmall.getChildByName('Frame_Assets'); frame.getComponent(UITransform).setContentSize(tipWidth + 100, 105); // 调整框架大小 setTimeout(() => { this.tipSmall.active = true; // 显示动画 this.tipSmall.scale = new Vec3(0, 0, 0); this.currentTipTween = tween(this.tipSmall) .to(0.1, { scale: new Vec3(1, 1, 1) }) .call(() => { // 5. 设置隐藏计时器 this.hideTimer = setTimeout(() => { this.hideTipSmall(); }, 1000); // 1秒后隐藏 }) .start(); }, 0.1); } private hideTipSmall() { if (!this.tipSmall.active) return; this.clearTipTimers(); // 清理可能存在的计时器 this.currentTipTween = tween(this.tipSmall) .to(0.1, { scale: new Vec3(0, 0, 0) }) .call(() => { this.tipSmall.active = false; this.currentTipTween = null; }) .start(); } private clearTipTimers() { // 停止当前的 tween if (this.currentTipTween) { this.currentTipTween.stop(); this.currentTipTween = null; } // 取消隐藏计时器 if (this.hideTimer !== null) { clearTimeout(this.hideTimer); this.hideTimer = null; } // 取消所有可能的计时器(以防万一) this.unscheduleAllCallbacks(); } private _balance: number = 0; setBalance(score: number) { if (score < 0) return; this._balance = score; this.balanceLabel.string = gold2cash(score); } getBalance(): number { return this._balance; } setBet(bet: number, isSysGift: boolean = false) { this.node.emit(SLOT_BAR_EVENT.BET_CHANGE, bet); this.betLabel.string = gold2cash(bet); if (isSysGift) { this.betIndex = -1; } else { this.betIndex = this.betGrade.indexOf(bet); } // 停止当前的 tween 动画 Tween.stopAllByTarget(this.betLabel.node); // 重置缩放 this.betLabel.node.scale = new Vec3(1, 1, 1); // 0.1秒内放大缩小动画 tween(this.betLabel.node) .to(0.15, { scale: new Vec3(1.2, 1.2, 1) }) // 0.05秒内放大 .to(0.015, { scale: new Vec3(1, 1, 1) }) // 0.05秒内缩小回原始大小 .start(); } getBet() { if (this.betIndex == -1) { return +this.betLabel.string * 10000; } return this.betGrade[this.betIndex]; } setWin(win: number) { this.winLabel.string = gold2cash(win); } onAutoMouseDown() { this.unscheduleAllCallbacks(); this.autoBtnAni.stop(); AudioManager.instance.playSFX('Common_Button_Click'); if (this.isAuto) { this.closeAutoSpin(); } else { let panel = NodePoolManager.instance.getNodeFromPoolStatic('AutoSpinPanel', this.autoSpinPanel); panel.getComponent(AutoSpinPanel).setCloseCallback(() => { this.startAutoSpin(); }); this.node.addChild(panel); panel.getComponent(AutoSpinPanel).showTween(); } } setLeftAutoCount(count: number) { this.leftAutoCount.string = count.toString(); } startAutoSpin() { this.isAuto = true; this.autoBtnAni.play('autoSpin_Pressed_animation'); this.scheduleOnce(() => { this.autoBtnAni.play('autoSpin_Enable_animation'); }, 0.4) this.setBtnEnable(this.subBtn, false); this.setBtnEnable(this.addBtn, false); this.setBtnEnable(this.autoBtn, false); this.setBtnEnable(this.menuBtn, false); this.setBtnEnable(this.spinBtn, false); this.setBtnVisible(this.spinBtn, false); this.setBtnVisible(this.stopAutoBtn, true); this.setLeftAutoCount(GameDataManager.instance.autoCount); this.node.emit(SLOT_BAR_EVENT.ON_AUTO_SPIN_CLICK, this.isAuto); } closeAutoSpin() { this.isAuto = false; this.autoBtnAni.stop(); this.autoBtnAni.play('autoSpin_Pressed_animation'); this.scheduleOnce(() => { this.autoBtnAni.play('autoSpin_Normal_animation'); }, 0.4) AudioManager.instance.playSFX('Common_Button_Click'); this.node.emit(SLOT_BAR_EVENT.ON_AUTO_SPIN_CLICK, this.isAuto); this.setBtnVisible(this.spinBtn, true); this.setBtnVisible(this.stopAutoBtn, false); this.setBtnEnable(this.spinBtn, false); } reconnectState(hasDelete: boolean = false) { if (hasDelete) { this.setBtnEnable(this.subBtn, false); this.setBtnEnable(this.addBtn, false); this.setBtnEnable(this.autoBtn, false); this.setBtnEnable(this.menuBtn, false); this.setBtnEnable(this.spinBtn, false); } } resetAllState() { this.hasClickSpin = false; this.hasClickManualStop = false; this.thisRotateTime = 0 this.manualStopNode.active = false this.isAuto = false; this.setBtnVisible(this.spinBtn, true); this.setBtnVisible(this.stopAutoBtn, false); this.setBtnEnable(this.spinBtn, true); this.setBtnEnable(this.subBtn, true); this.setBtnEnable(this.addBtn, true); this.setBtnEnable(this.menuBtn, true); this.setBtnEnable(this.autoBtn, true); } spinAniStop() { this.spinAni.stopSpin(); } onTurboMouseDown() { this.unscheduleAllCallbacks(); this.turboBtnAni.stop(); AudioManager.instance.playSFX('Common_Button_Click'); if (this.isFastSpin) { this.isFastSpin = false; this.turboBtnAni.play('turbo_Pressed_animation'); setTimeout(() => { this.turboBtnAni.play('turbo_Normal_animation'); }, 400); } else { this.isFastSpin = true; this.turboBtnAni.play('turbo_Pressed_animation'); // 修改为timeout setTimeout(() => { this.turboBtnAni.play('turbo_Enable_animation'); }, 400); } this.node.emit(SLOT_BAR_EVENT.FAST_SPIN, this.isFastSpin); } onBtnExit() { this.node.emit(SLOT_BAR_EVENT.ON_EXIT_CLICK); AudioManager.instance.playSFX('Common_Button_Click'); } //111 SPIN_ACTIVE = true; BTNS1_ACTIVE = true; BTNS2_ACTIVE = false; BTNS3_ACTIVE = false; enterFreeSpin(leftCount: number) { this.freeSpinBg.active = true; this.Msg.setPosition(0, -910, 0) this.BTNS1_ACTIVE = this.btns1.active; this.BTNS2_ACTIVE = this.btns2.active; this.BTNS3_ACTIVE = this.btns3.active; this.SPIN_ACTIVE = this.spinNode.active; this.btns1.active = false; this.btns2.active = false; this.btns3.active = false; this.spinNode.active = false; this.showLeftCount(leftCount); } showLeftCount(leftCount: number) { if (leftCount >= 1) { let rfs = this.left_1.getChildByName('rfs'); let leftCount_1 = this.leftCount.node.getChildByName('leftCount_1').getComponent(sp.Skeleton) rfs.getComponent(LocalizedSprite).updateSprite(); this.left_1.getComponent(Layout).updateLayout(); this.left_1.active = true; if (leftCount >= 10) { let num1 = leftCount / 10 let num2 = leftCount % 10 leftCount_1.node.active = true leftCount_1.clearTracks() this.leftCount.clearTracks() this.leftCount.setAnimation(0, `anim_${num1}`, true) leftCount_1.setAnimation(0, `anim_${num2}`, true) } else { leftCount_1.node.active = false this.leftCount.clearTracks() this.leftCount.setAnimation(0, `anim_${leftCount}`, true) } this.left_2.active = false; } else { this.left_1.active = false; let rfs = this.left_2.getChildByName('rfs'); rfs.getComponent(LocalizedSprite).updateSprite(); this.left_2.active = true; } } exitFreeSpin() { this.freeSpinBg.active = false; this.Msg.setPosition(0, -600, 0) this.btns1.active = this.BTNS1_ACTIVE; this.btns2.active = this.BTNS2_ACTIVE; this.btns3.active = this.BTNS3_ACTIVE; this.spinNode.active = this.SPIN_ACTIVE; } // 设置按钮可以点击并且置灰的函数 setBtnEnable(btn: Button | Node, enable: boolean) { if (btn instanceof Button) { btn.interactable = enable; this.setNodeOpacity(btn.node, enable ? 255 : 128); } else { btn.getComponent(Button).interactable = enable; this.setNodeOpacity(btn, enable ? 255 : 128); } } setGraySpinBtn(show: boolean) { this.spinBtn.node.active = !show this.grayBtn.active = show } setNodeOpacity(node: Node, opacity: number) { node.getComponent(UIOpacity).opacity = opacity; } // 设置按钮显示隐藏 setBtnVisible(btn: Button, visible: boolean) { btn.node.active = visible; } systemGiftContinue() { this.setBtnEnable(this.subBtn, false); this.setBtnEnable(this.addBtn, false); this.setBtnEnable(this.autoBtn, false); this.setBtnEnable(this.menuBtn, false); } systemGiftConfirm() { this.setBtnEnable(this.subBtn, true); this.setBtnEnable(this.addBtn, true); this.setBtnEnable(this.autoBtn, true); this.setBtnEnable(this.menuBtn, true); this.betIndex = 0; this.setBet(this.betGrade[this.betIndex]); } setSysGiftBet(bet) { let found = false; this.betGrade.forEach((v, i) => { if (v == bet) { this.betIndex = i; found = true; } }) if (!found) { this.setBet(bet, true); } else { this.setBet(this.betGrade[this.betIndex], true); } } }