All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m14s
364 lines
12 KiB
TypeScript
364 lines
12 KiB
TypeScript
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';
|
|
import { SlotScene } from '../../scripts/SlotScene';
|
|
|
|
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: SlotScene = 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 || SlotRankingDataManager.instance.getRankMaxCloseTimeIsBiggerThanCurTime();
|
|
|
|
this.rankingBtn.getComponent(Button).interactable = SlotRankingDataManager.instance.getRankListStatus() === 0;
|
|
this.rankingBtn.getChildByName('icon').getComponent(sp.Skeleton).color = SlotRankingDataManager.instance.getRankListStatus() === 0 ? Color.WHITE : Color.GRAY;
|
|
|
|
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: SlotScene) {
|
|
this.slotScene = slotScene;
|
|
// 将 slotScene 引用传递给 RewardList
|
|
if (this.rewardList) {
|
|
this.rewardList.setSlotScene(slotScene);
|
|
}
|
|
}
|
|
|
|
// 检查是否可以点击排行榜按钮
|
|
canClickRankingBtn(): boolean {
|
|
console.log('slotScene', this.slotScene)
|
|
|
|
if (!this.slotScene) return true;
|
|
console.log('isAutoSpin', this.slotScene.gameState.isAutoSpin)
|
|
console.log('isInFreeSpin', this.slotScene.gameState.isInFreeSpin)
|
|
console.log('isFeatureBuySpin', this.slotScene.gameState.isFeatureBuySpin)
|
|
console.log('isEliminating', this.slotScene.gameState.isEliminating)
|
|
// 如果正在滚动,不可点击
|
|
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.isFeatureBuySpin) {
|
|
return false;
|
|
}
|
|
|
|
if (this.slotScene.gameState.isEliminating) {
|
|
return false;
|
|
}
|
|
|
|
if (!this.rankingBtn.getComponent(Button).interactable) {
|
|
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;
|
|
}
|
|
console.log('isClick', this.isClick)
|
|
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);
|
|
}
|
|
}
|