仿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的鏈接。

相關文章
相關標籤/搜索