注册 登录
主题 : Cocos2d-x3.2教程——【我所认识的Cocos2d-x】四、Cocos2d-x项目—UI管理器篇
级别: 新手上路
状态: 连续签到 - [7天]
UID: 339298
精华: 0
发帖: 47
可可豆: 173 CB
威望: 140 点
在线时间: 114(时)
注册时间: 2014-07-07
最后登录: 2016-03-15
0 楼:  发表于: 2015-01-08 12:40    发自: Web Page
来源于 教程分享 分类

Cocos2d-x3.2教程——【我所认识的Cocos2d-x】四、Cocos2d-x项目—UI管理器篇   

管理提醒: 本帖被 偶尔e网事 执行加亮操作(2015-01-09)
    上一节,我们简单的了解了整个游戏程序应该需要的知识,那么本节,我们就详细的了解下UI管理器,UI管理器顾名思义,就是管理UI的。前几节和大家探讨过了,因为个人经历原因,我喜欢直接使用Layer,而不是Scene,所以本篇文章的切换页面都是用Layer实现,而不是Scene。
    本篇所用的Cocos2d-x版本为:Cocos2d-x 3.2
    编译器版本VS2013







Cocos2d-x3.2教程——【我所认识的Cocos2d-x】
四、Cocos2d-x项目—UI管理器篇
上一节我们已经大致的搭建出了基础工程,那么下面我们开始一些详细的设置。我们先将需要的组件全部加载进来。
  


然后通过解决方案将库文件引入进来。
  


这里面注意下 libuimanager 是我个人自己写的 UI管理器库 同学们自己的项目里是没有的!
  


然后在我们的工程属性里进行部署



将包含目录设置下


注意$(EngineRoot)cocos\editor-support\uimanager 是我的UI管理器路径 同学们的项目不必填写



然后再通用属性里进行一下引用



编译一下就能看见熟悉的HelloWorld了!
当我们项目搭建完毕,准备开始着手写代码的时候,我们势必要想到一个问题,谁来管理我们这些零散的业务类呢?我个人的第一个项目是没有主程的,小伙伴们都是各自顾及自己的业务,一个劲奋勇拼搏,最后的结果就导致,在整合业务类的时候,各业务类横飞,业务类调用复杂,代码复用率极低且不利于管理,给人的感觉就是我们自己在跟自己打仗。这个时候,我们就需要主程或我们自己跟小伙伴们规范,并设计管理器进行管理。
一、基础页面类 BaseLayer
那么如何设计基础的页面类呢?
首先,我们就先分析一下基本需求:
1、 基本的公用头文件引用
2、 基本的公用函数接口
A、初始化
B、 接收数据
C、 逻辑加载
D、逻辑返回
3、 具体代码


我记得在第二节中就跟大家基础的介绍了下MVC的架构方式,由于严谨的架构MVC方式需要大量的时间,请原谅我,在这里简单的搭建一下。
好了基础页面类 BaseLayer 已经搭建好了,那么我们的UI管理器要怎么弄呢?
二、UI管理器类UIManager
1、UI管理器的基础搭建
第一步,都是先分析,分析我们需要什么!
A、对所有BaseLayer派生出的业务类进行管理
B、派生出的业务类可以执行切换页面动画的基本诉求
C、对资源可实行异步加载
D、有公用的Loading页面
E、有公用的禁止触摸层
F、可以任意获取到管理器中的业务类
G、设置主管理器监听接口
H、可返回指定逻辑内容
I、……
好了,基本上我们大概的列出了这几条。
那么我们先看眼代码
我会逐一为大家讲解



首先,作为管理器,我们一定要单例出来!作为UI唯一的管理器存在!
然后按照代码顺序我为同学们一一解读:
//初始化;
staticUIManager *getGameUIManager();
静态创建一个UI管理器 方便我们随时能找到这个唯一的UI管理器
static UIManager* GameUIManager;
//初始化单例;
复制代码
  1. UIManager *UIManager::getGameUIManager(){       if (GameUIManager == nullptr)
  2.        {
  3.               GameUIManager = new UIManager();
  4.               GameUIManager->loadData();
  5.        }
  6.        return GameUIManager;
  7. }

//读取数据;
voidloadData();
通过静态单例调用 进行一些初始化的设置,可以包括心跳设置,支线程管理等
复制代码
  1. //初始化;
  2. void UIManager::loadData()
  3. {
  4.        //UI集合;
  5.        m_vAllLayerList.clear();
  6.        //资源集合;
  7.        m_vAllResList.clear();
  8.        //主管理初始化;
  9.        m_pGameMain = nullptr;
  10.        //逻辑初始化;
  11.        m_UILogic = nullptr;
  12.        //Loading初始化;
  13.        m_pLoadIngLayer = nullptr;
  14.        //开关初始化;
  15.        m_bLoadIng = true;
  16.        //支线程开关初始化;
  17.        m_bImgLoad = false;
  18.        //资源引用计数初始化;
  19.        m_iTextureIndex = 0;
  20.        //开启一个时间监听;
  21.        this->schedule(schedule_selector(UIManager::ThreadOver));
  22. }

//加入UI层;
voidaddUILayer(BaseLayer* t_paddUI, vector<string>   m_vResList);
管理器加载一个业务类,并对资源执行异步加载,这里尚未对pList文件加以支持。其实这个地方无非就是加载一个Layer,只不过我们是会对它进行一些处理,包括资源的异步加载,UI的压入及管理等。
复制代码
  1. //加入UI层;
  2. voidUIManager::addUILayer(BaseLayer* t_paddUI, vector<string> m_vResList)
  3. {
  4.        //资源纹理初始化;
  5.        m_vAllResList.clear();
  6.        //资源索引初始化;
  7.        m_iTextureIndex = 0;
  8.        //资源集合赋值;
  9.        m_vAllResList = m_vResList;
  10.        //UI压入;
  11.        t_paddUI->retain();
  12.        m_vAllLayerList.push_back(t_paddUI);
  13.        //开启读取页面;
  14.        LoadingLayerStart();
  15.        //是否开启支线程;
  16.        if (m_vAllResList.size() > 0)
  17.        {
  18.               //支线程;
  19.               thread t_Accep(ImgLoadThread, (void*)this);
  20.               //线程分离;
  21.               t_Accep.detach();
  22.        }
  23.        else
  24.        {
  25.               //异步加载完毕;
  26.               imageLoadedOver();
  27.        }
  28. }

//重载加入UI层;
voidaddUILayer(BaseLayer* t_paddUI);
管理器加载一个业务类
复制代码
  1. voidUIManager::addUILayer(BaseLayer* t_paddUI)
  2. {
  3.        //资源纹理初始化;
  4.        m_vAllResList.clear();
  5.        //资源索引初始化;
  6.        m_iTextureIndex = 0;
  7.        //UI压入;
  8.        t_paddUI->retain();
  9.        m_vAllLayerList.push_back(t_paddUI);
  10.        //开启读取页面;
  11.        LoadingLayerStart();
  12.        //异步加载结束;
  13.        imageLoadedOver();
  14. }

//执行动画;
voidExecutionAnimation(Gif_Action_Index t_iNum);
新加载的业务类要执行的切换动画,我们BaseLayer里专门设置了动画索引变量,管理器就会根据动画索引变量去执行页面的切换效果,像淡入淡出,像左出右进等基础效果
//切换UI;
voidSwitchingLayer();
业务类切换函数,主要进行对业务UI类进行切换时的管理,像引用计数,变量变更等
//删除AT0;
voidDelATLayer0();
删除上一个业务,就是删除上一个业务Layer,每次的新的业务Layer都会被放入后面,那么前面的就是以前的业务,所以删除索引0.
复制代码
  1. voidUIManager::DelATLayer0()
  2. {
  3.        BaseLayer* temp = m_vAllLayerList.at(0);
  4.        temp->autorelease();
  5.        this->removeChild(temp, true);
  6.        m_vAllLayerList.erase(m_vAllLayerList.begin() + 0);
  7. }

//显示UI;
voidadd_UI();
业务加载完毕,显示通知主管理器进行绘制处理,因为我们管理器操作的是基类BaseLayer,所以并不会调用的真正的业务类,所以这里我做了个小处理,扔回主管理器,让主管理器进行UI业务的处理,包括显示函数;
复制代码
  1. //显示UI;
  2. void UIManager::add_UI()
  3. {
  4.        //关闭读取页面;
  5.        LoadingLayerEnd();
  6.        auto temp = m_vAllLayerList.at(0);
  7.        (m_pGameMain->*m_UIDraw)(temp,(int*)temp->getClassIndex());
  8. }

//显示UI;
voidadd_UI_2();
业务加载完毕,显示通知主管理器进行绘制处理;
//设置总管理器连接;
voidsetMainManager(Ref* listener);
设置主管理器地址
//加载逻辑;
voidLoadUILogic(SEL_CallFuncND method, SEL_CallFuncND drawthod);
设置主管理器逻辑及绘制地址
//返回逻辑;
voidReturnLogic(int classIndex);
返回逻辑函数,通知主管理执行下一业务等;
//异步加载;
voidimageLoaded(Texture2D* texture);
异步加载方法
//异步加载完毕;
voidimageLoadedOver();
异步加载完毕
//开启读取页面;
voidLoadingLayerStart();
开启Loading页面
//关闭读取页面;
voidLoadingLayerEnd();
关闭Loading页面
//支线程静态函数;
staticvoid ImgLoadThread(void* data);
支线程静态方法,切记支线程不能调用主线程UI,否则程序必然崩溃!
//支线程结束;
voidThreadOver(float dt);
支线程结束,通知主线程进行下一步骤
//获取层;
BaseLayer*getLayerByName(string LayerName);
通过业务名称获取到相应的业务类
//设置Loading层;
CC_PROPERTY(Layer*,m_pLoadIngLayer, LoadIngLayer);
//Loading层开关;
CC_SYNTHESIZE(bool,m_bLoadIng, LoadingOpen);
//支线程开关;
CC_SYNTHESIZE(bool,m_bImgLoad, ImgLoadOpen);

2、UI管理器的基础设置
前文经常提到,我已经习惯的将Scene当作管理器来用,而且还是作为唯一的Scene,这个地方其实,我们可以根据需求来做,比如如果您的游戏是基于物理系统来做,那您就搭载一个createWithPhysics,怎么样运用都可以。
我创建了一个主管理器类GameMain,并替代里HelloWorld作为第一加载场景。



我们的主管理器,不仅仅要加载UI管理器,还要对数据管理器、网络管理器、数据库管理器等做管理,本节仅仅是对UI管理器的设置。

 



那么图片里出现的宏 其实就是我简单的对UI管理器的封装而已



好了,基础的UI管理器设置完毕了,同学肯定还在云雾之中没有明白吧,那么我们就写几个测试业务进行一下实践吧!
3、 UI管理器实践:
我们先写个业务类,根据BaseLayer派生出的 Tset_Layer_1


我们继承了并重载了 showUI函数
那么我们看看cpp是怎么实现的


就是一个基础的HelloWorld变异版,只不过添加了一些UI管理器调用方法,方便进行业务之间的跳转和数据上的交互等。
那么开始编译吧!!



OK出现了,那么我们就试验下吧!



效果还不错!下一节我将会更为详细的介绍一下,UI管理器的使用方法及一些注意事项,请原谅我对UI管理器不开源,因为我觉得我写的还是不够好,需要用更多的时间去完善,而且目前只支持VS2013编译器且不向下兼容,在这里给大家道歉了!
UI管理器下载地址
本部分内容设定了隐藏,需要回复后才能看到

[ 此帖被东扬冬阳在2015-01-08 14:37重新编辑 ]

级别: 新手上路
状态: 连续签到 - [81天]
UID: 264659
精华: 0
发帖: 5
可可豆: 414 CB
威望: 232 点
在线时间: 37(时)
注册时间: 2013-10-08
最后登录: 2015-03-23
1 楼:  发表于: 2015-01-08 15:21    发自: Web Page
顶一下
修行者
级别: 新手上路
状态: 连续签到 - [7天]
UID: 339298
精华: 0
发帖: 47
可可豆: 173 CB
威望: 140 点
在线时间: 114(时)
注册时间: 2014-07-07
最后登录: 2016-03-15
2 楼:  发表于: 2015-01-08 15:26    发自: Web Page
回 1楼(吴畏zen) 的帖子
这篇有点乱哈
级别: 新手上路
状态: 连续签到 - [81天]
UID: 264659
精华: 0
发帖: 5
可可豆: 414 CB
威望: 232 点
在线时间: 37(时)
注册时间: 2013-10-08
最后登录: 2015-03-23
3 楼:  发表于: 2015-01-08 15:33    发自: Web Page
回 2楼(DemonVV) 的帖子
形乱神不乱!还是那个深深的VV啊!
修行者
级别: 新手上路
UID: 408101
精华: 0
发帖: 44
可可豆: 179 CB
威望: 179 点
在线时间: 88(时)
注册时间: 2014-11-28
最后登录: 2017-06-27
4 楼:  发表于: 2015-01-08 18:08    发自: Web Page
赞赞赞赞,lz继续啊~
级别: 新手上路

UID: 421211
精华: 0
发帖: 55
可可豆: 101 CB
威望: 91 点
在线时间: 150(时)
注册时间: 2014-12-24
最后登录: 2017-11-14
5 楼:  发表于: 2015-01-08 21:02    发自: Web Page
弱弱说一句,论坛有代码高亮功能啊,其实直接插入代码片段比较好吧····
截图还麻烦。
级别: 侠客

状态: 连续签到 - [19天]
UID: 153389
精华: 0
发帖: 105
可可豆: 271 CB
威望: 189 点
在线时间: 233(时)
注册时间: 2012-07-09
最后登录: 2017-09-06
6 楼:  发表于: 2015-01-08 21:06    发自: Web Page
我只是来看看的
欢迎来访 http://blog.csdn.net/nmjkl001
级别: 新手上路
状态: 连续签到 - [7天]
UID: 339298
精华: 0
发帖: 47
可可豆: 173 CB
威望: 140 点
在线时间: 114(时)
注册时间: 2014-07-07
最后登录: 2016-03-15
7 楼:  发表于: 2015-01-09 09:03    发自: Web Page
回 5楼(acros) 的帖子
我才知道。。。。。
级别: 侠客
状态: 连续签到 - [7天]
UID: 307774
精华: 0
发帖: 113
可可豆: 321 CB
威望: 311 点
在线时间: 244(时)
注册时间: 2014-04-14
最后登录: 2016-04-01
8 楼:  发表于: 2015-01-09 09:53    发自: Web Page
顶顶顶
级别: 新手上路
UID: 424394
精华: 0
发帖: 6
可可豆: 6 CB
威望: 6 点
在线时间: 7(时)
注册时间: 2015-01-03
最后登录: 2015-12-24
9 楼:  发表于: 2015-01-13 17:54    发自: Web Page
h写的很好顶。。。。。
描述
快速回复

关注本帖(如果有新回复会站内信通知您)

发帖、回帖都会得到可观的积分奖励。查看论坛积分规则

按"Ctrl+Enter"直接提交
    顶部