仿LOL项目开发第七天

仿LOL项目开发第七天

                                                                     by 草帽php

不知不觉已经写到了第七篇这种类型的博客,可是回过头看看以前写的,发现都只能我本身能看懂。数据库

我相信在看的童鞋云里雾里的,由于我基本上没怎么详细讲一个脚本怎么用?可是大家能够本身看下代码,很快你就知道怎么用!之后也能够用到本身的项目中。缓存

因此说阅读别人的代码很是重要,由于大家从中发现他们代码的优势和缺点。服务器

OK,废话很少说,咱们继续上节课,上节课咱们已经封装本身的UI框架,可是还少个没讲,可能有些童鞋也会遇到报错,怎么解决?框架

在Window下新建一个UILib,而后里面新建一个脚本:ide

WidgetFactory:测试

 

using UnityEngine;
using System.Collections.Generic;
namespace UILib
{
    public class WidgetFactory
    {
        /// <summary>
        /// 查找节点下全部的UI组件,缓存到字典里面
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="parent"></param>
        /// <param name="dicAllUIObjects"></param>
        public static void FindAllUIObjects(Transform trans, IXUIObject parent, ref Dictionary<string, XUIObjectBase> dicAllUIObjects)
        {
            int i = 0;
            while (i < trans.childCount)
            {
                Transform child = trans.GetChild(i);
                XUIObjectBase component = child.GetComponent<XUIObjectBase>();
                if (!(null != component))
                {
                    goto IL_85;
                }
                if (component.GetType().GetInterface("IXUIListItem") == null)
                {
                    if (dicAllUIObjects.ContainsKey(component.name))
                    {
                        Debug.Log(component.name);
                        Debug.LogError("m_dicId2UIObject.ContainsKey:" + WidgetFactory.GetUIObjectId(component));
                    }
                    dicAllUIObjects[component.name] = component;
                    component.Parent = parent;
                    goto IL_85;
                }
                else 
                {
                    Debug.Log("fdsfd");
                }
            IL_8F:
                i++;
                continue;
            IL_85:
                WidgetFactory.FindAllUIObjects(child, parent, ref dicAllUIObjects);
                goto IL_8F;
            }
        }
        /// <summary>
        /// 取得该组件所在的id(包含父亲节点的id)
        /// </summary>
        /// <param name="uiObject"></param>
        /// <returns></returns>
        public static string GetUIObjectId(IXUIObject uiObject)
        {
            string result;
            if (null == uiObject)
            {
                result = string.Empty;
            }
            else
            {
                string text = uiObject.CacheGameObject.name;
                IXUIListItem iXUIListItem = uiObject as IXUIListItem;
                if (iXUIListItem != null)
                {
                    text = iXUIListItem.Id.ToString();
                }
                while (null != uiObject.Parent)
                {
                    uiObject = uiObject.Parent;
                    string arg = uiObject.CacheGameObject.name;
                    iXUIListItem = (uiObject as IXUIListItem);
                    if (null != iXUIListItem)
                    {
                        arg = iXUIListItem.Id.ToString();
                    }
                    text = string.Format("{0}#{1}", arg, text);
                }
                result = text;
            }
            return result;
        }
    }
}

这个脚本主要是用来找UI的子物体用的。动画

OK,咱们正式进入到LoginWindow的完善。咱们知道这个界面分为两块,一个是登录,一个选择服务器。网站

咱们先来写登录的逻辑。ui

能够看到这个界面分为3个组件:

1.用户名输入框

2.密码输入框

3.确认登录按钮

因此咱们在LoginWindow初始化这些组件:

而后在InitWidget()里面初始化这些定义的组件:

这里的名字是我本身去的好比Login/UserNameInput,大家能够本身取本身的名字。

Login是LoginWindow下面的子物体,而后UserNameInput是Login下面的子物体,咱们用/来区分紫武器。

OK,当咱们点击确认登录按钮的时候,确定须要一个登录事件给这个按钮,因此如今咱们来写这个事件监听。

而后咱们来编写OnLoginSumbit方法,主要处理一些登录逻辑的事情。

 

    public void OnLoginSumbit(GameObject go)
    {
        string username = this.m_Input_UsernameInput.value;
        string password = this.m_Input_PasswordInput.value;
        //若是用户名或者密码为空的话,就显示提示消息
        if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
        {
            CEvent evt = new CEvent(EGameEvent.eGameEvent_ShowMessage);
            evt.AddParam("content", StringConfigManager.GetString("MessageWindow.EMT_SureTip.LoginNullUsernameOrPassword"));
            EventCenter.SendEvent<EMessageType, Action<bool>>(evt, EMessageType.EMT_SureTip, (isOk) => 
            {
                EventCenter.Broadcast(EGameEvent.eGameEvent_HideMessage);
            });
        }
        LoginCtrl.singleton.Login(username, password);
    }

能够看到咱们搞了一个当肯定消息提示,若是用户名和密码为空的话。

而后为了符合类的单一职责,咱们把全部的逻辑放在LoginCtrl中。

新建文件夹取名为Controller,而后在里面新建一个LoginCtrl类:(我忘记以前是否是讲过这个类,若是有讲过这个类,由于我过久以前写的,都忘记了,读者自行改过)。

在写这个逻辑以前,咱们先来想下咱们登录进去在选择服务器,因此登录这个验证并无进入到游戏服务器中,由于咱们根本没有选择服务器,怎么能进到服务器中呢?

因此我认为就只是网页简单的验证用户名密码,而后选择服务器以后才真正的进入到游戏服务器。

因此这个登录的逻辑步骤是:

1.开启协程访问一个网站,这个网站验证用户名和密码。(因此我决定用PHP来写这个验证)

2.若是验证经过以后,而后发送服务器列表给客户端,客户端再进入到选择服务器界面。

3.客户端选择某个服务器,而后进入到这个游戏服务器。

因此首先,我在网站文件夹下面新建一个check.php文件:

这个脚本就是经过数据库链接,而后进行验证,这里我简单一点,我就直接都放回成功。由于咱们只是作下测试,不用每步都详细。

因此我这里只是简单放回一个success字符串,而后在LoginCtrl中:

 

 public void Login(string account, string password)
    {
        this.username = account;
        this.password = password;
        LOLGameDriver.Instance.StartCoroutine(CheckUserPass());
    }
    IEnumerator CheckUserPass()
    {
        if (string.IsNullOrEmpty(this.username) || string.IsNullOrEmpty(this.password))
        {
            yield break;
        }
        WWW www = new WWW("http://127.0.0.1/LOLGameDemo/check.php");
        bool success = false;
        for (int i = 0; i < 10; i++)
        {
            yield return new WaitForSeconds(0.5f);
            if (www.isDone)
            {
                if (string.IsNullOrEmpty(www.error))
                {
                    if (!string.IsNullOrEmpty(www.text))
                    {
                        if (www.text == "success")
                        {
                            //加载服务器信息
                            SystemConfig.LoadServerList();
                            success = true;
                            EventCenter.Broadcast(EGameEvent.eGameEvent_ShowSelectServerList);
                        }
                        else 
                        {
                            //登录失败
                        }
                    }
                }
                else 
                {
                    this.m_log.Error(www.error.ToString());
                }
                break;
            }
        }
        if (www != null)
        {
            www.Dispose();
            www = null;
        }
        //若是不成功
        if (!success)
        {
 
        }
        yield break;
    }

不知读者注意到没有,若是登录成功的话,咱们就开始加载服务器列表。

 

//加载服务器信息
SystemConfig.LoadServerList();

因此咱们回到SystemConfig里面:

 

/// <summary>
    /// 加载服务器列表
    /// </summary>
    public static void LoadServerList()
    {
        try
        {
            List<ServerInfo> servers;
            var url = GetCfgInfoUrlByName("ServerList");
            string xmlSerList = "";
            if (!string.IsNullOrEmpty(url))
            {
                xmlSerList = DownloadMgr.Instance.DownLoadHtml(url);
            }
            servers = LoadXMLText<ServerInfo>(xmlSerList);
            if (servers.Count != 0)
            {
                ServerList = servers;
            }
            for (int i = 0; i < ServerList.Count; i++)
            {
                if (ServerList[i].id == LocalSetting.SelectedServer)
                {
                    SelectedServerIndex = ServerList[i].id;
                    break;
                }
            }
        }
        catch (Exception e)
        {
            m_log.Error(e.ToString());
        }
    }

 

 

    /// <summary>
    /// 根据名字取得服务端配置信息Url
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static string GetCfgInfoUrlByName(string name)
    {
        string result = "";
        foreach (var item in CfgInfoList)
        {
            if (item.name == name)
            {
                result = item.url;
                break;
            }
        }
        return result;
    }

而后咱们到Cfg.xml文件添加这个url=>id是1,名字是ServerList:

 

<?xml version="1.0" encoding="utf-8"?>
<root>
  <cfg>
    <id>0</id>
    <name>version</name>
    <url>http://127.0.0.1/LOLGameDemo/ServerVersion.xml</url>
  </cfg>
  <cfg>
    <id>1</id>
    <name>ServerList</name>
    <url>http://127.0.0.1/LOLGameDemo/ServerList.xml</url>
  </cfg>
</root>

而后咱们添加4个游戏服务器,分别是电信2个(type为0),联通两个(type为1):

 

<?xml version="1.0" encoding="utf-8"?>
<root>
  <list>
    <id_i>0</id_i>
    <name_s>艾欧尼亚</name_s>
    <type_i>0</type_i>
    <flag_i>0</flag_i>
    <text_s>fe</text_s>
  </list>
  <list>
    <id_i>1</id_i>
    <name_s>战争学院</name_s>
    <type_i>0</type_i>
    <flag_i>0</flag_i>
    <text_s>csc</text_s>
  </list>
  <list>
    <id_i>2</id_i>
    <name_s>黑色玫瑰</name_s>
    <type_i>1</type_i>
    <flag_i>0</flag_i>
    <text_s>greger</text_s>
  </list>
  <list>
    <id_i>3</id_i>
    <name_s>洛克萨斯</name_s>
    <type_i>1</type_i>
    <flag_i>0</flag_i>
    <text_s>greger</text_s>
  </list>
</root>

因此咱们回到LoginWindow中,添加该事件:

 

    protected override void OnAddListener()
    {
        EventCenter.AddListener(EGameEvent.eGameEvent_ShowSelectServerList, ShowSelectServer);
    }

 

    protected override void OnRemoveListener()
    {
        EventCenter.RemoveListener(EGameEvent.eGameEvent_ShowSelectServerList, Show);
    }

在写ShowSelectServer方法以前,咱们得先定义选择服务器界面组件:

 

    #region 选择服务器界面
    private UIPanel m_Panel_Select;//选择服务器界面总体Panel
    private UIButton m_Button_Select;//确认选择按钮
    private UIButton m_Button_LeftButton;
    private UIButton m_BUtton_RightButton;
    private UIButton m_Button_ServerListButton;//服务器列表按钮
    private XUIList m_List_Dianxin;
    private XUIList m_List_Wangtong;
    private XUISprite m_Sprite_IconBG;
    private XUISprite m_Sprite_ServerName;
    private XUISprite m_Sprite_Icon;
    private XUILabel m_Label_ServerName;
    private XUILabel m_Label_NetworkSpeed;//测试速度Label
    #endregion

InitWeight:

 

        this.m_Button_ServerListButton = this.mRoot.FindChild("Select/Button/ServerListButton").GetComponent<UIButton>();
        this.m_Button_Select = this.mRoot.FindChild("Select/Button/SelectButton").GetComponent<UIButton>();
        this.m_Panel_Select = this.mRoot.FindChild("Select").GetComponent<UIPanel>();
        this.m_List_Dianxin = this.mRoot.FindChild("Select/ServerList/Table/Dianxin/DianxinGrid").GetComponent<XUIList>();
        this.m_List_Wangtong = this.mRoot.FindChild("Select/ServerList/Table/Wangtong/WangtongGrid").GetComponent<XUIList>();
        this.m_Sprite_IconBG = this.mRoot.FindChild("Select/Signal/IconBG").GetComponent<XUISprite>();
        this.m_Sprite_Icon = this.mRoot.FindChild("Select/Signal/IconAnim").GetComponent<XUISprite>();
        this.m_Sprite_ServerName = this.mRoot.FindChild("Select/Signal/Name/ServerNameIcon").GetComponent<XUISprite>();

OK,初始化好界面后,咱们回过头写ShowSelectServer:

 

/// <summary>
    /// 显示选择服务器界面
    /// </summary>
    public void ShowSelectServer()
    {
        if (this.m_Panel_Select != null)
        {
            if (this.ShowServerList())
            {
                //服务器列表按钮的sprite替换
                if (this.m_bShowServerList)
                {
                    this.m_Button_ServerListButton.normalSprite = "image 378";
                }
                else 
                {
                    this.m_Button_ServerListButton.normalSprite = "image 383";
                }
                this.m_Panel_Select.enabled = true;
                GameObject serverList = this.m_Panel_Select.transform.FindChild("ServerList").gameObject;
                //serverList.
                serverList.SetActive(this.m_bShowServerList);
                //若是显示服务器列表面板,播放偏移动画
                if (this.m_bShowServerList)
                {
                    serverList.transform.localPosition = new Vector3(14, 0, 0);
                    TweenAlpha.Begin(serverList, 1, 1);
                    TweenPosition.Begin(serverList, 1, Vector3.zero);
                }
            }
            else 
            {
                Debug.LogError("服务器列表尚未初始化");
            }
        }
    }

 

  

 /// <summary>
    /// 显示服务器列表
    /// </summary>
    public bool ShowServerList()
    {
        if (this.m_bHasLoadedServerList)
        {
            return true;
        }
        if (SystemConfig.ServerList != null)
        {
            this.m_selectedServerId = SystemConfig.SelectedServerIndex;
            this.m_lastSelectServerId = SystemConfig.SelectedServerIndex;
            int indexDianxin = 0;
            int indexWangtong = 0;
            foreach (var serverInfo in SystemConfig.ServerList)
            {
                IXUIListItem serverItem;
                switch (serverInfo.type)
                {
                    case 0:
                        if (serverInfo.flag == (int)ServerType.Recommend)
                        {
                            this.m_reDianxinServerId = serverInfo.id;
                        }
                        if (indexDianxin < this.m_List_Dianxin.Count)
                        {
                            serverItem = this.m_List_Dianxin.GetItemByIndex(indexDianxin);
                        }
                        else
                        {
                            serverItem = this.m_List_Dianxin.AddListItem();
                        }
                        if (serverItem != null)
                        {
                            serverItem.SetText("ServerName",serverInfo.name);
                            serverItem.SetVisible(true);
                            serverItem.TipParam = new TipParam
                            {
                                Tip = serverItem.Tip
                            };
                            serverItem.Id = serverInfo.id;
                        }
                        else
                        {
                            serverItem.SetVisible(false);
                        }
                        indexDianxin++;
                        break;
                    case 1:
                        if (serverInfo.flag == (int)ServerType.Recommend)
                        {
                            this.m_reWangtongServerId = serverInfo.id;
                        }
                        if (indexWangtong < this.m_List_Wangtong.Count)
                        {
                            serverItem = this.m_List_Wangtong.GetItemByIndex(indexWangtong);
                        }
                        else
                        {
                            serverItem = this.m_List_Wangtong.AddListItem();
                        }
                        if (serverItem != null)
                        {
                            serverItem.SetText("ServerName", serverInfo.name);
                            serverItem.SetVisible(true);
                            serverItem.TipParam = new TipParam 
                            {
                                Tip = serverItem.Tip
                            };
                            serverItem.Id = serverInfo.id;
                        }
                        else
                        {
                            serverItem.SetVisible(false);
                        }
                        indexWangtong++;
                        break;
                }
            }
            this.m_bHasLoadedServerList = true;
            return true;
        }
        else 
        {
            return false;
        }
    }

  

    #region 变量定义
    private bool m_bShowServerList = false;//是否显示服务器列表
    private bool m_bHasLoadedServerList = false;//是否已经加载过服务器列表
    private int m_selectedServerId = -1;
    private int m_lastSelectServerId = SystemConfig.SelectedServerIndex;
    private int m_reDianxinServerId = -1;//电信推荐服务器id
    private int m_reWangtongServerId = -1;//网通推荐服务器idn
    #endregion

而后在InitWeight中,让m_Button_ServerListButton监听显示服务器列表和不显示的事件监听:

 

UIEventListener.Get(this.m_Button_ServerListButton.gameObject).onClick = (x) => { this.m_bShowServerList = !this.m_bShowServerList; ShowSelectServer(); };

还有咱们点击某个服务器,得把那个服务器的id,记录下来,因此咱们仍是注册一个事件:

 

this.m_List_Dianxin.RegisterListOnClickEventHandler(new ListOnClickEventHandler(this.OnServerListItemClick));

 

/// <summary>
    /// 服务器某个被点击
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    private bool OnServerListItemClick(IXUIListItem item)
    {
        if (null == item)
        {
            return false;
        }
        this.m_selectedServerId = item.Id;
        ServerInfo info = SystemConfig.GetServerInfoById(this.m_selectedServerId);
        bool active = true;
        if (info.flag == (int)ServerType.Close || info.flag == (int)ServerType.Maintain)
        {
            active = false;
        }
        ShowServerSignal(active, info);
        return true;
    }
    /// <summary>
    /// 播放动画
    /// </summary>
    /// <param name="bActive"></param>
    /// <param name="info"></param>
    private void ShowServerSignal(bool bActive,ServerInfo info)
    {
        if (bActive)
        {
            if (info.id == 0)
            {
                this.m_Sprite_Icon.SetSprite("image 967", "Atlas/SelectAtlas/SelectServerAtlas");
                this.m_Sprite_ServerName.SetSprite("image 975");
            }
            else 
            {
                this.m_Sprite_Icon.SetSprite("image 1015", "Atlas/SelectAtlas/SelectServerAtlas");
                this.m_Sprite_ServerName.SetSprite("image 1012");
            }
            if (this.m_Sprite_IconBG != null)
            {
                this.m_Sprite_IconBG.PlayFlash(false);
                this.m_Sprite_ServerName.Alpha = 0f;
                this.m_Sprite_Icon.Alpha = 0f;
                TweenAlpha.Begin(this.m_Sprite_ServerName.gameObject, 0.8f, 1f);
                TweenAlpha.Begin(this.m_Sprite_Icon.gameObject, 0.8f, 1f);          
            }
        }
    } 

 

 

 OK,大体就是这么多的代码,具体步骤:

1.若是选择服务器Panel不激活的话,就显示服务器列表,而后激活。

2.注册一些按钮的事件

3.记录下来选择的服务器id

而后咱们点击选择按钮,就发送这个服务器id给游戏网关服务器,网关服务器就把用户链接到这个游戏服务器中。

下节课,咱们就开始进入游戏服务器链接,固然这里就涉及到NetworkManager的编写,主要是TCp的链接。

相关文章
相关标签/搜索