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; onLoad() { } 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; console.log("列表数据", 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(updates?: Array<{ itemIndex: number, isLeftReward: boolean }>) { // 如果提供了updates数组,则批量更新对应的奖励状态 if (updates && Array.isArray(updates) && updates.length > 0) { // 批量更新本地数据状态 for (const update of updates) { const { itemIndex, isLeftReward } = update; if (this.listData[itemIndex]) { if (isLeftReward) { this.listData[itemIndex].free = 0; // 标记为已领取 } else { this.listData[itemIndex].passCheck = 0; // 标记为已领取 } } } } console.log("给服务器发的值", updates); // 构造要发送到服务器的数据 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("通行证状态保存成功"); console.log("服务器返回的成功响应:", res); this.checkAllRewardsClaimed(); // this.refreshPassCheckItems(); } else { console.log("通行证状态保存失败"); } }, passCheck); } // 检查所有奖励是否领取完毕 private checkAllRewardsClaimed() { let allClaimed = true; for (let i = 0; i < this.listData.length; i++) { // 检查免费奖励是否已领取 (0表示已领取,1表示未领取) if (this.listData[i].free === 1) { allClaimed = false; break; } // 如果已激活通行证,检查通行证奖励是否已领取 if (cc.fx.GameConfig.GM_INFO.passCheckActivate && this.listData[i].passCheck === 1) { allClaimed = false; break; } } // 如果所有奖励都已领取,可以在这里触发相应逻辑 if (allClaimed) { console.log("所有奖励都已领取完毕"); // 隐藏通行证按钮上的红点 this.hidePassCheckRedDot(); } else { console.log("还有未领取的奖励"); } return allClaimed; } // 隐藏通行证按钮上的红点 private hidePassCheckRedDot() { const canvas = cc.find("Canvas"); if (canvas) { const jiaZai = canvas.getComponent("JiaZai"); if (jiaZai) { const top = jiaZai.node.getChildByName("Load")?.getChildByName("Top"); const passBtn = top?.getChildByName("passBtn"); const redNode = passBtn?.getChildByName("red"); if (redNode) { redNode.active = false; } } } } 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(updates: Array<{ itemIndex: number, isLeftReward: boolean }>) { const currentTime = Date.now(); // 使用防抖机制,延迟处理奖励更新 if (this.rewardUpdateTimeout) { clearTimeout(this.rewardUpdateTimeout); } console.log("传给服务器", updates) this.rewardUpdateTimeout = setTimeout(() => { // 修改为传入数组 this.updatePassCheckStatus(updates); this.rewardUpdateTimeout = null; }, 50); } public updateActivateStatus() { this.updatePassCheckStatus(); } // 奖励队列和处理状态 private rewardQueue: Array<{ itemIndex: number, itemId: number, itemNum: number, isLeftReward: boolean }> = []; private isProcessingRewards: boolean = false; private rewardProcessTimeout: any = null; // 整合自passCheckItem.ts的claimReward方法,支持处理可能的循环调用 public claimReward(itemIndex: number, itemId: number, itemNum: number, isLeftReward: boolean) { // 将奖励请求添加到队列中 console.log("领取奖励ID", itemIndex, "物品ID", itemId, "数量", itemNum) this.rewardQueue.push({ itemIndex, itemId, itemNum, isLeftReward }); // 清除之前的定时器 if (this.rewardProcessTimeout) { clearTimeout(this.rewardProcessTimeout); } // 设置延迟处理,合并短时间内多次调用 this.rewardProcessTimeout = setTimeout(() => { this.processRewardQueue(); }, 50); // 50ms延迟,合并短时间内多次调用 } // 处理奖励队列 private processRewardQueue() { // 如果正在处理中,则等待下次处理 if (this.isProcessingRewards) { // 重新设置定时器,稍后再次尝试 if (this.rewardProcessTimeout) { clearTimeout(this.rewardProcessTimeout); } this.rewardProcessTimeout = setTimeout(() => { this.processRewardQueue(); }, 100); return; } // 如果队列为空,直接返回 if (this.rewardQueue.length === 0) { return; } // 标记为正在处理 this.isProcessingRewards = true; // 处理队列中的所有奖励 this.processRewardsInternal([...this.rewardQueue]); // 清空队列 this.rewardQueue = []; // 处理完成 this.isProcessingRewards = false; } // 内部处理奖励方法 private processRewardsInternal(rewards: Array<{ itemIndex: number, itemId: number, itemNum: number, isLeftReward: boolean }>) { // 处理所有奖励的逻辑(道具增加等) const rewardData = []; const canvasTemp = cc.find("Canvas"); let JiaZai = null; if (canvasTemp) { JiaZai = canvasTemp.getComponent("JiaZai"); } // 处理每个奖励 for (const reward of rewards) { cc.fx.GameTool.getPassCheckPorp(reward.itemId, reward.itemNum, false); if (JiaZai) { switch (reward.itemId) { case 1001: // 金币 JiaZai.updateCoin(); break; case 2001: // 冰冻道具 case 2002: // 锤子道具 case 2003: // 魔棒道具 break; default: JiaZai.updatePower(); break; } } console.log("领取奖励", reward.itemId, reward.itemNum); // 通知对应的passCheckItem组件更新UI this.updateRewardUIAfterClaim(reward.itemIndex, reward.isLeftReward); // 收集奖励数据 rewardData.push({ itemId: reward.itemId, itemNum: reward.itemNum }); } // 合并相同类型的奖励 const mergedRewards = this.processRewardData(rewardData); // 显示奖励弹窗(只显示一次) if (JiaZai && mergedRewards.length > 0) { JiaZai.openRewardWindow(mergedRewards); } // 更新服务器状态 console.log("更新奖励状态到服务器:", rewards.length); if (rewards.length > 0) { const rewardUpdates = rewards.map(reward => ({ itemIndex: reward.itemIndex, isLeftReward: reward.isLeftReward })); this.updateRewardStatus(rewardUpdates); } } // 封装奖励数据处理方法,处理循环调用并合并相同类型奖励 private processRewardData(rewards: Array<{ itemId: number, itemNum: number }>): Array<{ type: string, count: number }> { // 创建一个映射来存储每种类型的奖励总和 const rewardMap = new Map(); // 处理每个奖励项 for (const reward of rewards) { let type: string = ""; switch (reward.itemId) { case 1001: // 金币 type = "coin"; break; case 2001: // 冰冻道具 type = "freeze"; break; case 2002: // 锤子道具 type = "hammer"; break; case 2003: // 魔棒道具 type = "magic"; break; case 3001: // 无限体力 900秒 type = "infinite_health"; reward.itemNum = 900; break; case 3002: // 无限体力 1800秒 type = "infinite_health"; reward.itemNum = 1800; break; case 3003: // 无限体力 3600秒 type = "infinite_health"; reward.itemNum = 3600; break; default: // 默认处理为无限体力,使用传入的数量 type = "infinite_health"; break; } console.log("处理奖励数据", reward.itemId, reward.itemNum); // 如果该类型已存在,累加数量;否则设置新值 if (rewardMap.has(type)) { rewardMap.set(type, rewardMap.get(type)! + reward.itemNum); } else { rewardMap.set(type, reward.itemNum); } } // 转换为数组格式 const result: Array<{ type: string, count: number }> = []; rewardMap.forEach((count, type) => { result.push({ type, count }); }); return result; } // 整合自passCheckItem.ts的updateRewardUIAfterClaim方法 private updateRewardUIAfterClaim(itemIndex: number, isLeftReward: boolean) { // 通知对应的passCheckItem组件更新UI 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 组件并更新UI 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.itemIndex === itemIndex) { // 调用passCheckItem的updateRewardUIAfterClaim方法 if (passCheckItem.updateRewardUIAfterClaim) { passCheckItem.updateRewardUIAfterClaim(isLeftReward); } break; } } } } } } allGetReward() { const allRewardsToClaim = []; for (let i = 0; i < this.listData.length; i++) { // 检查免费奖励是否可以领取 if (this.listData[i].free === 1) { allRewardsToClaim.push({ itemIndex: i, itemId: this.listData[i].ItemID1, itemNum: this.listData[i].ItemNum1, isLeftReward: true }); } if (cc.fx.GameConfig.GM_INFO.passCheckActivate) { // 检查通行证奖励是否可以领取 if (this.listData[i].passCheck === 1) { allRewardsToClaim.push({ itemIndex: i, itemId: this.listData[i].ItemID2, itemNum: this.listData[i].ItemNum2, isLeftReward: false }); } } } console.log("批量领取所有物品:", allRewardsToClaim); // 批量处理所有奖励 for (const reward of allRewardsToClaim) { this.claimReward( reward.itemIndex, reward.itemId, reward.itemNum, reward.isLeftReward ); } } protected onDestroy(): void { console.log("销毁passCheckMgr"); // 清理可能存在的列表数据 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; } }