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 = 0; i < tempArray.Length; i++)
        {
            tempArray[i] = tempArray[i].Replace("\r\n", "");
        }
        string year = tempArray[1].Split('=')[1];
        string month = tempArray[2].Split('=')[1];
        string day = tempArray[3].Split('=')[1];
        string hour = tempArray[5].Split('=')[1];
        string minite = tempArray[6].Split('=')[1];
        string second = tempArray[7].Split('=')[1];
        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") + 1) % 7));
                    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('_')[0]) == Reward_Level)
                    {
                       child.GetChild(0).active = true;
                       Set_Refresh(int.Parse(child.name.Split('_')[1]) * 1000, updatetime);
                    }
                    else
                    {
                        child.GetChild(0).active = false;
                    }
                    #endregion

                    //yellow <= Reward_Level
                    //blue > Reward_Level
                    #region
                    if (int.Parse(child.name.Split('_')[0]) <= 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 != 0 && 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;
    }
}

四、总结

  这里把服务器逻辑放在本地,其实应该放在服务器上的,后期可以考虑采用服务器判断。

  

  

posted @ 2014-05-09 22:31  灵魂重新  阅读(1337)  评论(0编辑  收藏  举报