cb/assets/shop/script/passCheckMgr.ts
2025-11-11 17:57:47 +08:00

340 lines
12 KiB
TypeScript
Raw 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 scrollViewList from "../../Script/module/List/scrollviewList";
import Utils from "../../Script/module/Pay/Utils";
import PassCheckItem from "./passCheckItem";
const { ccclass, property } = cc._decorator;
@ccclass
export default class passCheckMgr extends cc.Component {
private list: scrollViewList = null;
private passCheckItem: PassCheckItem = null;
listData: any[] = [];
private progressLevel: number = 0;
private progressBar3: cc.Node = null;
private progressBar4: cc.Node = null;
private ProgressIndex: number = 0;
private passCheckInfo: any[] = [];
private endTime: any;
private rewardUpdateTimeout: any = null;
private lastUpdateTime: number = 0;
private readonly UPDATE_DELAY: number = 200;
private isRewardTime: number = 0;
// private isLeftReward: boolean = false;
onLoad() {
cc.systemEvent.on('passcheck-reward-claimed', this.updateRewardStatus, this);
}
start() {
}
init(data: any[], progressLevel: number, oldPassCheckInfo: any[], time: any) {
// 确保组件已经被正确加载
if (!this.node) {
console.error("passCheckMgr: node is null");
return;
}
this.endTime = time;
this.passCheckInfo = oldPassCheckInfo;
// 设置当前进度等级
if (progressLevel !== undefined) {
this.progressLevel = progressLevel;
}
// 获取ScrollView组件使用不区分大小写的查找
let scrollViewNode: cc.Node | null = null;
const children = this.node.children;
for (let i = 0; i < children.length; i++) {
const child = children[i];
if (child.name.toLowerCase() === "scrollview") {
scrollViewNode = child;
break;
}
}
if (!scrollViewNode) {
console.error("passCheckMgr: Cannot find ScrollView node under this.node");
return;
}
// 尝试获取scrollViewList组件如果没有则自动添加
this.list = scrollViewNode.getComponent(scrollViewList);
if (!this.list) {
this.list = scrollViewNode.addComponent(scrollViewList);
}
// 手动调用初始化,因为组件可能是在运行时添加的
this.list["init"]();
// 设置数据
this.listData = data;
this.list.setData(data);
// 创建进度条
this.setupProgressBars(scrollViewNode);
// 刷新list数据
// this.updateListItem(data);
}
private setupProgressBars(scrollViewNode: cc.Node) {
const content = scrollViewNode.getComponent(cc.ScrollView).content;
// 获取进度条节点
this.progressBar3 = this.node.getChildByName("scrollView").getChildByName("progress_bar_3");
this.progressBar4 = this.node.getChildByName("scrollView").getChildByName("progress_bar_4");
// 确保进度条节点存在
if (!this.progressBar3 || !this.progressBar4) {
console.error("passCheckMgr: Progress bar nodes not found");
return;
}
// 确保进度条有Sprite组件
let sprite3 = this.progressBar3.getComponent(cc.Sprite);
if (!sprite3) {
sprite3 = this.progressBar3.addComponent(cc.Sprite);
}
let sprite4 = this.progressBar4.getComponent(cc.Sprite);
if (!sprite4) {
sprite4 = this.progressBar4.addComponent(cc.Sprite);
}
// 设置进度条父节点为content
this.progressBar3.parent = content;
this.progressBar4.parent = content;
// 设置进度条属性
this.progressBar3.width = 32;
this.progressBar3.anchorX = 0.5;
this.progressBar3.anchorY = 0.5;
this.progressBar3.zIndex = 1; // 确保进度条在背景层
this.progressBar4.width = 32;
this.progressBar4.anchorX = 0.5;
this.progressBar4.anchorY = 0.5;
this.progressBar4.zIndex = 1; // 确保进度条在背景层
// 激活进度条
this.progressBar3.active = true;
this.progressBar4.active = true;
// 更新进度条显示
this.updateProgressBars();
}
// ... existing code ...
private updateProgressBars() {
// 确保进度条已创建
if (!this.progressBar3 || !this.progressBar4) {
console.log("passCheckMgr: Progress bars not created yet");
return;
}
// 确保有足够的数据来计算进度条位置
if (this.listData.length === 0) {
console.warn("passCheckMgr: No data to calculate progress bar positions");
return;
}
// 获取scrollViewList组件的配置
const itemHeight = this.list.itemHeight > 0 ? this.list.itemHeight : this.list["itemHeightActual"];
const spacingY = this.list.spacingY;
const paddingTop = this.list.paddingTop;
const paddingBottom = this.list.paddingBottom;
// 计算第一个item的中心Y位置
const firstItemCenterY = -paddingTop - itemHeight / 2;
// 计算最后一个item的中心Y位置
const lastIndex = this.listData.length - 1;
const lastItemCenterY = -paddingTop - itemHeight / 2 - lastIndex * (itemHeight + spacingY);
// 计算总长度
const totalLength = Math.abs(firstItemCenterY - lastItemCenterY);
const centerX = this.progressBar3.parent.width / 2;
// 设置总长度进度条 (progress_bar_3)
this.progressBar3.height = totalLength;
this.progressBar3.setAnchorPoint(0.5, 1);
this.progressBar3.setPosition(centerX, firstItemCenterY);
// 获取已保存的进度索引
this.ProgressIndex = cc.fx.StorageMessage.getStorage("ProgressIndex") || 0;
if (this.ProgressIndex > this.progressLevel) {
this.ProgressIndex = this.progressLevel;
}
const adjustedProgressIndex = Math.max(0, this.progressLevel - 1);
const adjustedStoredIndex = Math.max(0, this.ProgressIndex - 1);
// 计算进度位置
const progressIndex1 = Math.min(adjustedStoredIndex, this.listData.length - 1);
const progressIndex2 = Math.min(adjustedProgressIndex, this.listData.length - 1);
// 计算对应位置的Y坐标
const progressItemCenterY1 = -paddingTop - itemHeight / 2 - progressIndex1 * (itemHeight + spacingY);
const progressItemCenterY2 = -paddingTop - itemHeight / 2 - progressIndex2 * (itemHeight + spacingY);
// 计算进度条高度
const progressLength1 = Math.abs(firstItemCenterY - progressItemCenterY1);
const progressLength2 = Math.abs(firstItemCenterY - progressItemCenterY2);
this.progressBar4.setAnchorPoint(0.5, 1);
this.progressBar4.setPosition(centerX, firstItemCenterY);
this.progressBar4.height = progressLength1;
let growthLength = progressLength2 - progressLength1;
const targetHeight = progressLength1 + growthLength;
if (growthLength > 0) {
cc.tween(this.progressBar4)
.delay(0.5)
.to(1, { height: targetHeight })
.call(() => {
this.progressBar4.height = progressLength2;
})
.start();
} else if (growthLength < 0) {
// 如果是倒退的情况(虽然不太可能)
this.progressBar4.height = progressLength2;
} else if (growthLength === 0 && progressLength2 === 0) {
// 特殊情况当进度为1级时进度条应该为0
this.progressBar4.height = 0;
}
cc.fx.StorageMessage.setStorage("ProgressIndex", this.progressLevel);
}
public updatePassCheckStatus(itemIndex?: number, isLeftReward?: boolean) {
// 如果提供了itemIndex和isLeftReward则更新对应的奖励状态
if (itemIndex !== undefined && isLeftReward !== undefined) {
// 更新本地数据状态
if (this.listData[itemIndex]) {
if (isLeftReward) {
this.listData[itemIndex].free = 0; // 标记为已领取
} else {
this.listData[itemIndex].passCheck = 0; // 标记为已领取
}
}
}
// 构造要发送到服务器的数据
let now = this.endTime;
let passCheck = null;
if (cc.fx.GameConfig.GM_INFO.getItemType == 2) {
passCheck = {
[1]: this.passCheckInfo,
[2]: {
time: now.toString(),
progress: cc.fx.GameConfig.GM_INFO.getProgress,
progressLevel: cc.fx.GameConfig.GM_INFO.getProgressLevel,
activate: cc.fx.GameConfig.GM_INFO.passCheckActivate, // activateValue,
free: this.listData.map(item => item.free),
passCheck: this.listData.map(item => item.passCheck),
}
};
} else {
passCheck = {
[1]: {
time: now.toString(),
progress: cc.fx.GameConfig.GM_INFO.getProgress,
progressLevel: cc.fx.GameConfig.GM_INFO.getProgressLevel,
activate: cc.fx.GameConfig.GM_INFO.passCheckActivate, // activateValue,
free: this.listData.map(item => item.free),
passCheck: this.listData.map(item => item.passCheck),
},
[2]: this.passCheckInfo,
}
}
// 发送到服务器
Utils.setPassCheckInfo((res) => {
if (res.code === 1) {
console.log("通行证状态保存成功");
// this.refreshPassCheckItems();
} else {
console.log("通行证状态保存失败");
}
}, passCheck);
}
public refreshPassCheckItems() {
this.updatePassCheckStatus();
// 通知所有 passCheckItem 组件更新界面
if (this.list && this.list.node) {
// 通过ScrollView组件获取content节点
const scrollViewComponent = this.list.node.getComponent(cc.ScrollView);
if (scrollViewComponent && scrollViewComponent.content) {
const content = scrollViewComponent.content;
// 遍历所有子节点,查找 passCheckItem 组件并刷新
for (let i = 0; i < content.childrenCount; i++) {
const child = content.children[i];
// 查找 passCheckItem 节点(通常是间接子节点)
if (child.name === "passCheckItem") {
const passCheckItem = child.getComponent("passCheckItem");
if (passCheckItem) {
passCheckItem.dataChanged();
}
// }
}
}
}
}
}
public updateRewardStatus(itemIndex: number, isLeftReward: boolean) {
// this.updatePassCheckStatus(itemIndex, isLeftReward);
const currentTime = Date.now();
// 防止短时间内重复触发
if (currentTime - this.lastUpdateTime < this.UPDATE_DELAY) {
console.log("阻止短时间内重复更新:", currentTime - this.lastUpdateTime, "ms");
return;
}
this.isRewardTime = currentTime;
// 更新最后调用时间
this.lastUpdateTime = currentTime;
// 使用防抖机制,延迟处理奖励更新
if (this.rewardUpdateTimeout) {
clearTimeout(this.rewardUpdateTimeout);
}
this.rewardUpdateTimeout = setTimeout(() => {
this.updatePassCheckStatus(itemIndex, isLeftReward);
this.rewardUpdateTimeout = null;
}, 50);
}
public updateActivateStatus() {
this.updatePassCheckStatus();
}
protected onDestroy(): void {
console.log("销毁passCheckMgr");
cc.systemEvent.off('passcheck-reward-claimed', this.updateRewardStatus, this);
// 清理可能存在的列表数据
if (this.listData) {
this.listData = null;
}
// 如果列表组件存在,尝试清理它
if (this.list && cc.isValid(this.list.node)) {
try {
// 先清理数据
if (this.list.setData) {
this.list.setData([]);
}
} catch (e) {
console.warn("清理列表数据时出错:", e);
}
}
this.list = null;
this.passCheckItem = null;
}
}