cb/assets/shop/script/passCheckMgr.ts

606 lines
22 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;
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<string, number>();
// 处理每个奖励项
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;
}
}