import { _decorator, Component, Node, Label, Button, JsonAsset, Sprite, Color, SpriteFrame } from 'cc'; import { SaveDataManager } from '../../LevelSystem/SaveDataManager'; import EventBus, { GameEvents } from '../../Core/EventBus'; import { TopBarController } from '../TopBarController'; const { ccclass, property } = _decorator; interface ShopConfig { dailyRewards: { money: { baseAmount: number; maxClaimsPerDay: number; maxAdsPerDay: number; firstClaimFree: boolean; adRequiredAfterFirst: boolean; }; diamond: { baseAmount: number; maxClaimsPerDay: number; maxAdsPerDay: number; firstClaimFree: boolean; adRequiredAfterFirst: boolean; }; // 新增Cost按钮配置 costButtons: { maxAdsPerDay: number; // Cost按钮每日最大广告观看次数 }; } } interface DailyRewardData { lastResetDate: string; moneyFreeCount: number; moneyAdCount: number; diamondsFreeCount: number; diamondsAdCount: number; // Cost按钮相关 costAdCount: number; // Cost按钮免费使用状态 - 分别管理 billCostFreeUsed: boolean; diamondCostFreeUsed: boolean; } @ccclass('ShopController') export class ShopController extends Component { @property(Node) moneyRewardNode: Node = null; @property(Node) diamondRewardNode: Node = null; @property(Button) moneyButton: Button = null; @property(Button) diamondButton: Button = null; @property(Label) moneyCountLabel: Label = null; @property(Label) diamondCountLabel: Label = null; @property(Label) moneyAmountLabel: Label = null; @property(Label) diamondAmountLabel: Label = null; @property(JsonAsset) shopConfigAsset: JsonAsset = null; // 新增Cost按钮装饰器 @property(Button) billCostButton: Button = null; @property(Button) diamondCostButton: Button = null; // 按钮置灰图片资源 @property(SpriteFrame) disabledButtonSprite: SpriteFrame = null; // 保存原始按钮图片 private originalBillButtonSprite: SpriteFrame = null; private originalDiamondButtonSprite: SpriteFrame = null; private shopConfig: ShopConfig = null; private dailyRewardData: DailyRewardData = null; private saveDataManager: SaveDataManager = null; private readonly DAILY_REWARD_KEY = 'daily_reward_data'; /** * 格式化数字显示,在数字之间添加空格 * @param num 要格式化的数字 * @returns 格式化后的字符串,如 "50" -> "5 0" */ private formatNumberWithSpaces(num: number): string { return num.toString().split('').join(' '); } onLoad() { this.saveDataManager = SaveDataManager.getInstance(); this.loadShopConfig(); this.loadDailyRewardData(); this.setupEventListeners(); } start() { // 检查disabledButtonSprite是否已设置 console.log('[ShopController] disabledButtonSprite是否已设置:', !!this.disabledButtonSprite); // 保存原始按钮图片 if (this.billCostButton) { const sprite = this.billCostButton.node.getComponent(Sprite); if (sprite) { this.originalBillButtonSprite = sprite.spriteFrame; console.log('[ShopController] 保存钞票按钮原始图片:', !!this.originalBillButtonSprite); } else { console.log('[ShopController] 警告:无法获取钞票按钮的Sprite组件'); } } if (this.diamondCostButton) { const sprite = this.diamondCostButton.node.getComponent(Sprite); if (sprite) { this.originalDiamondButtonSprite = sprite.spriteFrame; console.log('[ShopController] 保存钻石按钮原始图片:', !!this.originalDiamondButtonSprite); } else { console.log('[ShopController] 警告:无法获取钻石按钮的Sprite组件'); } } this.updateUI(); } private loadShopConfig() { if (this.shopConfigAsset) { this.shopConfig = this.shopConfigAsset.json as ShopConfig; console.log('[ShopController] shop.json加载成功:', this.shopConfig); this.updateUI(); } else { console.error('[ShopController] shopConfigAsset未设置,请在编辑器中拖拽shop.json文件到shopConfigAsset属性'); } } private loadDailyRewardData() { const savedData = localStorage.getItem(this.DAILY_REWARD_KEY); const today = this.getCurrentDateString(); if (savedData) { const data = JSON.parse(savedData) as DailyRewardData; // 兼容旧数据:如果存在旧的costFreeUsed字段,迁移到新字段 if (data.hasOwnProperty('costFreeUsed')) { const oldCostFreeUsed = (data as any).costFreeUsed; data.billCostFreeUsed = oldCostFreeUsed || false; data.diamondCostFreeUsed = oldCostFreeUsed || false; delete (data as any).costFreeUsed; console.log('[ShopController] 迁移旧的costFreeUsed数据到新字段'); } // 确保新字段存在,设置默认值 if (data.billCostFreeUsed === undefined) { data.billCostFreeUsed = true; // 默认为true(可用) console.log('[ShopController] 设置billCostFreeUsed默认值: true'); } if (data.diamondCostFreeUsed === undefined) { data.diamondCostFreeUsed = true; // 默认为true(可用) console.log('[ShopController] 设置diamondCostFreeUsed默认值: true'); } // 检查是否需要重置(新的一天) if (data.lastResetDate !== today) { console.log('[ShopController] 检测到新的一天,重置每日奖励数据'); this.resetDailyRewardData(today); } else { this.dailyRewardData = data; console.log('[ShopController] 加载已有的每日奖励数据'); } } else { console.log('[ShopController] 首次运行,创建新的每日奖励数据'); this.resetDailyRewardData(today); } console.log('[ShopController] 每日奖励数据:', this.dailyRewardData); } private resetDailyRewardData(date: string) { this.dailyRewardData = { lastResetDate: date, moneyFreeCount: 0, moneyAdCount: 0, diamondsFreeCount: 0, diamondsAdCount: 0, costAdCount: 0, billCostFreeUsed: true, diamondCostFreeUsed: true }; this.saveDailyRewardData(); } private saveDailyRewardData() { localStorage.setItem(this.DAILY_REWARD_KEY, JSON.stringify(this.dailyRewardData)); } private getCurrentDateString(): string { const now = new Date(); const month = (now.getMonth() + 1).toString(); const day = now.getDate().toString(); const paddedMonth = month.length === 1 ? '0' + month : month; const paddedDay = day.length === 1 ? '0' + day : day; return `${now.getFullYear()}-${paddedMonth}-${paddedDay}`; } private setupEventListeners() { // 监听货币变化事件,更新UI EventBus.getInstance().on(GameEvents.CURRENCY_CHANGED, this.updateUI, this); } private updateUI() { if (!this.shopConfig || !this.dailyRewardData) return; // 更新钞票奖励UI this.updateMoneyRewardUI(); // 更新钻石奖励UI this.updateDiamondRewardUI(); // 更新Cost按钮UI this.updateBillCostButtonUI(); this.updateDiamondCostButtonUI(); } private updateMoneyRewardUI() { if (!this.shopConfig || !this.dailyRewardData) return; const config = this.shopConfig.dailyRewards.money; const freeCount = this.dailyRewardData.moneyFreeCount; const adCount = this.dailyRewardData.moneyAdCount; const totalCount = freeCount + adCount; const maxCount = config.maxClaimsPerDay; // 更新次数显示 if (this.moneyCountLabel) { this.moneyCountLabel.string = `${totalCount}/${maxCount}`; } // 更新金额显示 if (this.moneyAmountLabel) { this.moneyAmountLabel.string = this.formatNumberWithSpaces(config.baseAmount); } // 更新按钮状态(带广告标识的按钮) if (this.moneyButton) { const canClaim = totalCount < maxCount; this.moneyButton.interactable = canClaim; // 更新按钮文本 const buttonLabel = this.moneyButton.node.getChildByName('Label')?.getComponent(Label); if (buttonLabel) { if (!canClaim) { buttonLabel.string = "今日已达上限"; } else { buttonLabel.string = "观看广告"; } } } } private updateDiamondRewardUI() { if (!this.shopConfig || !this.dailyRewardData) return; const config = this.shopConfig.dailyRewards.diamond; const freeCount = this.dailyRewardData.diamondsFreeCount; const adCount = this.dailyRewardData.diamondsAdCount; const totalCount = freeCount + adCount; const maxCount = config.maxClaimsPerDay; // 更新次数显示 if (this.diamondCountLabel) { this.diamondCountLabel.string = `${totalCount}/${maxCount}`; } // 更新金额显示 if (this.diamondAmountLabel) { this.diamondAmountLabel.string = this.formatNumberWithSpaces(config.baseAmount); } // 更新按钮状态(带广告标识的按钮) if (this.diamondButton) { const canClaim = totalCount < maxCount; this.diamondButton.interactable = canClaim; // 更新按钮文本 const buttonLabel = this.diamondButton.node.getChildByName('Label')?.getComponent(Label); if (buttonLabel) { if (!canClaim) { buttonLabel.string = "今日已达上限"; } else { buttonLabel.string = "观看广告"; } } } } // 钞票奖励按钮点击事件(带广告标识的按钮) public onMoneyRewardClick() { if (!this.shopConfig || !this.dailyRewardData) return; const config = this.shopConfig.dailyRewards.money; const freeCount = this.dailyRewardData.moneyFreeCount; const adCount = this.dailyRewardData.moneyAdCount; const totalCount = freeCount + adCount; const maxCount = config.maxClaimsPerDay; if (totalCount >= maxCount) { console.log('[ShopController] 钞票奖励已达每日上限'); return; } // 看广告增加次数 this.showAdForMoneyReward(); } // 钻石奖励按钮点击事件(带广告标识的按钮) public onDiamondRewardClick() { if (!this.shopConfig || !this.dailyRewardData) return; const config = this.shopConfig.dailyRewards.diamond; const freeCount = this.dailyRewardData.diamondsFreeCount; const adCount = this.dailyRewardData.diamondsAdCount; const totalCount = freeCount + adCount; const maxCount = config.maxClaimsPerDay; if (totalCount >= maxCount) { console.log('[ShopController] 钻石奖励已达每日上限'); return; } // 看广告增加次数 this.showAdForDiamondReward(); } private claimMoneyReward(isFromAd: boolean) { const amount = this.shopConfig.dailyRewards.money.baseAmount; // 添加钞票 const success = this.saveDataManager.addMoney(amount, isFromAd ? 'shop_ad_reward' : 'shop_free_reward'); if (success) { // 更新领取次数 if (isFromAd) { this.dailyRewardData.moneyAdCount++; } else { this.dailyRewardData.moneyFreeCount++; } this.saveDailyRewardData(); this.updateUI(); console.log(`[ShopController] 成功领取钞票奖励: ${amount}, 来源: ${isFromAd ? '广告' : '免费'}`); // 可以在这里添加奖励动画或提示 this.showRewardEffect('money', amount); } else { console.error('[ShopController] 领取钞票奖励失败'); } } private claimDiamondReward(isFromAd: boolean) { const config = this.shopConfig.dailyRewards.diamond; const amount = config.baseAmount; // 添加钻石 const success = this.saveDataManager.addDiamonds(amount, isFromAd ? 'shop_ad_reward' : 'shop_free_reward'); if (success) { // 更新领取次数 if (isFromAd) { this.dailyRewardData.diamondsAdCount++; } else { this.dailyRewardData.diamondsFreeCount++; } this.saveDailyRewardData(); this.updateUI(); console.log(`[ShopController] 成功领取钻石奖励: ${amount}, 来源: ${isFromAd ? '广告' : '免费'}`); // 可以在这里添加奖励动画或提示 this.showRewardEffect('diamonds', amount); } else { console.error('[ShopController] 领取钻石奖励失败'); } } private showAdForMoneyReward() { console.log('[ShopController] 显示钞票奖励广告'); // 这里应该调用广告SDK显示广告 // 立即发放奖励,无延迟 console.log('[ShopController] 广告观看完成,发放钞票奖励'); this.claimMoneyReward(true); } private showAdForDiamondReward() { console.log('[ShopController] 显示钻石奖励广告'); // 这里应该调用广告SDK显示广告 // 立即发放奖励,无延迟 console.log('[ShopController] 广告观看完成,发放钻石奖励'); this.claimDiamondReward(true); } private showRewardEffect(type: 'money' | 'diamonds', amount: number) { // 这里可以添加奖励特效 console.log(`[ShopController] 显示奖励特效: ${type} +${amount}`); // 可以触发TopBarController的货币动画 const topBarController = this.node.parent?.getComponentInChildren(TopBarController); if (topBarController) { // 如果TopBarController有显示奖励动画的方法,可以在这里调用 } } // 更新钞票Cost按钮UI状态(底部免费按钮) public updateBillCostButtonUI() { if (!this.dailyRewardData) { console.log('[ShopController] dailyRewardData为空,跳过更新'); return; } const costFreeUsed = this.dailyRewardData.billCostFreeUsed !== undefined ? this.dailyRewardData.billCostFreeUsed : true; console.log('[ShopController] 更新钞票Cost按钮UI状态,billCostFreeUsed:', costFreeUsed); if (this.billCostButton) { const buttonLabel = this.billCostButton.node.getChildByName('Label')?.getComponent(Label); const buttonSprite = this.billCostButton.node.getComponent(Sprite); console.log('[ShopController] 按钮组件检查 - Label:', !!buttonLabel, 'Sprite:', !!buttonSprite); if (costFreeUsed) { // 每天第一次,显示"免费" this.billCostButton.interactable = true; if (buttonLabel) { buttonLabel.string = "免费"; } // 恢复原始图片 if (buttonSprite && this.originalBillButtonSprite) { buttonSprite.spriteFrame = this.originalBillButtonSprite; console.log('[ShopController] 恢复按钮原始图片'); } } else { // 免费已使用,按钮置灰,并更新对应的数值显示 this.billCostButton.interactable = false; if (buttonLabel) { buttonLabel.string = "已使用"; } // 设置置灰图片 console.log('[ShopController] 尝试设置置灰图片 - buttonSprite:', !!buttonSprite, 'disabledButtonSprite:', !!this.disabledButtonSprite); if (buttonSprite && this.disabledButtonSprite) { buttonSprite.spriteFrame = this.disabledButtonSprite; console.log('[ShopController] 设置按钮为置灰图片成功'); } else { console.log('[ShopController] 警告:无法设置置灰图片 - buttonSprite:', !!buttonSprite, 'disabledButtonSprite:', !!this.disabledButtonSprite); } // 更新钞票数值显示 this.updateMoneyAmountFromConfig(); } } } // 更新钻石Cost按钮UI状态(底部免费按钮) public updateDiamondCostButtonUI() { if (!this.dailyRewardData) { console.log('[ShopController] dailyRewardData为空,跳过更新'); return; } const costFreeUsed = this.dailyRewardData.diamondCostFreeUsed !== undefined ? this.dailyRewardData.diamondCostFreeUsed : true; console.log('[ShopController] 更新钻石Cost按钮UI状态,diamondCostFreeUsed:', costFreeUsed); if (this.diamondCostButton) { const buttonLabel = this.diamondCostButton.node.getChildByName('Label')?.getComponent(Label); const buttonSprite = this.diamondCostButton.node.getComponent(Sprite); if (costFreeUsed) { // 每天第一次,显示"免费" this.diamondCostButton.interactable = true; if (buttonLabel) { buttonLabel.string = "免费"; } // 恢复原始图片 if (buttonSprite && this.originalDiamondButtonSprite) { buttonSprite.spriteFrame = this.originalDiamondButtonSprite; } } else { // 免费已使用,按钮置灰,并更新对应的数值显示 this.diamondCostButton.interactable = false; if (buttonLabel) { buttonLabel.string = "已使用"; } // 设置置灰图片 if (buttonSprite && this.disabledButtonSprite) { buttonSprite.spriteFrame = this.disabledButtonSprite; } // 更新钻石数值显示 this.updateDiamondAmountFromConfig(); } } } // 从配置JSON更新钞票数值显示 private updateMoneyAmountFromConfig() { if (this.moneyAmountLabel && this.shopConfig) { // 从配置中读取下一次的钞票数值 const nextMoneyAmount = this.shopConfig.dailyRewards.money.baseAmount || 100; this.moneyAmountLabel.string = this.formatNumberWithSpaces(nextMoneyAmount); console.log('[ShopController] 从配置更新钞票数值:', nextMoneyAmount); } } // 从配置JSON更新钻石数值显示 private updateDiamondAmountFromConfig() { if (this.diamondAmountLabel && this.shopConfig) { // 从配置中读取下一次的钻石数值 const nextDiamondAmount = this.shopConfig.dailyRewards.diamond.baseAmount || 10; this.diamondAmountLabel.string = this.formatNumberWithSpaces(nextDiamondAmount); console.log('[ShopController] 从配置更新钻石数值:', nextDiamondAmount); } } // 钞票Cost按钮点击事件(底部免费按钮) public onBillCostClick() { console.log('[ShopController] 钞票Cost按钮被点击'); if (!this.dailyRewardData) { console.log('[ShopController] dailyRewardData为空,无法处理点击'); return; } const costFreeUsed = this.dailyRewardData.billCostFreeUsed; console.log('[ShopController] 当前billCostFreeUsed状态:', costFreeUsed); if (costFreeUsed) { // 第一次免费点击 this.dailyRewardData.billCostFreeUsed = false; // 增加钞票计数 this.dailyRewardData.moneyFreeCount++; this.saveDailyRewardData(); console.log('[ShopController] 钞票免费按钮使用完毕,更新UI'); this.updateBillCostButtonUI(); // 立即更新按钮UI this.updateUI(); // 更新整体UI return; } console.log('[ShopController] 钞票免费按钮今日已使用'); } // 钻石Cost按钮点击事件(底部免费按钮) public onDiamondCostClick() { if (!this.dailyRewardData) return; const costFreeUsed = this.dailyRewardData.diamondCostFreeUsed; if (costFreeUsed) { // 第一次免费点击 this.dailyRewardData.diamondCostFreeUsed = false; // 增加钻石计数 this.dailyRewardData.diamondsFreeCount++; this.saveDailyRewardData(); this.updateUI(); console.log('[ShopController] 钻石免费按钮使用完毕,钻石计数增加'); return; } console.log('[ShopController] 钻石免费按钮今日已使用'); } onDestroy() { // 移除事件监听 EventBus.getInstance().off(GameEvents.CURRENCY_CHANGED, this.updateUI, this); } // 调试方法:重置每日奖励数据 public resetDailyRewards() { const today = this.getCurrentDateString(); this.resetDailyRewardData(today); this.updateUI(); console.log('[ShopController] 每日奖励数据已重置'); } // 获取当前每日奖励状态(用于调试) public getDailyRewardStatus() { return { config: this.shopConfig, data: this.dailyRewardData, today: this.getCurrentDateString() }; } }