怎样制作基于Cocos2d-x的SLG游戏-第3章

原创: @涵紫任珊

怎样制作基于Cocos2d-x的SLG游戏-第1章
怎样制作基于Cocos2d-x的SLG游戏-第2章
怎样制作基于Cocos2d-x的SLG游戏-第3章
怎样制作基于Cocos2d-x的SLG游戏-第4章
怎样制作基于Cocos2d-x的SLG游戏-第5章
怎样制作基于Cocos2d-x的SLG游戏-第6章
怎样制作基于Cocos2d-x的SLG游戏-第7章

经过前面两章的学习,我们已经可以掌握了地图的创建和加载,并且可以对它进行缩放,移动等基本的操作了。那么在本章,我们将通过Cocos Studio编辑器快速地制作一款能自动适应多分辨率的UI系统,享受一下Cocos2d-x的GUI系统和Cocos Studio所带来的便捷。

一直以来,如何快速地制作UI是开发游戏中不得不遭遇的一个问题,Cocos2d-x一路经历了1.0时期的固定位置和2.0的相对位置,一直到现在3.0中全新的GUI机制。尽管3.0版本引擎中引进了全新的,且功能强大的GUI机制,但如果要手动编码实现相关GUI的显示和布局问题,这还是将会是一件特别繁琐的事情。好在Cocos Studio对Cocos2d-x新的GUI系统进行了全面的支持,我们可以很方便的利用它来实现UI系统的设计。

result

本章的目标是实现如上图所示的效果(高清截图臣妾做不到,猿媛们请见谅)。选择左下角的购物车按钮会弹出一个购物滚动列表,下面就让我们一起来学习吧。

制作UI界面

开始之前,首先还是简单介绍下Cocos Studio,扫扫盲。Cocos Studio是一套基于Cocos2d-x的免费游戏开发工具集,它能帮助开发者快速创建游戏资源,将大部分繁琐的游戏开发工作使用编辑器来快速制作,进一步帮助游戏开发者减短开发周期、提高开发效率。

由于各个版本的Cocos Studio功能上略有不同,所以开发项目时最好采用对应的版本进行学习。本教程中采用的是Windows版本的Cocos Studio 1.5.0.1,其下载地址可在http://cn.cocos2d-x.org/download中找到。

下载安装好Cocos Studio以后,运行应用程序你将发现Windows版本Cocos Studio中核心的四个编辑器:UI编辑器、动画编辑器、场景编辑器和数据编辑器,它们分别用于处理游戏中的UI界面、动画资源、游戏场景和游戏数据。但因为我们只需要使用Cocos Studio来完成UI界面的制作,所以打开Cocos Studio后,选择UI Editor(UI编辑器)项,新建一个UI工程。下面就让我们一起来创建UI界面吧。

1)首先,因为我们的UI资源是按着1136

640的分辨率来制作的,所以先在快捷菜单栏中设置画布大小为1136

640。如下:

p2

2)接着选择 文件->导入资源 导入所需的资源文件,也可直接将资源拷入UI工程的Resources文件夹目录下,然后刷新资源面板。本教程所使用的资源已共享,可点击这里下载。

3)此时对象结构面板中只有如下的一个根节点。

p3

我们需要设置一下根节点的属性,如下图所示:

p4

其中,Cocos Studio的子控件布局的方式有四种,在图中依次排开,它们分别是:

  1. 绝对布局:子控件的位置由其坐标决定,其优点是布局灵活性大,缺点是在做全屏多分辨率的情况下不太适用。
  2. 相对布局:子控件的位置由其相对于父控件的纵横两个方向的位置决定,它还允许子控件相对于父控件的位置做偏移。
  3. 线性横向布局:线性布局的一种,子控件在父控件上呈平行结构依次排列。
  4. 线性纵向布局:线性布局的一种,子控件在父控件上呈垂直结构依次排列。

因为我们需要制作一款能自动适应多分辨率的界面,所以绝对布局是不可行的,这里需要把子控件布局设置为相对布局,也就是上图中所选择的第二个布局选项。

再者,去掉“交互”项的√勾选,因为UI将位于地图背景的上层,如果我们勾选了交互项,那么地图背景层的触摸事件就将遭到拦截,我们就无法对它做拖动和缩放操作了。交互项的意思简单点说就是此控件是否拦截输入、触摸等消息。

最后,将背景颜色调为无颜色,并勾选“自适应分辨率”项,这样整个根节点大小就会随着屏幕大小的变化而变化了。

4)接下来向场景中拖入一个图片控件,以它为例,我们来看看如何设置子控件的属性,如下图所示:

p5

因为我们需要让图片的大小随着分辨率的变化而变化,所以把尺寸的模式从Auto修改为了Custom,并把图片的尺寸设为它原始尺寸大小(280

82)。这样在1136

640的分辨率下就显示了原始大小。

勾选百分比选框,这样在其他分辨率下,比如480

320下,图片显示的尺寸就变成了((480 / 1136

280)

(320 / 640

82))的大小,保证了显示效果的一致性。但需要说明的是,如果非1136 * 640比例的分辨率下,图片难免会出现拉伸。

将名字属性修改为便于识别的名称,养成良好的习惯。

在控件布局中选择其横向布局为左边,纵向布局为上边,这样图片就会紧贴根节点的左上角了。调整边缘属性可改变图片相对于左上角的位置坐标。

5)同样的方法添加其他控件,注意层级关系,并一定要勾选百分比项。

6)下面我们来制作按下购物车按钮所弹出的商店部分。

首先,向场景中拖入一层容器,命名为panel_shop,控件布局时让它停靠在购物车按钮(button_shop)的左侧,因为shop_button本身就在屏幕的最左下角,所以新建的panel_shop位于屏幕渲染区域之外的。如下图所示:

p6

向panel_shop中添加一个滚动层控件,设置其属性,如下图所示:

p7

这里我们把滚动层的大小设置为了panel_shop的2/3,仅仅时为了后面在程序中好控制它们的显示。把滚动层的布局方式设置为线性纵向布局,同时勾选“交互”项,这样做的原因为了让我们能滚动该滚动层。滚动区域的大小应该比滚动层本身大,这样才能让滚动层滚动起来。所以我们把滚动区域的高调整为800。

接着在滚动层内创建一个如下的panel,并为其添加如下的子控件。

p8

快速复制上图控件并调整位置,清理滚动层的背景颜色,将滚动层的颜色设置为“无颜色”,将panel_shop层的颜色设为白色。

7)这时,改变画布大小试试,如果一切正常,那么这个画布里的几乎所有内容都会根据当前的分辨率进行适配。

你也看到啦,我们说的是几乎,那还有什么不能进行适配啦?比如:字体大小,滚动层滚动区域大小等等,它们对并勾选“自适应分辨率”项是不敏感的,这让人有点头疼,这可能是Cocos Studio存在的一个bug吧。所以为了避免一些不必要的问题,我们把画布大小改为程序中所设置的design resolution,既480*320,同时把滚动层滚动区域大小调整为一个比较合适的大小。

p9

制作完成后勾选滚动层的“裁剪”属性,这样滚动层超出自身区域的内容将不会显示。

8)打开导出对话框,选择导出路径,按默认配置导出资源。

代码中加载

Cocos2d-x 使用UI框架的步骤:

1)Cocos2d-x 导入Cocos Studio的UI编辑器文件(json和资源)
2)编码获取/创建控件,绑定控件
3)使用控件做逻辑处理:比如,按钮、ScrollView等等控件的响应事件。

打开GameScene.cpp添加头文件

#include "cocostudio/CCSGUIReader.h"
#include "ui/CocosGUI.h"

using namespace ui;

编写initUI函数,先简单初始化下游戏UI,如下列代码所示:

void GameScene::initUI()
{
    playerLayout = static_cast(cocostudio::GUIReader::getInstance()->widgetFromJsonFile("Ui/Ui_1.json"));
    addChild(playerLayout, 10);

    // 获取商店层和购物车按钮
    panel_shop = dynamic_cast(playerLayout->getChildByName("panel_shop"));   
    shop_btn = dynamic_cast

按钮是要有响应函数的,又由于它是Widget的一个子类,所以采用的TouchEvent的回调方式。这里所说的TouchEvent响应主要是使用在Widget上的,可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。下面是按钮回调的实现:

void GameScene::menuShopCallback(cocos2d::Ref* pSender, Widget::TouchEventType type)
{
    Size winSize = Director::getInstance()->getWinSize();

    switch (type)
    {
        case Widget::TouchEventType::BEGAN:  // 按下按钮
            // 为shop_btn添加一个缩放效果
            shop_btn->runAction( EaseElasticInOut::create(Sequence::create( ScaleBy::create(0.1f, 2),ScaleBy::create(0.2f, 0.5f), NULL), 0.5f));
            break;
        case Widget::TouchEventType::MOVED:  // 移动按钮
            break;
        case Widget::TouchEventType::ENDED:  // 放开按钮
            if(comeOut == false)  // 弹出
            {
                // 为panel_shop和shop_btn添加一个弹性的移动效果,移动的距离是(panel_shop->getContentSize().width / 3 * 2, 0)个单位。
                panel_shop->runAction( EaseElasticOut::create(MoveBy::create(1, Vec2(panel_shop->getContentSize().width / 3 * 2, 0)), 0.5f));
                shop_btn->runAction( EaseElasticOut::create(MoveBy::create(1, Vec2(panel_shop->getContentSize().width / 3 * 2, 0)), 0.5f));
                comeOut = true;
            }
            else if(comeOut == true) // 缩回
            {
                panel_shop->runAction( EaseElasticOut::create(MoveBy::create(1, Vec2(-panel_shop->getContentSize().width / 3 * 2, 0)), 0.5f));
                shop_btn->runAction( EaseElasticOut::create(MoveBy::create(1, Vec2(- panel_shop->getContentSize().width / 3 * 2, 0)), 0.5f));
                comeOut = false;
            }
            break;

        case Widget::TouchEventType::CANCELED:  // 取消点击
            break;

        default:
            break;
    }

}

效果图:

p10

当商店层和购物车按钮弹出时,如果触碰到了它们范围之外的区域,它们应该缩回。所以,在onTouchesBegan函数中需要添加如下的一段代码。

void GameScene::onTouchesBegan(const std::vector&touches, Event  *event)
{
    Size winSize = Director::getInstance()->getWinSize();
    if(comeOut == true)
    {
        panel_shop->runAction( EaseElasticOut::create(MoveBy::create(1, Vec2(-panel_shop->getContentSize().width / 3 * 2, 0)), 0.5f));
        shop_btn->runAction( EaseElasticOut::create(MoveBy::create(1, Vec2(- panel_shop->getContentSize().width / 3 * 2, 0)), 0.5f));
        comeOut = false;
    }
}

好的,现在我们已经简单的实现了UI的显示了。下一章我们将替换滚动层中的商品项和信息,并拖动商品到地图。

标签: none

?>