UI框架简介(六)

9 篇文章 1 订阅
5 篇文章 0 订阅

大家看了前面的那么多理论代码,相信都对框架里面的东西有一定的掌握了吧!下面我会带着大家一起来开发背包功能。

这里我说一下一般公司开发项目的简要流程哦!首先由策划根据用户等提出各种需求,然后在项目开始前,所有人员会开一个项目分析会,美术人员,策划人员,程序前后端人员。开完会以后,主程搭好框架,然后给我们。项目团队之间的交流一般用svn。然后明确你在框架中开发东西。比如,我们拿到的任务就是开发背包模块。

下面我们就背包模块进行开发:
拿到需求了!我们首先需要拼UI背包面板,拼好以后去存预制物。然后去看框架,看完以后。我们来开发。记住所有的开发都是从数据层入手的!那么我们来创建BagModule类。继承自框架中的BaseProxy 父类。

****************背包模块开发************************
父类没有什么好说的,自己看吧!具体功能在子类呢!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 所有数据的父类
/// </summary>
public class BaseProxy
{

    /// <summary>
    /// 初始化数据
    /// </summary>
    public virtual void Init()
    {

    }

    /// <summary>
    /// 数据接收完后
    /// </summary>
    public virtual void Logout()
    {

    }

    /// <summary>
    /// 注册侦听
    /// </summary>
    public virtual void RegisterListener()
    {

    }

    /// <summary>
    /// 移除侦听
    /// </summary>
    public virtual void RemoveListener()
    {

    }

}

下面我们开发子类,记好了哦!这是数据层的开发哦!

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 管理背包从从服务器接接收的数据和向服务器请求后,服务器做出回应的数据
/// </summary>
public class BagModule : BaseProxy
{
    #region 单例模式
    private static BagModule _instance;

    public static BagModule GetInstance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new BagModule();

            }

            return _instance;
        }

    }

    #endregion

    /// <summary>
    /// 存放接收数据的列表
    /// </summary>
    private List<ItemData> bagList = new List<ItemData>();

    /// <summary>
    /// 构造函数
    /// </summary>
    public BagModule()
    {

    }

    public override void Init()
    {
        this.RegisterListener();
    }

    public override void Logout()
    {
        this.RemoveListener();
    }

    /// <summary>
    /// 侦听服务器发过来的数据
    /// </summary>
    public override void RegisterListener()
    {
        #region 侦听服务器层数据
        //S2C_Bag_AddData告诉全部背包数据的
        //服务器向我们发送信息
        CEventDispatcher.GetInstance().AddEventListener(CEventType.S2C_Bag_SetAllData, OnSetAllData);
        CEventDispatcher.GetInstance().AddEventListener(CEventType.S2C_Bag_RemoveData, OnRemoveData);
        CEventDispatcher.GetInstance().AddEventListener(CEventType.S2C_Bag_AddData, OnSetAddData);

        #endregion

        #region 侦听显示层(View)数据

        CEventDispatcher.GetInstance().AddEventListener(CEventType.Bag_UserItem, SendUseItem);

        #endregion

    }

    /// <summary>
    /// 移除侦听事件
    /// </summary>
    public override void RemoveListener()
    {
        #region 移除侦听服务器层数据
        CEventDispatcher.GetInstance().RemoveEventListener(CEventType.S2C_Bag_SetAllData, OnSetAllData);
        CEventDispatcher.GetInstance().RemoveEventListener(CEventType.S2C_Bag_RemoveData, OnRemoveData);
        CEventDispatcher.GetInstance().RemoveEventListener(CEventType.S2C_Bag_AddData, OnSetAddData);
        #endregion

        #region 移除侦听显示层(View)数据

        CEventDispatcher.GetInstance().RemoveEventListener(CEventType.Bag_UserItem, SendUseItem);

        #endregion


    }

    #region 侦听事件的回调函数

    /// <summary>
    /// 设置所有背包数据
    /// </summary>
    /// <param name="evt"></param>
    private void OnSetAllData(CBaseEvent evt)
    {
        while (bagList.Count > 0)
        {
            bagList.RemoveAt(0);
        }

        bagList = evt.Sender as List<ItemData>;

        //拿到数据然后派发事件 让显示层去更新显示
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.Bag_UpdataData, bagList));
    }

    /// <summary>
    /// 移除数据
    /// </summary>
    /// <param name="evt"></param>
    private void OnRemoveData(CBaseEvent evt)
    {
        for (int i = 0; i < bagList.Count; i++)
        {
            if (bagList[i].itemId == (evt.Sender as ItemData).itemId)
            {
                //bagList.Remove(bagList[i]);
                bagList.RemoveAt(i);
                break;
            }
        }

        //更新数据以后派发事件 让显示层去更新显示
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.Bag_UpdataData, bagList));
    }


    /// <summary>
    /// 添加背包数据
    /// </summary>
    /// <param name="evt"></param>
    private void OnSetAddData(CBaseEvent evt)
    {
        //背包中是否有数据了
        bool isHas = false;

        for (int i = 0; i < bagList.Count; i++)
        {
            //如果找到相等的直接覆盖之前的(注意:服务器推过来的对象ItemData 包含了各种id,num等信息)
            if (bagList[i].itemId == (evt.Sender as ItemData).itemId)
            {
                bagList[i] = evt.Sender as ItemData;
                isHas = true;
                break;
            }
        }

        if (!isHas)
        {
            //注意:服务器推过来的对象ItemData 包含了各种id,num等信息
            bagList.Add(evt.Sender as ItemData);
        }

        //更新数据以后派发事件 让显示层去更新显示
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.Bag_UpdataData, bagList));


    }




    #endregion

    #region  向服务器发送的请求数据(发过去以后,由服务器去做侦听,我, 不需要管,而我们和后端通信的就是这些事件了)

    public void SendGetAllData()
    {
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.C2S_Bag_GetAllData));
    }

    public void SendGetItem(CBaseEvent evt)
    {
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.C2S_Bag_AddItem, evt.Sender.ToString()));
    }

    public void SendUseItem(CBaseEvent evt)
    {
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.C2S_Bag_RemoveItem, evt.Sender.ToString()));
    }

    #endregion
}

数据层开发完了以后,我们的数据都有了。下面我们应该做显示层了吧!因为我们这个简单,所以我们呢!没有C控制层的。下面来看显示层(V)

这里写图片描述

那么我们一起来看这个六大子类中的背包类吧!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using System;
using Newtonsoft.Json;

/// <summary>
/// 背包预制物panel管理类(我们的背包面板是要做成预制物的)
/// </summary>
public class BagPanel : BasePanel
{
    private GameObject bagItem;
    private CanvasGroup canvsGrounp;
    private Button btnClose;
    private Button btnReset;
    private Transform content;
    /// <summary>
    /// 存放创建的BagItem
    /// </summary>
    private List<GameObject> bagItems = new List<GameObject>();

    /// <summary>
    /// 初始化方法
    /// </summary>
    void Awake()
    {
        LoadItem();
        RegisterComponent();
        RegiseterEvent();
    }

    private void RegisterComponent()
    {
        canvsGrounp = GetComponent<CanvasGroup>();
        btnClose = transform.Find("CloseButton").GetComponent<Button>();
        btnReset = transform.Find("ResetButton").GetComponent<Button>();
        content = transform.Find("Scroll View/Viewport/Content");
    }

    /// <summary>
    /// 加载背包里面小item的预制物的
    /// </summary>
    private void LoadItem()
    {
        bagItem = Resource.LoadPrefab("UI/BagItem");
    }

    void Start()
    {

        ////添加侦听事件(背包更新数据事件)
        //CEventDispatcher.GetInstance().AddEventListener(CEventType.Bag_UpdataData, RefreshData);

        ////派发使用item的事件
        //CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.Bag_UserItem, "99"));
        if (canvsGrounp == null)
        {
            //获取CanvasGroup组件
            canvsGrounp = GetComponent<CanvasGroup>();
        }
        //向服务器主动请求数据的
        BagModule.GetInstance.SendGetAllData();
    }

    /// <summary>
    /// 注册侦听的
    /// </summary>
    private void RegiseterEvent()
    {
        btnClose.onClick.AddListener(delegate ()
        {
            UIManager.Instance.PopPanel();
        });

        btnReset.onClick.AddListener(delegate ()
        {

        });

        //侦听一条更新数据的消息,然后做显示
        CEventDispatcher.GetInstance().AddEventListener(CEventType.Bag_UpdataData, OnUpdataData);
    }

    /// <summary>
    /// 处理发送过来的数据的方法
    /// </summary>
    /// <param name="evt"></param>
    private void OnUpdataData(CBaseEvent evt)
    {
        List<ItemData> list = evt.Sender as List<ItemData>;

        //先删除旧的显示对象 方法二:
        //foreach (var item in bagItems)
        //{
        //    Destroy(item.gameObject);
        //}

        for (int i = 0; i < bagItems.Count; i++)
        {
            Destroy(bagItems[i] as GameObject);
        }

        bagItems.Clear();

        foreach (ItemData item in list)
        {
            //content设置父物体
            //Instantiate有多个重载(预制物,父物体)
            GameObject go = Instantiate(bagItem, content);
            BagItem itemData = Util.Add<BagItem>(go);//添加脚本
            itemData.SetData(item);//设置数据
            bagItems.Add(go);//将所有的对象管理起来

        }
    }

    /// <summary>
    /// 复写的父类面板进入时的方法
    /// </summary>
    public override void OnEnter()
    {
        if (canvsGrounp == null)
        {
            canvsGrounp = GetComponent<CanvasGroup>();
            canvsGrounp.alpha = 1;
            canvsGrounp.blocksRaycasts = true;
        }
        else
        {
            canvsGrounp.alpha = 1;
            canvsGrounp.blocksRaycasts = true;
        }


        //缓动动画(利用DoTween插件做的动画)
        Vector3 temp = transform.localPosition;
        temp.x = 600;
        temp.y = 0;
        transform.localPosition = temp;
        transform.DOLocalMoveX(0, 0.5f);//缓动

    }

    /// <summary>
    /// 覆写的父类面板进入时的方法
    /// </summary>
    public override void OnExit()
    {
        canvsGrounp.blocksRaycasts = false;
        //OnComplete后面可以跟一个回调函数
        transform.DOLocalMoveX(600, 0.5f).OnComplete(() => canvsGrounp.alpha = 0);

    }

    /// <summary>
    /// 覆写的父类面板暂停时的方法
    /// </summary>
    public override void OnPause()
    {
        canvsGrounp.blocksRaycasts = false;
    }

    /// <summary>
    /// 覆写的父类面板继续时的方法
    /// </summary>
    public override void OnResume()
    {
        canvsGrounp.blocksRaycasts = true;
    }

}

由于我们的背包离里面有单个的小对象item吧,即背包里面的物品。我们需要再创建一个类。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 背包中临时Item(物品管理类)
/// </summary>
public class BagItem : MonoBehaviour
{
 //item上面的引用
 private ItemData itemData;
    private Button btn;
    private Text itemNum;
    private Text itemName;
    private Image itemIcon;


    // Use this for initialization
    void Awake()
    {

        RegisterComponent();
        RegiseterEvent();

    }

    /// <summary>
    /// 查找组件
    /// </summary>
    private void RegisterComponent()
    {
        itemIcon = transform.Find("itemIcon").GetComponent<Image>();
        btn = transform.Find("itemButton").GetComponent<Button>();
        itemName = transform.Find("itemName").GetComponent<Text>();
        itemNum = transform.Find("itemNum").GetComponent<Text>();

    }

    /// <summary>
    /// 移除侦听
    /// </summary>
    private void RegiseterEvent()
    {
        btn.onClick.AddListener(delegate ()
        {
            CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.Bag_UserItem, itemData.itemId));
        });

    }

    /// <summary>
    /// 设置数据
    /// </summary>
    /// <param name="data"></param>
    public void SetData(ItemData data)
    {
        itemData = data;
        RefreshView();
    }

    /// <summary>
    /// 做显示的方法
    /// </summary>
    private void RefreshView()
    {
        //print("images/equip/" + itemData.itemIcon);
        Sprite sprite = Resource.LoadSprite("images/equip/" + itemData.itemIcon);

        if (sprite == null)
        {
            Debug.LogError("sprite is null !!!");
        }
        itemIcon.sprite = sprite;
        itemName.text = itemData.itemName;
        itemNum.text = itemData.itemNum;
        btn.GetComponent<Image>().sprite = sprite;
    }
}

小item上面的组件。
这里写图片描述

好了!这些就是实战开发背包模块了哦!不懂的话欢迎私聊QQ哦!
希望这些可以帮助到大家哦!

本篇小结:本篇主要想大家讲解了背包模块是如何开发出来的哦!这只是六大模块中的一个小部分模块哦!大家要是有时间的话,就去开发其他模块练练手嘛!如果没有策划的话,建议自己去体验当前比较火的手游王者荣耀哦!它里面的功能还是比较多的!还有一点,作为程序员的我们,有空一定要多多体验游戏,因为你体验的多了,才会有新的见识哦!好了,就写这么多吧!马上就要春节了,也是我们的休息时间了哦!最后感谢大家的阅读,祝大家新年快乐哦!不懂的地方欢迎私聊QQ哦!QQ在前面博客中有哦!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值