Unity3D 游戏开发应用篇——每日登陆(持久化类实现)
上一篇中我们实现用本地文件实现了持久化类的保存,当然小型数据用PlayerPrefs存储,或者采用XML服务器持久化也行。因为我涉及的角色类和玩家类数据比较多,加上项目要求尽量少与服务器交互,所以采用了本地持久化。废话不多说,进入主题
一、应用场景

项目要实现这么一个每日登陆的功能,设计如下:
我们假设每天9点刷新登陆奖励,中断一天则从第一天开始:

初步设想是每日登陆奖励必须有网的情况下才能领取,通过服务器逻辑验证上一次领取时间和登陆时间,产生对应的奖励界面。
至于领取时间可以采用服务器自动刷新和玩家手动刷新,这里我选择了手动刷新。
注意,最好不要采用本地时间为基准。
二、设计思路
玩家持久化类中增加一个领取奖励时间变量,规则如下:
在每次登陆游戏联网的时候得到服务器的标准网络时间,和上一次的领取奖励时间进行逻辑判断。
有以下三种情况:
领取奖励时间为null:
领取奖励时间和联网验证时间在同一天:
领取奖励时间和联网验证时间不在同一天:
逻辑图如下:

至于领取时间刷新,则如下图所示有两种情况:
一、服务器判断逻辑之后自动给客户端刷新
二、客户端手动刷新

三、核心代码
//进行联网验证
if (DebugUtils.HasConnection() && Globals.Me != null)
{ Globals.NetWorkAvailable = true;
//请求服务器刷新
StartCoroutine(UpdateLoginTime());
} public IEnumerator UpdateLoginTime()
{
Debug.Log("privious time is " + Globals.Me.LoginDateTime);
if (!Globals.NetWorkAvailable)
yield break; WWW www = new WWW(GameUrl.Time_Url);
yield return www;
//有错误
#region
if (www.error != null)
{
Utils.WriteLog("UpdateLoginTime" + www.error);
MsgBox.Show("亲 网络有问题哦");
Globals.NetWorkAvailable = false;
}
#endregion
else
{
//解析网络时间
#region
string[] tempArray = www.text.Split(';');
for (int i = ; i < tempArray.Length; i++)
{
tempArray[i] = tempArray[i].Replace("\r\n", "");
}
string year = tempArray[].Split('=')[];
string month = tempArray[].Split('=')[];
string day = tempArray[].Split('=')[];
string hour = tempArray[].Split('=')[];
string minite = tempArray[].Split('=')[];
string second = tempArray[].Split('=')[];
DateTime tmp = DateTime.Parse(year + "-" + month + "-" + day + " " + hour + ":" + minite + ":" + second);
#endregion
Debug.Log("update time" + tmp);
//第一次更新
//这里是服务器逻辑判断
#region
if (Globals.Me.LoginDateTime == null)
{
//调用第一天第一次奖励
if (!PlayerPrefs.HasKey("Reward_Level")){
PlayerPrefs.SetInt("Reward_Level", (int)(Login_Kind.FirstDay));
Debug.Log("first" + PlayerPrefs.GetInt("Reward_Level"));
}
else {
PlayerPrefs.SetInt("Reward_Level", (int)(Login_Kind.FirstDay));
Debug.Log("first" + PlayerPrefs.GetInt("Reward_Level"));
}
Create_Login_Reward(tmp);
}
#endregion
//不是第一次
else {
//不是同一天更新
#region
if (!isSameDay(tmp))
{
//是连续更新
#region
if (isContinue(tmp))
{
PlayerPrefs.SetInt("Reward_Level", ((PlayerPrefs.GetInt("Reward_Level") + ) % ));
Debug.Log("then" + PlayerPrefs.GetInt("Reward_Level"));
}
#endregion
//不是连续更新
#region
else
{
//调用第一天奖励
PlayerPrefs.SetInt("Reward_Level", (int)(Login_Kind.FirstDay));
Debug.Log("Reset" + PlayerPrefs.GetInt("Reward_Level"));
}
#endregion Create_Login_Reward(tmp);
}
#endregion
//同一天
#region
else
{
Create_Normal();
}
#endregion }
}
}
//根据联网的服务器逻辑产生对应的奖励列表
//satisfy update reward condition
//called by other
public void Update_Reward(DateTime updatetime)
{ #region
foreach (Transform child in transform)
{
if (child.name.Contains("_"))
{
int Reward_Level = PlayerPrefs.GetInt("Reward_Level");
//check Reward_Level day
#region
if (int.Parse(child.name.Split('_')[]) == Reward_Level)
{
child.GetChild().active = true;
Set_Refresh(int.Parse(child.name.Split('_')[]) * , updatetime);
}
else
{
child.GetChild().active = false;
}
#endregion //yellow <= Reward_Level
//blue > Reward_Level
#region
if (int.Parse(child.name.Split('_')[]) <= Reward_Level)
{
//yellow
child.GetComponent<ButtonNormal>().OnMouseDown();
}
else
{
//blue
child.GetComponent<ButtonNormal>().OnMouseUpAsButton();
}
#endregion
}
}
#endregion
} public void Set_Refresh(int Add_Number,DateTime RefreshDateTime) {
UI_Get_LoginReword tmp = transform.Find("Get").GetComponent<UI_Get_LoginReword>();
tmp.Add_Number = Add_Number;
tmp.RefreshDateTime = RefreshDateTime;
}
//采用手动刷新 这里是按下领取奖励按钮之后
public void OnMouseUpAsButton()
{ //print("you enter is " + transform.name);
base.OnMouseUpAsButton(); if (Add_Number != && RefreshDateTime!=DateTime.MinValue) {
//print(Add_Number + "add is ");
//Globals.Me.LoginDateTime = new Nullable<DateTime>(currentTime);
Globals.Me.LoginDateTime = RefreshDateTime;
print("RefreshDateTime is " + Globals.Me.LoginDateTime);
Globals.Me.Gold_Number += Add_Number;
}
}
四、总结
这里把服务器逻辑放在本地,其实应该放在服务器上的,后期可以考虑采用服务器判断。
Unity3D 游戏开发应用篇——每日登陆(持久化类实现)的更多相关文章
- 【Unity3D游戏开发】之全局管理类的几种方式 (十六)
如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合存储一些全局的变量,如游戏当前关卡.玩家得分等 ...
- unity3D游戏开发之详解Animation类和Animator类
详解Animator类和Animation类 链接: http://wenku.baidu.com/link?url=SiaUYcdrNYjOYrWVDJSKGAYdJOntMTOhsVJtyBk2i ...
- [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读
---------------------------------------------------------------------------------------------------- ...
- NHibernate 之持久化类、拦截器 (第二篇)
一.持久化类中成员标量的要求 作为被NHibernate使用的持久化类,必须满足以下几点要求: 1.声明读写属性 在NHibernate的使用中,持久化类的成员变量必须声明对应的属性,NHiberna ...
- [Unity3D]Unity3D游戏开发之飞机大战项目解说
大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目.这是一个比較综合的 ...
- [Unity3D]Unity3D游戏开发Lua随着游戏的债券(于)
---------------------------------------------------------------------------------------------------- ...
- [Unity3D]Unity3D游戏开发《反对》说到游戏(上)——目标跟踪
朋友,大家好.我是秦培,欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 首先博主要自我反省,过了这么久才来更新博客,这段时间主要是在忙着写期末的作业,所以博主基本上没 ...
- [Unity3D]Unity3D游戏开发之异步记载场景并实现进度条读取效果
大家好,我是秦元培.欢迎大家关注我的博客,我的博客地址是:blog.csdn.net/qinyuanpei.终于在各种无语的论文作业中解脱了,所以立即抓紧时间来这里更新博客.博主本来计划在Unity3 ...
- [Unity3D]Unity3D游戏开发之从Unity3D到Eclipse
---------------------------------------------------------------------------------------------------- ...
随机推荐
- php面向对象的多态
多态是指使用类的上下文来重新定义或改变类的性质或行为,或者说接口的多种不同的实现方式即为多态.把不同的子类对象都当成父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需要 ...
- 标识域 Identify Field
在对象中保存DB的ID字段,以维持内存对象和DB数据Row之间的identify. 关系DB使用key来区分数据行. 而内存对象不需要这样的键.因为对象系统能够保证身份确认. 读取时没有问题,但是为了 ...
- css3学习笔记之按钮
基本按钮样式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <!DOCTYPE ht ...
- javascript给不能修改的函数增加额外处理的方法
不知道是否可行,但姑且google之. 查看到相关的stack overflow(堆栈溢出)帖子:http://stackoverflow.com/questions/1659219/add-to-a ...
- CSS3/jQuery创意盒子动画菜单
作为前端开发者,各种各样的jQuery菜单见过不少,这款jQuery/CSS3菜单却是别具一格,菜单项嵌入到九宫格中,像小盒子一样,加上温馨的背景,菜单整体外观十分可爱.点击菜单项,盒子就会展开,展示 ...
- 12.iscsi-target
server: 环境:rhel7.2 软件包:targetcli-2.1.fb41-3.el7.noarch,selinux-policy-targeted-3.13.1-60.el7.noarch ...
- Android 悬浮窗 WindowManager WindowManager.LayoutParamas
前方高清大图~~~~ 绘制的图片资源: // draw bitmap BitmapDrawable bmpDraw = (BitmapDrawable) getResources().getDrawa ...
- silverlight视频、音频
几天发现MediaElement播放不了wav格式的音频文件,在网上找到一篇解决的文章: http://www.cnblogs.com/rupeng/archive/2011/02/20/195936 ...
- Laravel 5 基础(三)- 向视图传送数据
我们在Routes.php中新建一个路由 Route::get('about', 'PagesController@about'); 在浏览器中浏览会获得一个错误,错误信息仅仅是一个提示信息,缺少细节 ...
- 通过数据绑定模板得到对应的Item控件
这类控件都继承于Selector,其中主要有ComboBox.listview.listbox.datagrid. 由于个人对WPF的了解所有可能有遗漏,希望各位能够指出一起进步. 在遍历上面控件时主 ...