zoukankan      html  css  js  c++  java
  • 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("
    ", "");
            }
            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;
        }
    }

    四、总结

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

      

      

  • 相关阅读:
    UML箭头含义整理
    协变返回类型
    Thymeleaf取出model中的数据
    宝塔面板中的mysql查看密码问题
    宝塔面板如何登录
    mysql查看数据库、表的基本语句
    springboot拦截器实例
    Thymeleaf中的fragments学习
    食物链
    银河英雄传说
  • 原文地址:https://www.cnblogs.com/chongxin/p/3719744.html
Copyright © 2011-2022 走看看