触控科技代理的ARPG手游《武尊》一直有很多忠实玩家。作为页游,武尊获得了相当不俗的成绩,是手游上一次重大突破。

        我们知道此类游戏在开发时经常遇到一个问题:界面多,手机屏幕小,无法很好的布局UI。但是《武尊》却处理的很好,UI布局合理,界面直观简洁。熔炉系统是其中的特色系统之一,它用到了“标签”对UI进行分区处理,如图左右两侧均有标签栏,通过点击标签实现多UI有序切换。下面就跟小编一起学习如何用Cocos Studio完成这项工作吧!

1406078700764442.png


一、制作游戏所需的UI 

我们使用的是Cocos Studio for Mac 1.0 Beta版,Mac版本将UI、动画、场景编辑器合而为一,在游戏开发时根据需要选择资源,灵活使用。本次我们所做的UI界面大致分为三部分:标签栏、背景层、每个标签对应的功能层。

1406078733994297.png

标签组是独立的层,而每一个标签对应的熔炉玩法分别对应单独层,即标签组内相互关联,玩法容器层各自独立。每个熔炉都是单独的panel,为了方便查看,制作时我们将背景色设置为蓝色半透明。

当编辑完UI单元后,我们可以用Cocos Studio很快拼出初始界面效果。也就是将一些在初始状态下需要显示的控件摆放到位,如图中的熔炉以及标签组。最后只需将层容器的背景色透明度改为0,就可以在模拟器(截图中的小窗口)里看到真实效果,如下图:

1406078796632376.png


二、在项目中运用

本次我们使用的Cocos2dx 3.2 RC0, 通过Cocos2d-Console的cocos.py脚本创建工程:“你的Cocos2d-x 3.2 RC0路径”+\tools\cocos2d-console\bin>cocos.pynew -d ../../../projects -l cpp -p com.cocosstudio.wuzhunui WuzhunUITest,如果使用cpp项目,可以参考《给新建的Cocos2d-x 3.0rc0 的Win32工程添加Cocos Studio库》来加入对Cocos Studio相关库的引用。

完成类库的引用后,我们直接在默认的HelloWorldScene类里实现所有的内容。

首先在头文件中添加以下引用及命名空间:

1
2
3
#include "CocoStudio.h"
#include "ui\CocosGUI.h"
using namespace ui;

创建一个全局变量以及方法定义:

1
2
3
private:
    Node* rooNode;
    void touchEvent(Ref*pSender, Widget::TouchEventType type);


接下来就是最关键的工作了:

第一步是将编辑器中编辑的画面显示到游戏画面中:

1
2
3
4
5
6
7
8
9
//添加一个游戏背景
auto sprite =Sprite::create("background.png");
// position the sprite on thecenter of the screen
sprite->setPosition(Vec2(visibleSize.width/2+ origin.x, visibleSize.height/2 + origin.y));
// add the sprite as a child tothis layer
this->addChild(sprite, 0);
//读取导出的json文件,并将编辑器中的画面添加到游戏界面
rootNode =cocostudio::timeline::NodeReader::getInstance()->createNode("wzui_1/wzui_1.json");
this->addChild(rootNode,0);

    

第二步需要为标签组里的每一个button添加事件响应:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//遍历node下的节点
 for (int i = 0; i <rootNode->getChildrenCount(); i++)
   {
       Node* child = rootNode->getChildren().at(i);
       Button * childeBtn ;
       //因为getchilden获取的都是子节点,不会遍历,所以先要找到负责管理按钮的层容器
       if (child->getTag()==176)
       {
           Widget * btnGroup =(Widget*)child;
           //遍历查找button并添加事件
            for (int j = 0; j < 7; j++)
            {
                 Button * childeBtn=(Button*)Helper::seekWidgetByTag(btnGroup,j+18);
                 childeBtn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::touchEvent,this));
            }
         }
    }


需要注意的是,目前新版本的编辑器的根节点还是Node*对象,且所有的控件均是直接添加到根节点的,所以查找的时候需要先遍历根节点去查找对应的层。有个很简便的解决方法:编辑时添加一个层容器作为根节点,这样每次使用时只需通过rootNode->getChildren().at(0)取出这个UI根节点就可以像以前一样使用了。


下面是对按钮的响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
if (type ==Widget::TouchEventType::ENDED)
    {
        //获取button 的tag 是18到25
        Button *senderBtn =(Button*)pSender;
        intbtnTag=senderBtn->getTag();
        //panel层是tag=31开始到37
        //遍历所有的子节点
        for (int i = 0; i <rootNode->getChildrenCount(); i++)
         {
             Node* child = rootNode->getChildren().at(i);
             //移出屏幕
             for (int j = 0; j < 7; j++)
             {         
                 if (child->getTag()==j+31)
                {
                    child->setPosition(-500,64);
                 }
             }
             //移动对应的layer,如果不能看到效果,要注意渲染层级是否正确
             if (child->getTag()==btnTag-18+31)
             {
                 child->setPosition(159,64);
             }
         }
    }

 

自此已经完成了所有的功能,赶快自己动手试试吧!

1406079287357140.gif


Lua版本实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
local function creatMainUI() 
local rootNode = ccs.NodeReader:getInstance():createNode("res/wzui_1/wzui_1.json") 
--点击处理方法 
local children = rootNode:getChildren() 
local function touchEvent(sender, eventType) 
      if eventType == ccui.TouchEventType.ended then 
         for i= 1,tonumber(rootNode:getChildrenCount()) do 
                    local child  = children 
                    for j = 0,6 do 
                        if child:getTag() == j+31 then 
                            child:setPosition(-500,64) 
                        end 
                    end 
                    if child:getTag() == sender:getTag()-18+31 then 
                        child:setPosition(159,64) 
                    end 
                end 
            end 
        end 
        --添加事件 
        for i= 1,tonumber(rootNode:getChildrenCount()) do 
            local child = children 
            if child:getTag() == 176 then 
                for j =0,6 do 
                    local childBtn = ccui.Helper:seekWidgetByTag(child,j+18) 
                    if childBtn~= nill then 
                        childBtn:addTouchEventListener(touchEvent) 
                    end 
                end 
            end 
        end 
        return rootNode 
    end