Sample地址https://github.com/chukong/CocoStudioSamples/tree/master/DemoLogin
各位小伙伴们,sample讲解将会全部制作,目前仓库中还是2.2.0版本,我这里会尽快将新版本提交到github分支,如果需要直接看正在改的版本,可以到https://github.com/geron-cn/CocoStudioSamples查看。
以后的每一次版本发布都会及时更新该samples。感谢大家对cocostudio的支持
一、了解目标
作为第一讲,我们的这个示例较为简单,仅仅是一个注册页面,包含的元素也是非常基础的部分。下图是程序运行的效果:
二、创建一个新的UI项目
打开cocostudio编辑器,选择UI Editor
在菜单栏中选择“文件”—》“创建新项目”(快捷键:Ctrl+N)

在弹出的界面设置项目的名称和项目的存放路径。
三、引入资源
开始制作之前,第一步是添加所需要用的资源。
添加资源有两种主要方式,一种是直接将资源拖放到资源版本内,另一种是试用导入。
资源可以打开示例工程的DemoLogin_editor文件夹获取。

四、创建控件
一个登陆界面由背景图层和一些文本标签、输入框、按钮等组成。一般是按照从下到上的顺序创建控件。
第一步是给根节点设置贴图,首先是选在对象结构中选中根节点,并打开属性面板,然后在资源面板中找到Register.png,并拖拽到属性面板中的文件属性框内。

接下来就是上层的控件了,根节点是默认已经存在的一个层,我们想要再添加新的控件就需要在编辑器的左测列表层找到对应的控件类型并拖放到渲染面板内。
这里控件的主要类型如图所示

按照顺序逐个添加控件
直接拖到渲染区后大致是这个样子
五、配置属性
从上图看到可能跟我们想要的有较大的差距,别担心,只是编辑器给我们提供了默认的资源及属性。我们需要一一修改。
这里说一下自定义字体,自定义字体是一种通过.fnt字体文件来显示文字的控件,一般和.fnt文件配套的还有一个图片,该图片会包含所有字体的样式。因为可以自由绘制每一个文字的样式,所以显示效果比普通的文本效果要好很多。但是因为需要每个字都要有对应的纹理,所以一般用于显示英文字符或者少量明确的汉字。
Sample示例中已经包含一些fnt字体文件,我们可以选择一个.Fnt文件拖放到属性面板“FNT字体文件”属性框内,并修改文本属性为需要的文本。
注意:设置文本时一定要设置fnt文件中已经包含的字符,否则控件将无法识别。
配置字体文件及文本后,可以开始调整控件的大小,选中控件,拖拽四个顶点即可调整控件的大小,不过这里调整的是缩放属性,而不是控件本身的大小。
下面是输入框的配置,这个较为简单,直接在属性框修改属性即可。

其中开启密码属性是用于设置是否显示掩码,一般用户密码的输入。文本属性是输入框中的字符,一般都设置为空。占位文本是给用户的一个提示,指导用户输入需要的内容。
自此 主体的控件已经做好,还有两个按钮和一个复选框。下面是一个按钮的属性框。

一个按钮拥有三个状态:正常、按下、禁用。通常我们需要给每一种状态都要设置一个纹理资源。当然如果明确不需要的话也可以不设置。
复选框一般用于表示状态,可以理解为开关,不过他的属性要稍微复杂些:

不过这里除了选中状态外都用的是同一个纹理,因为有些属性并不是必须的,通常可以通过图片的处理,仅使用“底图资源”和“标示图选中”两个图即可描述开关两个状态。
完成后如下图所示:

完成显示界面的配置后,还有一项很重要的配置:勾选“交互选项”
所有需要有和用户进行交互的控件都勾选“交互”这个属性,如本示例中的按钮、文本框、复选框。
注意:这里的“交互”属性并不能实现事件,如果要添加自己的事件处理一定要在程序中添加事件。
六、导出
编辑完成后选择“菜单”—》“文件”—》“导出项目”
这里使用默认配置即可,导出后的文件在我们创建的项目“Export”文件夹下。
默认每一个画布导出后会独立占用一个文件夹。除了引用到的资源外还有一个导出的.json文件。该json配置文件记录了整个画布的所有信息,导出后请勿随意改动。
七、创建一个新的cocos2dx项目
使用以下脚本创建一个新的cocos2d-x项目:
pythoncreate_project.py -project 项目名称 -package 包名 -language 语言
(关于项目环境的配置请参考http://www.cocoachina.com/bbs/read.php?tid=161597)
将编辑器中导出的文件放置到新建项目的Resources文件夹内。
八、创建一个新的场景类
在cocos2d-x工程目录的Class文件夹下创建一个新的场景类(.h文件和.c++文件),取名为CocosGUIExamplesRegisterScene,然后添加到VS工程内。
在AppDelegate.cpp文件里添加新建CocosGUIExamplesRegisterScene类的类引用,并将boolAppDelegate::applicationDidFinishLaunching()方法尾部的场景实现方法替换为新的类:
// create a scene. it’s an autorelease object
//自动生成的HelloWorld场景。
// CCScene *pScene = HelloWorld::scene();
//自定义场景
CocosGUIExamplesRegisterScene*pScene = new CocosGUIExamplesRegisterScene();
pScene->autorelease();
// run
pDirector->runWithScene(pScene);
九、实现程序
CocosGUIExamplesRegisterScene.h
#ifndef __TestCpp__CocosGUIExamplesRegisterScene__
#define __TestCpp__CocosGUIExamplesRegisterScene__
#include "cocos2d.h"
#include "cocos-ext.h"//引入cocos扩展库,使用cocostudio部分必须添加该引用
//通过宏函数添加cocos的命名空间
USING_NS_CC;
USING_NS_CC_EXT;
using namespace gui;//添加GUI命名空间,ui控件在cocos2d-x 2.2.2版本开始使用新的命名空间
class CocosGUIExamplesRegisterScene : public CCScene
{
public:
CocosGUIExamplesRegisterScene(bool bPortrait = false);
~CocosGUIExamplesRegisterScene();
virtual void onEnter();
virtual void onExit();
// 关闭按钮的触摸事件回调函数,点击关闭按钮时会调用这个函数
void menuCloseCallback(CCObject* pSender, TouchEventType type);
//输入框的事件回调函数
void textFieldEvent(CCObject* pSender, TextFiledEventType type);
protected:
//存储根节点的两个全局变量
TouchGroup* m_pUILayer;
Layout* m_pLayout;
};
#endif /* defined(__TestCpp__CocosGUIExamplesRegisterScene__) */
CocosGUIExamplesRegisterScene.cpp
#include "CocosGUIExamplesRegisterScene.h"
CocosGUIExamplesRegisterScene::CocosGUIExamplesRegisterScene(bool bPortrait)
: m_pUILayer(NULL)
, m_pLayout(NULL)
{
CCScene::init();
}
CocosGUIExamplesRegisterScene::~CocosGUIExamplesRegisterScene()
{
}
void CocosGUIExamplesRegisterScene::onEnter()
{
CCScene::onEnter();
//创建一个TouchGroup用于存放ui界面
m_pUILayer = TouchGroup::create();
m_pUILayer->scheduleUpdate();
addChild(m_pUILayer);
// 从配置文件中解析出UI界面,并添加到m_pUILayer
m_pLayout = dynamic_cast<Layout*>(GUIReader::shareReader()->widgetFromJsonFile("cocosgui/gui_examples/DemoLogin/DemoLogin.json"));
m_pUILayer->addWidget(m_pLayout);
//从UI中通过控件名称查找到第三个输入框,并添加事件监听
TextField* comfirm_textfield = static_cast<TextField*>(m_pUILayer->getWidgetByName("confirm_TextField"));
comfirm_textfield->addEventListenerTextField(this, textfieldeventselector(CocosGUIExamplesRegisterScene::textFieldEvent));
//从UI中通过控件名称查找到关闭按钮,并添加事件监听
Button* close_button = static_cast<Button*>(m_pUILayer->getWidgetByName("close_Button"));
close_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesRegisterScene::menuCloseCallback));
}
//退出场景函数,用于清理资源
void CocosGUIExamplesRegisterScene::onExit()
{
m_pUILayer->removeFromParent();
SceneReader::sharedSceneReader()->purge();
GUIReader::shareReader()->purge();
cocos2d::extension::ActionManager::shareManager()->purge();
CCScene::onExit();
}
//关闭按钮的回调函数
void CocosGUIExamplesRegisterScene::menuCloseCallback(CCObject* pSender, TouchEventType type)
{ //判断触摸事件的类型,如果是TOUCH_EVENT_ENDED触摸结束就关闭当前程序
if (type == TOUCH_EVENT_ENDED)
{
//调用Director的结束方法
CCDirector::sharedDirector()->end();
//判断系统平台是否是ios平台,如果是则调用exit(0)方法,该方法是ios系统专用的退出函数。
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
}
//输入框回调函数
void CocosGUIExamplesRegisterScene::textFieldEvent(CCObject *pSender, TextFiledEventType type)
{
switch (type)
{ //如果是开始编辑事件
case TEXTFIELD_EVENT_ATTACH_WITH_IME:
{
TextField* textField = dynamic_cast<TextField*>(pSender);
//判断是否是第三个输入框
if (strcmp(textField->getName(), "confirm_TextField") == 0)
{//将整个视图向上移动25%
CCMoveBy* moveBy = CCMoveBy::create(0.1f, ccp(0, textField->getContentSize().height * 2.5));
m_pLayout->runAction(moveBy);
}
}
break;
//如果是结束编辑事件
case TEXTFIELD_EVENT_DETACH_WITH_IME:
{
TextField* textField = dynamic_cast<TextField*>(pSender);
if (strcmp(textField->getName(), "confirm_TextField") == 0)
{//将整个视图向下移动25%
CCMoveBy* moveBy = CCMoveBy::create(0.1f, ccp(0, -textField->getContentSize().height * 2.5));
m_pLayout->runAction(moveBy);
}
}
break;
default:
break;
}
}


