上一篇中我们实现用本地文件实现了持久化类的保存,当然小型数据用PlayerPrefs存储,或者采用XML服务器持久化也行。因为我涉及的角色类和玩家类数据比较多,加上项目要求尽量少与服务器交互,所以采用了本地持久化。废话不多说,进入主题
一、应用场景
项目要实现这么一个每日登陆的功能,设计如下:
我们假设每天9点刷新登陆奖励,中断一天则从第一天开始:
初步设想是每日登陆奖励必须有网的情况下才能领取,有网才能更新每天第一次登陆时间,进行服务器验证,之后的登陆时间如果小于一天则不记录。
然后根据连续登陆天数更新奖励列表。这里第一次登陆时间是持久化保存的。
如果没有网的情况下使用本地时间更新每天第一次登陆时间,出现如下后果:
玩家今天只需要多次设定好本地时间,分别为今天,明天,后天的8点,规则却判定一天内有多次第一次登陆,也就是说可以无限刷金币。
下图可以多次刷金币
二、设计思路
玩家持久化类中增加一个第一次登陆时间属性,规则如下:
如果没有网,则该属性是一个默认值,永远满足第一天登陆规则:
如果有网,则该属性被服务器刷新,并且一天内登陆不会被重复刷新:在明天的登陆中才会被刷新,可以满足第二天登陆的奖励:
在明天没有登陆,第三天登陆刷新登陆时间,重置第一天登陆奖励。
三、核心代码
//有网的情况下,才生成每日登陆奖励预设,可以刷新玩家是持久化类每天第一次登陆时间
//当然此时的玩家持久化类已经加载,每天第一次登陆时间永远是默认的
if (DebugUtils.HasConnection())
{
//print(DebugUtils.HasConnection());
Globals.NetWorkAvailable = true;
Instantiate(Login_Reward);
}
//Login_Reward 的组件脚本
//更新角色每天第一次登陆时间,然后和上一个第一次登陆时间进行比较,判断更新奖励列表
//当然我这里写的比较简单,应该还要保证一天内其他登陆时间不会刷新,这里的代码都是初步代码,后期我还会更新
IEnumerator Start() {
//已经联网的情况下
//服务器更新游戏的角色登陆时间
if (Globals.Me != null && Globals.NetWorkAvailable) {
Nullable<DateTime> pervious = Globals.Me.LoginDateTime;
//wait update
yield return StartCoroutine(Globals.Me.UpdateLoginTime());
Nullable<DateTime> now = Globals.Me.LoginDateTime;
DebugUtils.Assert(now.HasValue&&pervious.HasValue);
//print(now.Value.Second);
Update_Reward();
}
}
//Update_Reward判断
//根据两次的第一次登陆来判断是否连续登陆,更新奖励列表
//if中的主要是一些更新操作
void Update_Reward(Nullable<DateTime> pervious, Nullable<DateTime> now)
{
//if true
//satisfy update reward condition
if (Judge_Update_Reward_Condition())
{
//get the reward level
//这个变量我放在持久化类中
#region
if (!PlayerPrefs.HasKey("Reward_Level"))
{
PlayerPrefs.SetInt("Reward_Level", (int)(Login_Kind.FirstDay));
print("first" + PlayerPrefs.GetInt("Reward_Level"));
}
else
{
PlayerPrefs.SetInt("Reward_Level", ((PlayerPrefs.GetInt("Reward_Level") + 1) % 7));
print("then" + PlayerPrefs.GetInt("Reward_Level"));
}
#endregion
//Update Reward
#region
foreach (Transform child in transform)
{
if (child.name.Contains("_")) {
int tmp = PlayerPrefs.GetInt("Reward_Level");
child.GetChild(0).active = (int.Parse(child.name.Split(‘_‘)[0]) == tmp ? true : false);
//print(transform.GetChild(0).name);
if (int.Parse(child.name.Split(‘_‘)[0]) <= tmp)
{
child.GetComponent<ButtonNormal>().OnMouseDown();
}
else {
child.GetComponent<ButtonNormal>().OnMouseUpAsButton();}
}
}
#endregion
}}
四、总结
其实这些持久化类本身最好还是存放在服务器中比较好,后期估计要做一点改动。