# ShopSystem每日奖励系统实现说明 ## 功能概述 本系统实现了一个完整的每日奖励机制,包括: 1. 每天第一次免费领取钞票和钻石 2. 观看广告获得额外奖励(有每日上限) 3. 新增Cost按钮,支持免费观看广告(计入总广告次数) 4. 自动每日刷新机制 ## 核心功能实现 ### 1. 每日刷新机制 **实现原理:** - 使用 `localStorage` 存储每日奖励数据 - 每次启动时检查 `lastResetDate` 与当前日期 - 如果日期不同,自动重置所有计数器 **关键代码:** ```typescript private loadDailyRewardData() { const savedData = localStorage.getItem(this.DAILY_REWARD_KEY); const today = this.getCurrentDateString(); if (savedData) { const data = JSON.parse(savedData) as DailyRewardData; // 检查是否需要重置(新的一天) if (data.lastResetDate !== today) { this.resetDailyRewardData(today); } else { this.dailyRewardData = data; } } else { this.resetDailyRewardData(today); } } 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}`; } ``` ### 2. 数据结构 **DailyRewardData接口:** ```typescript interface DailyRewardData { lastResetDate: string; // 上次重置日期 moneyFreeCount: number; // 金币免费领取次数 moneyAdCount: number; // 金币广告观看次数 diamondsFreeCount: number; // 钻石免费领取次数 diamondsAdCount: number; // 钻石广告观看次数 costAdCount: number; // Cost按钮广告观看次数 costFreeUsed: boolean; // Cost按钮免费使用标记 } ``` ### 3. 配置文件结构 **shop.json配置:** ```json { "dailyRewards": { "money": { "baseAmount": 100, "maxClaimsPerDay": 36, "maxAdsPerDay": 4, "firstClaimFree": true, "adRequiredAfterFirst": true }, "diamond": { "baseAmount": 10, "maxClaimsPerDay": 36, "maxAdsPerDay": 2, "firstClaimFree": true, "adRequiredAfterFirst": true }, "costButtons": { "maxAdsPerDay": 5 } }, "ui": { "moneyClaimButton": { "normalText": "领取钞票", "adText": "看广告领取", "disabledText": "今日已达上限" }, "diamondClaimButton": { "normalText": "领取钻石", "adText": "看广告领取", "disabledText": "今日已达上限" }, "costButtons": { "freeText": "免 费", "normalText": "免费观看", "disabledText": "今日已达上限" } } } ``` ## 新增功能 ### 1. Cost按钮装饰器 在ShopController中新增了两个按钮属性: ```typescript @property(Button) billCostButton: Button = null; @property(Button) diamondCostButton: Button = null; ``` **免费机制**: - 每天第一次点击显示"免费"文本,点击后直接生效 - 免费使用后按钮文本变为空,并根据广告次数判断是否置灰 - 后续点击需要观看广告,计入每日广告观看总次数 - 当达到广告上限后按钮会自动置灰 ### 2. Cost按钮事件处理 ```typescript // 钞票Cost按钮点击事件 public onBillCostClick() { // 检查每日广告观看次数限制 // 显示广告并增加计数 } // 钻石Cost按钮点击事件 public onDiamondCostClick() { // 检查每日广告观看次数限制 // 显示广告并增加计数 } ``` ### 3. UI状态更新 新增 `updateCostButtonsUI()` 方法,根据当前广告观看次数更新按钮状态: - 未达上限:显示"免费观看",按钮可点击 - 达到上限:显示"今日已达上限",按钮置灰 ## 使用说明 ### 1. 编辑器配置 在Cocos Creator编辑器中: 1. 将 `shop.json` 文件拖拽到 `ShopController` 的 `shopConfigAsset` 属性 2. 将对应的按钮节点拖拽到相应的属性: - `billCostButton`: Canvas/ShopUI/ScrollView/view/content/bill/Cost - `diamondCostButton`: Canvas/ShopUI/ScrollView/view/content/diamond/Cost ### 2. 按钮事件绑定 在编辑器中为按钮绑定点击事件: - 钞票Cost按钮 → `ShopController.onBillCostClick` - 钻石Cost按钮 → `ShopController.onDiamondCostClick` ### 3. 配置参数说明 - `maxAdsPerDay`: 每日最大广告观看次数 - `firstClaimFree`: 是否首次免费领取 - `baseAmount`: 基础奖励数量 - `maxClaimsPerDay`: 每日最大领取次数 #### Cost按钮参数说明 **配置参数**: - `maxAdsPerDay`: 每日最大广告观看次数 **UI文本**: - `freeText`: 每天第一次免费状态显示文本 - `normalText`: 正常状态显示文本(广告观看) - `disabledText`: 禁用状态显示文本(达到上限后) ## 每日刷新机制详解 ### 刷新时机 - 游戏启动时自动检查 - 跨越午夜0点时自动重置 - 可手动调用 `resetDailyRewards()` 方法重置(调试用) ### 刷新内容 - 所有领取次数归零 - 广告观看次数归零 - 更新最后重置日期 - 重新启用所有按钮 ### 数据持久化 - 使用 `localStorage` 存储 - 键名:`daily_reward_data` - 格式:JSON字符串 ## 扩展建议 1. **服务器同步**:可将数据同步到服务器,防止本地数据被篡改 2. **时区处理**:考虑不同时区用户的刷新时间 3. **奖励动画**:添加领取奖励时的视觉效果 4. **统计分析**:记录用户的领取行为数据 5. **推送通知**:在新的一天提醒用户领取奖励 ## 调试功能 ```typescript // 重置每日奖励数据(调试用) public resetDailyRewards() // 获取当前状态(调试用) public getDailyRewardStatus() ``` 这些方法可以在开发过程中用于测试每日刷新功能。