ShopSystem每日奖励实现说明.md 5.9 KB

ShopSystem每日奖励系统实现说明

功能概述

本系统实现了一个完整的每日奖励机制,包括:

  1. 每天第一次免费领取钞票和钻石
  2. 观看广告获得额外奖励(有每日上限)
  3. 新增Cost按钮,支持免费观看广告(计入总广告次数)
  4. 自动每日刷新机制

核心功能实现

1. 每日刷新机制

实现原理:

  • 使用 localStorage 存储每日奖励数据
  • 每次启动时检查 lastResetDate 与当前日期
  • 如果日期不同,自动重置所有计数器

关键代码:

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接口:

interface DailyRewardData {
    lastResetDate: string;     // 上次重置日期
    moneyFreeCount: number;    // 金币免费领取次数
    moneyAdCount: number;      // 金币广告观看次数
    diamondsFreeCount: number; // 钻石免费领取次数
    diamondsAdCount: number;   // 钻石广告观看次数
    costAdCount: number;       // Cost按钮广告观看次数
    costFreeUsed: boolean;     // Cost按钮免费使用标记
}

3. 配置文件结构

shop.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中新增了两个按钮属性:

@property(Button)
billCostButton: Button = null;

@property(Button)
diamondCostButton: Button = null;

免费机制

  • 每天第一次点击显示"免费"文本,点击后直接生效
  • 免费使用后按钮文本变为空,并根据广告次数判断是否置灰
  • 后续点击需要观看广告,计入每日广告观看总次数
  • 当达到广告上限后按钮会自动置灰

2. Cost按钮事件处理

// 钞票Cost按钮点击事件
public onBillCostClick() {
    // 检查每日广告观看次数限制
    // 显示广告并增加计数
}

// 钻石Cost按钮点击事件
public onDiamondCostClick() {
    // 检查每日广告观看次数限制
    // 显示广告并增加计数
}

3. UI状态更新

新增 updateCostButtonsUI() 方法,根据当前广告观看次数更新按钮状态:

  • 未达上限:显示"免费观看",按钮可点击
  • 达到上限:显示"今日已达上限",按钮置灰

使用说明

1. 编辑器配置

在Cocos Creator编辑器中:

  1. shop.json 文件拖拽到 ShopControllershopConfigAsset 属性
  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. 推送通知:在新的一天提醒用户领取奖励

调试功能

// 重置每日奖励数据(调试用)
public resetDailyRewards()

// 获取当前状态(调试用)
public getDailyRewardStatus()

这些方法可以在开发过程中用于测试每日刷新功能。