import { _decorator, Button, Color, Component, EventTouch, Node, sp, Sprite, tween, UITransform, v3, Vec3 } from 'cc'; import { RankList } from './RankList'; import { RankHistoryList } from './RankHistoryList'; import { RewardList } from './RewardList'; import { RewardHistoryList } from './RewardHistoryList'; import { SlotRankingDataManager } from './SlotRankingDataManager'; import { callGameApiForRank, getGameId } from 'db://assets/Loading/scripts/comm'; import { AudioManager } from 'db://assets/Loading/scripts/manager/AudioManager'; const { ccclass, property } = _decorator; @ccclass('SlotRanking') export class SlotRanking extends Component { // ==================== 排行榜入口 ==================== rankingBtn: Node = null; // 排行榜入口按钮 // ==================== 主弹窗节点 ==================== rankingRewardNode: Node = null; // 排行榜弹窗主节点 @property(RankList) rankList: RankList = null; @property(RankHistoryList) rankHistoryList: RankHistoryList = null; @property(RewardList) rewardList: RewardList = null; @property(RewardHistoryList) rewardHistoryList: RewardHistoryList = null; // 设计分辨率 DESIGN_WIDTH: number = 1080; DESIGN_HEIGHT: number = 1920; slotScene: any = null; // SlotScene 引用 isMove: boolean = false; // 是否是拖动状态 isClick: boolean = false; // 是否是点击状态 startPos: Vec3 = v3(432, 650, 0); touchStartPos: Vec3 = v3(0, 0, 0); // 触摸开始位置(世界坐标) nodeStartPos: Vec3 = v3(0, 0, 0); // 节点开始位置 uiTransform: UITransform = null; // 节点UI变换组件 parentUITransform: UITransform = null; // 父节点UI变换组件 async onLoad() { this.rankingBtn = this.node.getChildByName("rankingBtn"); this.rankingRewardNode = this.node.getChildByName("rankingRewardNode"); this.rankingBtn.active = false; this.rankingRewardNode.active = false; try { let rankList = await callGameApiForRank("ranklist", { GameId: getGameId() }); if (!rankList || !rankList.List || rankList.List.length === 0) { return; } SlotRankingDataManager.instance.rankList = rankList; } catch (error) { return; } this.rankingBtn = this.node.getChildByName("rankingBtn"); this.rankingRewardNode = this.node.getChildByName("rankingRewardNode"); this.uiTransform = this.rankingBtn.getComponent(UITransform); this.parentUITransform = this.rankingBtn.parent.getComponent(UITransform); this.initComponents(); this.rankingBtn.setPosition(this.startPos); this.rankingBtn.active = SlotRankingDataManager.instance.getRankListStatus() === 0 || SlotRankingDataManager.instance.getRankListStatus() === 1; this.rankingBtn.getChildByName('icon').getComponent(sp.Skeleton).color = SlotRankingDataManager.instance.getRankListStatus() === 0 ? Color.WHITE : Color.GRAY; this.rankingBtn.getComponent(Button).interactable = SlotRankingDataManager.instance.getRankListStatus() === 0; this.rankingBtn.on(Node.EventType.TOUCH_START, this.onTouchStart, this); this.rankingBtn.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.rankingBtn.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this); this.rankingBtn.on(Node.EventType.TOUCH_END, this.onTouchEnd, this); this.rankingRewardNode.active = false; } initComponents() { this.rankList.init(this.rankingRewardNode.getChildByName('rankList')); this.rankList.onShowHistory = (type: string) => { this.showRankHistoryList(type); }; this.rankList.onShowReward = (type: string) => { this.showRewardListFromRank(type); }; this.rankList.onClose = () => { this.closeRankingPopup(); }; this.rankHistoryList.init(this.rankingRewardNode.getChildByName('rankHistoryList')); this.rankHistoryList.onBack = () => { this.showRankList(); }; this.rewardList.init(this.rankingRewardNode.getChildByName('rewardList')); this.rewardList.onShowRank = (type: string) => { this.showRankListFromReward(type); }; this.rewardList.onShowHistory = () => { this.showRewardHistoryList(); }; this.rewardHistoryList.onBack = () => { this.showRewardList(); }; this.rewardHistoryList.init(this.rankingRewardNode.getChildByName('rewardHistoryList')); this.rewardList.onClose = () => { this.closeRankingPopup(); }; } setSlotScene(slotScene: any) { this.slotScene = slotScene; // 将 slotScene 引用传递给 RewardList if (this.rewardList) { this.rewardList.setSlotScene(slotScene); } } // 检查是否可以点击排行榜按钮 canClickRankingBtn(): boolean { if (!this.slotScene) return true; // 如果正在滚动,不可点击 if (this.slotScene.slotGame && this.slotScene.slotGame.isScroll()) { return false; } // 如果正在自动旋转,不可点击 if (this.slotScene.gameState.isAutoSpin) { return false; } if (this.slotScene.gameState.isInFreeSpin) { return false; } if (this.slotScene.gameState.isEliminating) { return false; } return true; } // ==================== 触摸事件处理 ==================== onTouchStart(event: EventTouch) { this.isMove = false; this.isClick = true; let touchPos = event.getUILocation(); if (this.parentUITransform) { let localPos = this.parentUITransform.convertToNodeSpaceAR(v3(touchPos.x, touchPos.y, 0)); this.touchStartPos.set(localPos); } else { this.touchStartPos.set(v3(touchPos.x, touchPos.y, 0)); } this.nodeStartPos.set(this.rankingBtn.position); } onTouchMove(event: EventTouch) { if (!this.isClick) return; this.isMove = true; let touchPos = event.getUILocation(); let currentTouchPos; if (this.parentUITransform) { currentTouchPos = this.parentUITransform.convertToNodeSpaceAR(v3(touchPos.x, touchPos.y, 0)); } else { currentTouchPos = v3(touchPos.x, touchPos.y, 0); } let deltaX = currentTouchPos.x - this.touchStartPos.x; let deltaY = currentTouchPos.y - this.touchStartPos.y; let newX = this.nodeStartPos.x + deltaX; let newY = this.nodeStartPos.y + deltaY; let clampedPos = this.clampPosition(newX, newY); this.rankingBtn.setPosition(v3(clampedPos.x, clampedPos.y, 0)); } onTouchCancel(event: EventTouch) { if (this.isClick && !this.isMove) return; if (this.isMove) { this.snapToEdge(); } this.isMove = false; this.isClick = false; } onTouchEnd(event: EventTouch) { if (this.isMove) { this.snapToEdge(); this.isMove = false; this.isClick = false; return; } if (this.isClick) { // 检查是否可以点击 if (!this.canClickRankingBtn()) { this.isMove = false; this.isClick = false; return; } this.handleClickEvent(); } this.isMove = false; this.isClick = false; } clampPosition(newX: number, newY: number): { x: number, y: number } { if (this.uiTransform) { let nodeWidth = this.uiTransform.width; let nodeHeight = this.uiTransform.height; let anchorX = this.uiTransform.anchorX; let anchorY = this.uiTransform.anchorY; let leftBound = -this.DESIGN_WIDTH / 2 + nodeWidth * anchorX; let rightBound = this.DESIGN_WIDTH / 2 - nodeWidth * (1 - anchorX); let bottomBound = -this.DESIGN_HEIGHT / 2 + nodeHeight * anchorY; let topBound = this.DESIGN_HEIGHT / 2 - nodeHeight * (1 - anchorY); newX = Math.max(leftBound, Math.min(rightBound, newX)); newY = Math.max(bottomBound, Math.min(topBound, newY)); } else { let halfWidth = this.DESIGN_WIDTH / 2; let halfHeight = this.DESIGN_HEIGHT / 2; newX = Math.max(-halfWidth, Math.min(halfWidth, newX)); newY = Math.max(-halfHeight, Math.min(halfHeight, newY)); } return { x: newX, y: newY }; } snapToEdge() { let currentPos = this.rankingBtn.position; let screenCenterX = 0; let targetX: number; if (this.uiTransform) { let nodeWidth = this.uiTransform.width; let anchorX = this.uiTransform.anchorX; if (currentPos.x > screenCenterX) { targetX = this.DESIGN_WIDTH / 2 - nodeWidth * (1 - anchorX); } else { targetX = -this.DESIGN_WIDTH / 2 + nodeWidth * anchorX; } } else { let edgeMargin = 20; if (currentPos.x > screenCenterX) { targetX = this.DESIGN_WIDTH / 2 - edgeMargin; } else { targetX = -this.DESIGN_WIDTH / 2 + edgeMargin; } } tween(this.rankingBtn) .to(0.05, { position: v3(targetX, currentPos.y, 0) }) .start(); } // ==================== 主弹窗控制 ==================== async handleClickEvent() { AudioManager.instance.playSFX("Common_Button_Click"); this.rankingRewardNode.active = true; await this.showRankList('day'); } async showRankList(defaultType: string = 'day') { this.rankHistoryList.hide(); this.rewardList.hide(); this.rewardHistoryList.hide(); await this.rankList.show(defaultType); } showRankHistoryList(type: string) { this.rankList.hide(); this.rewardList.hide(); this.rewardHistoryList.hide(); this.rankHistoryList.show(type); } async showRankListFromReward(rewardType: string) { this.rewardList.hide(); this.rankHistoryList.hide(); this.rewardHistoryList.hide(); await this.rankList.show(rewardType); } showRewardHistoryList() { this.rankList.hide(); this.rankHistoryList.hide(); this.rewardList.hide(); this.rewardHistoryList.show(); } async showRewardList(defaultType: string = 'day') { this.rankList.hide(); this.rankHistoryList.hide(); this.rewardHistoryList.hide(); await this.rewardList.show(defaultType); } async showRewardListFromRank(rankType: string) { this.rankList.hide(); this.rankHistoryList.hide(); this.rewardHistoryList.hide(); await this.rewardList.show(rankType); } closeRankingPopup() { this.rankingRewardNode.active = false; this.rankList.hide(); this.rankHistoryList.hide(); this.rewardList.hide(); this.rewardHistoryList.hide(); } setStartPosition(pos: Vec3) { this.startPos.set(pos); this.rankingBtn.setPosition(pos); } onDestroy() { this.rankingBtn.off(Node.EventType.TOUCH_START, this.onTouchStart, this); this.rankingBtn.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.rankingBtn.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this); this.rankingBtn.off(Node.EventType.TOUCH_END, this.onTouchEnd, this); } }