zoukankan      html  css  js  c++  java
  • 仿LOL项目开发第五天

    仿LOL项目开发第五天

                                          by草帽

    今天呢,我们看下能开发什么内容,首先上节我们已经讲了UI框架的搭建,上节还遗留下很多问题,比如说消息的字符是代码里面自己赋值的。

    那么就比较死板,按照正常的逻辑,那些字符我们得从配置文件中获取,然后赋值给消息提示。

    所以呢,我们创建一个StringConfigManager来统一管理这些字符串。

    using UnityEngine;
    using System.Collections.Generic;
    using System.Xml;
    using Game;
    using Utility;
    /// <summary>
    /// 字符串管理器
    /// </summary>
    public class StringConfigManager : Singleton<StringConfigManager>
    {
        //所有字符缓存字典
        private Dictionary<string, string> m_oDicAllStringData;
        public StringConfigManager()
        {
            this.m_oDicAllStringData = new Dictionary<string, string>();
        }
        public void Init()
        {
            this.m_oDicAllStringData.Clear();
            XmlDocument doc = XmlResAdapter.GetXmlDocument(UnityTools.LoadFileText(SystemConfig.StringPath));
            OnLoadStringFinishedEventHandler(doc);
        }
        /// <summary>
        /// 根据字符id取得字符串内容
        /// </summary>
        /// <param name="id"></param>
        public static string GetString(string id)
        {
            return StringConfigManager.singleton.TryGetString(id);
        }
        private void OnLoadStringFinishedEventHandler(XmlDocument doc)
        {
            if (doc != null)
            {
                XmlNode root = doc.SelectSingleNode("root");
                XmlNodeList tableList = root.ChildNodes;
                foreach (var node in tableList)
                {
                    XmlElement ele = (XmlElement)node;
                    string id = ele.GetAttribute("id");
                    string content = ele.InnerText;
                    bool flag = this.m_oDicAllStringData.ContainsKey(id);
                    if (flag)
                    {
                        Debug.Log("字符字典已经包含该字符id");
                    }
                    this.m_oDicAllStringData[id] = content;
                }
            }
        }
        private string TryGetString(string id)
        {
            if (this.m_oDicAllStringData.ContainsKey(id))
            {
                return this.m_oDicAllStringData[id];
            }
            else
            {
                return id;
            }
        }
    }

    然后创建string.xml文件,存放在Resources/Config文件夹下面:

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <ele id="MessageWindow.EMT_NetTryAgain.Title">网络错误</ele>
      <ele id="MessageWindow.EMT_NetTryAgain.Content">您的网络无法连接上服务器,请检查下网络是否良好。</ele>
      <ele id="MessageWindow.EMT_NetTryAgain.TryAgainButton">image 168</ele>
      <ele id="MessageWindow.EMT_NetTryAgain.QuitButton">image 172</ele>
    </root>

    更改MessageWindow里面的代码,将StringConfigManager里面用上。

            //根据不同的消息类型,显示不同的提示消息
            switch (this.m_eMessageType)
            {
                    //如果是重试消息的话
                case EMessageType.EMT_NetTryAgain:
                    this.m_firstButton.normalSprite = StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.TryAgainButton");
                    this.m_secondButton.normalSprite = StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.QuitButton");
                    this.m_title.text = StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.Title");
                    this.m_content.text = StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.Content");
                    break;
                case EMessageType.EMT_ReConnect:
                    break;
                case EMessageType.EMT_None:
                    break;
            }

    对了,在用StringConfigManager之前得先初始化,那么在LOLGameDriver里面初始化。

        void Init()
        {
            WindowManager.singleton.Init();//界面UI初始化
            StringConfigManager.singleton.Init();//字符管理器初始化
        }

    Ok,大功告成,我们运行程序。

    与之前的一模一样,但是我们现在只要改下配置文件里面的字符,程序中的字符也会改变。

    OK,我们接着做,更新消息提示框,还是在MessageWindow里面,我们只需要再添加一个消息类型:EWT_UpdateTip和EWT_UpdateDownload:

    然后再修改MessageWindow里面的代码:

    未完待续。。。。。。

     时隔几日,终于才有时间来写博客。这几日,当然我也没有闲着,也修改了好多代码。所以如果代码中有些步骤错过的话,可以留言给我。

    OK,我们这几日试着发现这样的消息类型,要定到死为止,所以我定了一个总的消息类型:

        /// <summary>
        /// 消息类型
        /// </summary>
        public enum EMessageType
        {
            EMT_None = -1,
            EMT_UpdateDownload, //更新下载提示
            EMT_Double, //两个按钮
            EMT_Tip,     //提示
            EMT_SureTip //确定提示
        }

    确定提示:

    两个按钮:

    仅仅提示:

    还有比较特殊的更新界面提示(其实就是double+多字符Label):

    OK,已经知道了这么多的消息类型,那么我们就实现这些类型的表现:在MessageWindow的ShowMessage里面:

     public void ShowMessage(CEvent evt,EMessageType type,Action<bool> callback = null)
        {
            //如果已经显示了,就直接返回
            if (mVisible && evt.GetParamCount() == 0)
            {
                return;
            }
            this.m_eMessageType = type;
            this.m_actCallBack = callback;
            Show();
            //根据不同的消息类型,显示不同的提示消息
            switch (this.m_eMessageType)
            {
                    //如果是重试消息的话
                case EMessageType.EMT_Double:
                    this.m_firstButton.gameObject.SetActive(true);
                    this.m_secondButton.gameObject.SetActive(true);
                    this.m_centerButton.gameObject.SetActive(false);
                    this.m_firstButton.normalSprite = StringConfigManager.GetString("MessageWindow.EMT_Double.TryAgainButton");
                    this.m_secondButton.normalSprite = StringConfigManager.GetString("MessageWindow.EMT_Double.QuitButton");
                    this.m_title.text = evt.GetParam("title") as string;//StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.Title");
                    this.m_content.text = evt.GetParam("content") as string; //StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.Content");
                    break;
                case EMessageType.EMT_Tip:
                    this.m_frame.spriteName = StringConfigManager.GetString("EMessageType.EMT_Tip.Frame");
                    this.m_firstButton.gameObject.SetActive(false);
                    this.m_secondButton.gameObject.SetActive(false);
                    this.m_centerButton.gameObject.SetActive(false);
                    this.m_title.gameObject.SetActive(false);
                    this.m_content.alignment = NGUIText.Alignment.Center;
                    this.m_content.text = evt.GetParam("content") as string;//StringConfigManager.GetString("EMessageType.EMT_UpdateTip.Content1");
                    break;
                case EMessageType.EMT_SureTip:
                    this.m_frame.spriteName = StringConfigManager.GetString("EMessageType.EMT_Tip.Frame");
                    this.m_firstButton.gameObject.SetActive(false);
                    this.m_secondButton.gameObject.SetActive(false);
                    this.m_centerButton.gameObject.SetActive(true);
                    this.m_title.gameObject.SetActive(false);
                    this.m_content.alignment = NGUIText.Alignment.Center;
                    this.m_content.text = evt.GetParam("content") as string;
                    break;
                case EMessageType.EMT_UpdateDownload:
                    this.m_frame.spriteName = StringConfigManager.GetString("EMessageType.EMT_UpdateTip.Frame");
                    this.m_firstButton.gameObject.SetActive(true);
                    this.m_secondButton.gameObject.SetActive(true);
                    this.m_firstButton.normalSprite = StringConfigManager.GetString("MessageWindow.EMT_UpdateDownload.LookNewButton");
                    this.m_secondButton.normalSprite = StringConfigManager.GetString("MessageWindow.EMT_Double.TryAgainButton");
                    this.m_title.gameObject.SetActive(false);
                    this.m_content.alignment = NGUIText.Alignment.Center;
                    this.m_content.text = string.Format(StringConfigManager.GetString("EMessageType.EMT_UpdateDownload.Content"), evt.GetParam("index"), evt.GetParam("total"), evt.GetParam("fileName"));
                    break;
                case EMessageType.EMT_None:
                    break;
            }

    因为我们消息改了,所以有些组件也需要添加进去,我们重新制作消息UI界面,我们新增一个centerButton:

       private UIButton m_centerButton;//中间按钮

    然后在InitWeight里面添加事件监听:

            this.m_centerButton = this.mRoot.FindChild("Frame/CenterButton").GetComponent<UIButton>();
            EventDelegate.Add(this.m_firstButton.onClick, OnFirstBtn);
            EventDelegate.Add(this.m_secondButton.onClick, OnSecondBtn);
            EventDelegate.Add(this.m_centerButton.onClick, OnFirstBtn);
    
        public void OnFirstBtn()
        {
            switch (this.m_eMessageType)
            {
                //如果是重试消息的话
                case EMessageType.EMT_Double:
                    this.m_actCallBack(true);
                    Hide();
                    break;
                case EMessageType.EMT_None:
                    break;
            }
        }
        public void OnSecondBtn()
        {
            switch (this.m_eMessageType)
            {
                //如果是重试消息的话
                case EMessageType.EMT_Double:
                    this.m_actCallBack(false);
                        Hide();
                    break;
                case EMessageType.EMT_None:
                    break;
            }
        } 

    这里我只写double类型的,以后再来扩充。

    可能有些童鞋发现了,那么消息的内容不是都是不一样吗,我们不能写死了,所以我们要在其他地方传入到这个方法里面赋值。

    那么我们直接用EventCenter.Broadcast是不支持传递参数的,所以我们在ShowMessage传入一个Cevent类的实例,这个类主要是传递值的。也就是在两个类之间传递数值。

    我已经在ShowMessage传入了Cevent类型,所以我们需要到EventCenter里面改下代码:

        static public void SendEvent(CEvent evt)
        {
            Broadcast<CEvent>(evt.GetEventId(), evt);
        }
        static public void SendEvent<T>(CEvent evt, T arg2)
        {
            Broadcast<CEvent, T>(evt.GetEventId(), evt, arg2);
        }
        static public void SendEvent<T,U>(CEvent evt, T arg2,U arg3)
        {
            Broadcast<CEvent, T, U>(evt.GetEventId(), evt, arg2,arg3);
        }
        static public void SendEvent<T, U,V>(CEvent evt, T arg2, U arg3,V arg4)
        {
            Broadcast<CEvent, T, U,V>(evt.GetEventId(), evt, arg2, arg3,arg4);
        }
    

     修改SendEvent方法能带更多的泛型参数。

    OK,那么我们怎么使用,我们先修改下MessageWindow的错误:

    到Init()修改下参数错误:

        public override void Init()
        {
            EventCenter.AddListener<CEvent,EMessageType,Action<bool>>(EGameEvent.eGameEvent_ShowMessage, ShowMessage);      
        }

    你们全部修改完成之后,我们回到LOLGameDriver修改下:

    checkTimeout.AsynIsNetworkTimeout((result) =>
                {
                    //网络良好
                    if (result)
                    {
                        //开始更新检测
                        DoInit();
                    }
                    else //说明网络错误
                    {
                        Debug.Log("网络错误");
                        //开始消息提示框,重试和退出
                        CEvent evt = new CEvent(EGameEvent.eGameEvent_ShowMessage);
                        evt.AddParam("title", StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.Title"));
                        evt.AddParam("content", StringConfigManager.GetString("MessageWindow.EMT_NetTryAgain.Content"));
                        EventCenter.SendEvent<EMessageType, Action<bool>>(evt, EMessageType.EMT_Double, (isOk) =>
                        {
                            if (isOk)
                            {
                                TryInit();//重试
                            }
                            else
                            {
                                Application.Quit();//退出
                            }
                        });
                    }
                });

    先new一个CEvent实例,然后在其中添加两个参数,也就是我们消息的标题和内容。然后调用SendEvent方法。OK,我们在MessageWindow接收到CEvent传递的“title”和“content”两个参数的值,初始化消息框的Label的值。

    OK,我们接着制作其他消息提示框,其实大致步骤是一样的:

    Action<bool> fileDecompress = (finish) => 
            {
                LOLGameDriver.Invoke(() => 
                {
                    EventCenter.Broadcast(EGameEvent.eGameEvent_HideMessage);
                    if (finish)
                    {
                        CEvent evt = new CEvent(EGameEvent.eGameEvent_ShowMessage);
                        evt.AddParam("content", StringConfigManager.GetString("EMessageType.EMT_UpdateTip.Content2"));
                        EventCenter.SendEvent<EMessageType, Action<bool>>(evt, EMessageType.EMT_Tip, null);
                        Debug.Log("正在更新本地文件");
                    }
                    else 
                    {
                        CEvent evt = new CEvent(EGameEvent.eGameEvent_ShowMessage);
                        evt.AddParam("content", StringConfigManager.GetString("EMessageType.EMT_UpdateTip.Content3"));
                        EventCenter.SendEvent<EMessageType, Action<bool>>(evt, EMessageType.EMT_Tip, null);
                        Debug.Log("数据读取中");
                    }
                });
            };
    

    我们重点看看更新消息提示框(其实也一样,那就不重点看看了):

            Action<int, int, string> taskProgress = (total, index, fileName) => 
            {
                LOLGameDriver.Invoke(() => 
                {
                    //正在下载更新文件
                    Debug.Log(string.Format("正在下载更新文件({0}/{1}:{2})", index + 1, total, fileName));
                    CEvent evt = new CEvent(EGameEvent.eGameEvent_ShowMessage);
                    evt.AddParam("index", index + 1);
                    evt.AddParam("total", total);
                    evt.AddParam("fileName", fileName);
                    EventCenter.SendEvent<EMessageType, Action<bool>>(evt, EMessageType.EMT_UpdateDownload, (isOk) =>
                    {
                        if (isOk)
                        {
                            Application.OpenURL("http://www.baidu.com");
                        }
                        else
                        {
    
                        }
                    });
                });
            };

    OK,既然我们能让一个消息界面显示,那么我也需要自动让他消息,那么我们就再加个消息不显示的事件类型,在AddListener里面,直接添加WindowBase父类的Hide方法:

        protected override void OnAddListener()
        {
            EventCenter.AddListener(EGameEvent.eGameEvent_HideMessage, Hide);
        }
        protected override void OnRemoveListener()
        {
            EventCenter.RemoveListener(EGameEvent.eGameEvent_HideMessage, Hide);
        }

    然后在适当的时机调用隐藏消息提示框。

    OK,我这里又要改下,在CheckVersion里面,如果不需要更新的话,就添加执行finished的委托,我忘记加了。

        public void CheckVersion(Action<bool> fileDecompress,Action<int,int,string> taskProgress,Action<int,long,long> progress,Action finished,Action<Exception> error)
        {
            BeforeCheck((result) =>
            {
                if (result)
                {
                    //需要更新
                    Debug.Log("需要更新");
                    EventCenter.Broadcast(EGameEvent.eGameEvent_HideMessage);
                    CheckAndDownload(fileDecompress, taskProgress, progress, finished, error);
                }
                else
                {
                    EventCenter.Broadcast(EGameEvent.eGameEvent_HideMessage);
                    //不需要更新
                    Debug.Log("不需要更新");
                    if (finished != null)
                    {
                        finished();
                    }
                }
            }, () => { error(new Exception("下载版本文件超时!")); });
        }
    

      

    OK,消息界面已经搞一个段落,我们下节开始登陆的逻辑编程,这里就涉及游戏状态机的管理。

     仿LOL项目开发第六天地址链接

  • 相关阅读:
    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结
    085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用
    jQuery UI组件库Kendo UI使用技巧小分享
    Kendo UI ListView模板功能,让Web开发更轻松
    UI组件套包DevExpress ASP.NET Core v20.2新版亮点:全新的查询生成器
    Devexpress WinForms最新版开发.NET环境配置Visual Studo和SQL Server对应版本
    全新的桌面应用数据可视化呈现方式,Sankey Diagram控件你了解多少?
    java中的递归方法
    连接数据库查询 将查询结果写入exce文件中
    java连接mysql数据查询数据
  • 原文地址:https://www.cnblogs.com/CaomaoUnity3d/p/5471621.html
Copyright © 2011-2022 走看看