cocos2d-x使用有半年多时间,想来去年这时候还在写游戏服务器程序,不得不感慨变化很大。
这半年时间对2d游戏客户端开发也越来越熟悉,视野也变得更加开阔,就拿游戏的UI开发来说,最早学习cocos2d-x的时候,是在代码里面写UI,后来写了一个简单的UI编辑器,用在一个音乐游戏中,效果还可以;再后来接触cocosbuilder,效率就更高了。
然而,过几天去新公司,项目是做一个ARPG游戏,对UI的要求更高,cocosbuilder也显得力不从心,端游里面,用CEGUI和mygui的很多,而且这两者都非常强大,不过它们和ogre联系太紧密,如果想在cocos2d-x里面使用此二者,要做的工作会比较大,我目前已经将CEGUI的源代码移植到cocos2d-x的ios环境中,编译链接没问题,然而却需要写一个ogre的渲染接口,由于对glsles语言不是很熟,一时就放下了。
然而也因此产生了一个想法,那就是提供一套GUI接口以及与之兼容的cocosbuilder、cegui、mygui的xml解析接口扩张。
想到了就能做到,我花了大概一天的时间写了一个简单而自认为比较好的雏形,暂时命名为CCGUI,这个雏形的标准如下:
(1)采用树状结构,所有GUI控件继承自Widget类,该Widget类派生自TouchNode类,TouchNode派生自CCNode和CCTargetedTouchDelegate,TouchNode的作用是注册和销毁touch事件。
Widget是一个具有touch功能的方形,虽然派生自CCNode,但是Widget内部有自己的树结构,这样不至于依赖CCNode的一些属性,自成一家。
(2)解决触摸优先级问题,所见即所得,显示在上层的Widget优先级更高,用户不用自己设置优先级。
(3)解决触摸后窗口前置问题,Widget在接受touch事件后处于激活状态,可以将窗口前置到最上层。
(2)和(3)结合在一起能够完成cegui这种GUI所能完成的最重要的窗口与窗口之前的层次问题,这也是本雏形核心部分之一。
(4)touch事件在底层设计上脱离CCTargetedTouchDelegate的控制,而完全是另外一种机制,这种机制是这样的:根节点root由WidgetManager产生,设置触摸优先级为CCGUI的最低优先级,普通GUI控件的优先级均为Normal级别,这样root会在CCGUI的节点里面最后响应touch事件,所有GUI节点都会响应touch事件,在响应时会向WidgetManager注册,在root节点响应时,计算当前哪个GUI节点获得焦点,此时才真正调用该GUI节点的touch事件,这里不妨说成是二次响应。
(5)整个设计干净利落,没有多余的东西,GUI层的节点非常易于控制与touch回调,Widget类进一步组合与派生,非常容易支持TextBox、ScrollView、ItemBox等控件。
(6)采用string类型name为唯一id,虽然是字符串,但是优化下效率应该不会成为瓶颈,好处是非常便于开发者调用。
目前已经完成了几个简单的控件TextBox、ScrollView、ListBox等,支持CocosBuilder的ccb文件解析,明天再花一天时间应该能够将之前的cocosbuilder UI结构全部替换成这套新的雏形结构。
现在我将这部分代码开源出来(https://github.com/dansen/ccgui),希望对cocos2d-x GUI系统实现感兴趣的同学有所帮助。
CCGUI有志于成为cocos2d-x的cegui、mygui的解析框架,这样不用花精力去写编辑器,嘎嘎!!
本人菜鸟一枚,这里说要支持cegui、mygui自然有些自夸,仅仅算一个愿景吧^_^。
最后吐槽下cocosbuilder的几个问题:
(1)通过tag得到节点,是一个比较头疼得问题,两个字,麻烦。
(2)一直觉得CCMenu是个傻乎乎的设计,最蛋疼的是CCMenuItemImage不能添加子节点(尼玛我要在这上面加点文字、图片啥的折腾死),一个字,烦,
(3)支持控件少,适合小游戏开发,给了一个ScrollView,没有列表滚动条等控件,寒酸。
(4)C++里面加一个touch回调不容易,在lua里面注册回调也不容易,哎
本人作为一个极简主义者,对于这些问题能忍这么久也不容易,今天写此博文也算吐吐气,回头还得继续忍着。