触控科技代理的ARPG手游《武尊》一直有很多忠实玩家。作为页游,武尊获得了相当不俗的成绩,是手游上一次重大突破。
我们知道此类游戏在开发时经常遇到一个问题:界面多,手机屏幕小,无法很好的布局UI。但是《武尊》却处理的很好,UI布局合理,界面直观简洁。熔炉系统是其中的特色系统之一,它用到了“标签”对UI进行分区处理,如图左右两侧均有标签栏,通过点击标签实现多UI有序切换。下面就跟小编一起学习如何用Cocos Studio完成这项工作吧!
、
一、制作游戏所需的UI
我们使用的是Cocos Studio for Mac 1.0 Beta版,Mac版本将UI、动画、场景编辑器合而为一,在游戏开发时根据需要选择资源,灵活使用。本次我们所做的UI界面大致分为三部分:标签栏、背景层、每个标签对应的功能层。
标签组是独立的层,而每一个标签对应的熔炉玩法分别对应单独层,即标签组内相互关联,玩法容器层各自独立。每个熔炉都是单独的panel,为了方便查看,制作时我们将背景色设置为蓝色半透明。
当编辑完UI单元后,我们可以用Cocos Studio很快拼出初始界面效果。也就是将一些在初始状态下需要显示的控件摆放到位,如图中的熔炉以及标签组。最后只需将层容器的背景色透明度改为0,就可以在模拟器(截图中的小窗口)里看到真实效果,如下图:
二、在项目中运用:
本次我们使用的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);
}
}
}
|
自此已经完成了所有的功能,赶快自己动手试试吧!
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
|