一步一步CocosBuilder(1)

  • 本帖最后由 young40 于 2012-12-29 05:32 编辑 *

CocosBuilder是Cocos2d系列的配套开源工具,最新的版本是3.0a, 也是我们这个系列文章所采用的版本. CCB(CocosBuilder简称)目前只有OS X版本, 没有Windows的版本, 而且源代码也是用Objective-c, 估计移植难度会比较大. 我想这个也是其不够流行的原因吧.如果你是CCB的熟客,那么你一定会记得CCB v2.x以前版本附带的例子. 而CCB v3.0采用了一个叫做CocosDragonJS的例子, 主要是展示CCB的Javascript的调用能力. 我虽然很喜欢JS, 但是正在学习2d-x, 又很想学好, 所以还是打好基础, 学好原滋原味的2d-x才好, 以后换用无论是Html5, 还是JS, Lua, 心里才会觉得踏实. 我无论C++,还是2d-x都是新手,又是第一次想正儿八经的写博客文章, 难免有很多错误, 还望各位看客踊跃拍砖.这次的目的是基本实现原来v2.0中的例子. 我采用的2d-x的版本是:cocos2d-2.1beta3-x-2.1.0, 以OS X版本为主, 以sample目录下的HelloCpp为基础改进. CCB的版本是v3.0alpha0.本文的目标是基本实现将CCB整合进Mac OS X版本的项目中.首先将2d-x源代码中sample目录下的HelloCpp目录重命名为TestCocosBuilder.并使用CocosBuilder创建新项目文件在其Resources文件夹中. 还需要将项目需要的图片资源放入Resources目录中. 具体可以参见我打包后的整体项目文件.还可以参见文末的目录树说明.贴下Xcode项目的目录,如果添加extensions应该逐个添加,否则可能会遇到编译错误,有可能会把其他平台文件错误添加进来.

做完这些准备工作后, 我们接下来按步来讲解.1.首先编辑下AppMacros.h, 修改以下代码AppMacros.h

static Resource smallResource  =  { cocos2d::CCSizeMake(480, 320),   "resources-iphone" };
static Resource mediumResource =  { cocos2d::CCSizeMake(1024, 768),  "resources-ipad"   };
static Resource largeResource  =  { cocos2d::CCSizeMake(2048, 1536), "resources-ipadhd" };

这一段主要是修改HelloCpp默认的资源目录, 配合CCB的发布路径.同时可以将原来几个目录中文件分别移入对应目录. 2.添加一个新类MainScene如下MainScene.h

#ifndef __HelloCpp__MainScene__
#define __HelloCpp__MainScene__

#include "cocos2d.h"
#include "cocos-ext.h"

class MainScene
: public cocos2d::CCLayer //从CCLayer派生
{
public:
    static cocos2d::CCScene* scene();
};

#endif /* defined(__HelloCpp__MainScene__) */

MainScene.cpp

#include "MainScene.h"

USING_NS_CC;
USING_NS_CC_EXT;

CCScene* MainScene::scene()
{
    CCScene *scene = CCScene::create();

    CCNodeLoaderLibrary *lib = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); //生成一个默认的Node Loader

    CCBReader *reader = new CCBReader(lib); //用node load lib 初始化一个ccb reader

    CCNode *node = reader->readNodeGraphFromFile("MainScene.ccbi", scene); //从ccbi文件中加载node

    reader->release(); //注意手动释放内存

    if (node!=NULL)
    {
        scene->addChild(node); //将node 添加到scene中
    }

    return scene;
}
  • 本帖最后由 young40 于 2012-12-29 05:40 编辑 *

上一篇我们建立了基本的工作环境, 这一次我们将基本实现例子中的HelloCocosBuilder.

###注意
这两天纠结了一个问题. 我发现按照上次的配置来实现例子, 图片的大小怎么都和例子中的搭配不上. 后来动用CCB的源代码才看出端倪.
CCB v3.0加入了一个resources-auto的目录, 在发布的时候, 会自动缩放图片到对应的分辨率去. 因为图片的分辨率不合适(初步目测), 我们暂时不使用这功能. 请大家将上一篇文章
中的resources-auto文件夹下图片移到父目录ccb-source下面. 这个也解释了为什么resources-auto有非图片文件会导致CCB崩溃的原因.

#####1
在CCB中打开MainScene.ccb,按delete键删除已经存在的几个Sprite.
#####2
添加一个CCLayerGradient到屏幕, 如果有问题的话, 可以参见下文档. 选中该节点, 我们可以在右侧看到他的属性, 常规的属性有比如位置, 大小, 锚点, 缩放, 旋转, 标签.
我们现在将其设置为大小为100%x100%的大小, 即满屏.
#####3
从左侧的文件中将burst.png拖入屏幕, 也可以使用工具栏添加然后再选择属性Sprite frame.
可以在节点树上双击该节点给其重命名, 我们将该节点命名为CCSprite-burst, 便于识别.
同样我们将其中心的设置到屏幕中心50%x50%, 缩放到2.5倍.
然后将Blend src, Blend dst 都设置为One, 好吧, 我暂时还不知道这个Blend是什么东西. 有知道的朋友不妨在评论中告诉我下, 或者参考资料.
大概是透明之类的东西吧.
#####4
然后我们再添加一个CCParticleSystemQuad粒子系统, 就是工具栏的那个Fx按钮.
将其位置设为最下居中, 在最下边Particle Texture设置为ccbParticleSnow.png效果,粒子系统还是很复杂的,估计能单独讲很久了. 这里就不再展开了.
#####5
logo-icon.png拖入屏幕, 放在左上角合适位置, 并将其缩放到0.5. 节点重命名为CCSprite-logo-icon.
接下来就是动画的制作了.选中节点, 可以在菜单栏中Animation => Insert KeyFrame找到插入Framekey的各种快捷键.或许我们需要记熟他们.
首先让我们给Timeline设置下时间.双击时间可以编辑, 我们输入00:03:00, 就是3秒钟. 后面最后一位是帧数, 每秒30帧.
按下小三角可以展开当前节点的各种KeyFrame.
拖动时间轴游标到1秒10帧,按下键盘S, 可以插入一个Scale类型的KeyFrame, 这时将当前节点Scale属性改为0.
然后继续拖动时间轴游标到2秒10帧, 再插入一个Scale KeyFrame, 并将Scale属性改为0.5. 这时点击播放按钮, 可以看到logo会蹦出来.
然后在紫色条上点击右键, 可以看到动作菜单, 我们选择Bounce Out, 这个时候再点击播放, 就可以看到logo蹦出的时候会有一个弹震的效果.
再来说明两点, 紫色条设置不同的动作, 可以看到上面会有一点阴影变化, 可以帮助我们快速确认设置的是什么动作.
如果不小心加多了KeyFrame, 那么可以点击选择KeyFrame, 然后点击delete键删除.
还有需要注意的是, 如果游标不在KeyFrame的点上, 那么此时无法编辑该节点属性, 移动到相应的KeyFrame点即可.
#####6
然后依法炮制, 将logo.png加入, 你可以给其设置想要的动画效果.
#####7
我们再添加一个CCLabelBMFont, 字体设置为markerfelt24shadow.fnt.Label的内容设置为"Hello Cocos2d-x!!!", 然后调整下位置, 换个喜欢的颜色.
#####8
我们再添加一个CCControlButton, Title设置为Menu & Item.
然后再分别设置State Normal, State Highlighted的Sprite frame为btn-test-0.png btn-test-1.png.
然后再设置下弹出效果.
将这个节点再复制5份, 对齐. 再分别设置下Title和弹出效果.设置对齐的时候可能会比较麻烦. 可以从标尺那里拉出几条线, 用于对齐.将该对齐线拉出显示区域即可删除.
{ img /upload/2012-12/ccb-sbs-2-001.png }
#####9
最后将左右的两片叶子加入屏幕, 设置个动画即可.
然后将CCB项目发布一下, 在Xcode里面将项目运行一下. 就可以看到效果了.

:Q:Q:Q:Q:Q:Q

贴进来格式全乱了…

#####10
我们接下来研究文件和类的绑定, 控件和变量的绑定, 以及事件和函数的绑定.
我们在CCB中将根节点的Custom class设置为MainScene.
我们在Xcode中打开MainScene.h, 给MainScene增加一个新的函数CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(MainScene, create);.
最后的代码应该如下:

class MainScene
: public cocos2d::CCLayer
{
public:
    static cocos2d::CCScene* scene();
    
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(MainScene, create);
};

然后在MainScene.h中添加一个新类MainSceneLayerLoader代码如下:

class MainSceneLayerLoader : public cocos2d::extension::CCLayerLoader
{
public:
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(MainSceneLayerLoader, loader);
protected:
    CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(MainScene);
};

如果需要探究的话, 可以点开相应的函数定义. 也都是些简单的工作.
吐槽下, 这些名字真的是太难记. 可能需要多熟悉下, 搞清楚其原理了才好.

然后我们在MainScene.cpp中添加一行注册将ccb文件和类绑定起来.

CCNodeLoaderLibrary *lib = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary();
lib->registerCCNodeLoader("MainScene", MainSceneLayerLoader::loader());

然后运行下, 确保没有错误.
这几行代码, 就是ccb文件和类绑定的最简模式了.

#####11
接着我们研究下控件和变量的绑定.
我们先在CCB中给CCLabelBMFont添加一个Doc root var类型的绑定mLabelText.
一个需要注意的地方就是CCB v3.0alpha似乎无法将jsControlled设置为false, 所以可能需要手工打开MainScene.ccb将其改为false.

	<key>jsControlled</key>
	<false/>

然后在Xcode中给MainScene增加一个从CCBMemberVariableAssigner的继承并实现其虚函数. 并且添加相应的变量.

class MainScene
: public cocos2d::CCLayer
, public cocos2d::extension::CCBMemberVariableAssigner
{
public:
    MainScene();
    ~MainScene();
    
    static cocos2d::CCScene* scene();
        
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(MainScene, create);
    
    virtual bool onAssignCCBMemberVariable(cocos2d::CCObject* pTarget, const char* pMemberVariableName, cocos2d::CCNode* pNode);
    
private:
    cocos2d::CCLabelBMFont *mLabelText;
};

MainScene.cpp中需要添加的是:

MainScene::MainScene()//构造函数
: mLabelText(NULL)
{}

MainScene::~MainScene()//析构函数中释放内存不能忘
{
    CC_SAFE_DELETE(mLabelText);
}

bool MainScene::onAssignCCBMemberVariable(cocos2d::CCObject *pTarget, const char *pMemberVariableName, cocos2d::CCNode *pNode)
{
    CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "mLabelText", CCLabelBMFont*, this->mLabelText);
    
    return true;
}

需要注意的是, 由于绑定较晚, 所以无法在init函数中使用变量mLabelText.
#####12
接下来我们研究事件和函数的绑定.
在CCB中找到Menu & Item这个CCControlButton, 并设置其Selector为onButtonTest.Target设置为Document root.
这里需要注意的是, 设置值的时候,cocos2d-iphone似乎比较喜欢设置成onButtonTest:即多个:的形式. 我们在cocos2d-x中保持一致即可.不必加:.
然后打开MainScene.hMainScene再增加一个继承.

class MainScene
: public cocos2d::CCLayer
, public cocos2d::extension::CCBMemberVariableAssigner
, public cocos2d::extension::CCBSelectorResolver

还有需要实现的函数

virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, const char* pSelectorName);
virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, const char* pSelectorName);
    
void onButtonTest(cocos2d::CCObject *pSender, cocos2d::extension::CCControlEvent pCCControlEvent);

接下来是增加的函数的实现

SEL_MenuHandler MainScene::onResolveCCBCCMenuItemSelector(cocos2d::CCObject *pTarget, const char *pSelectorName)
{
    return NULL;
}

SEL_CCControlHandler MainScene::onResolveCCBCCControlSelector(cocos2d::CCObject *pTarget, const char *pSelectorName)
{
    CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this, "onButtonTest", MainScene::onButtonTest);

    return NULL;
}

void MainScene::onButtonTest(cocos2d::CCObject *pSender, cocos2d::extension::CCControlEvent pCCControlEvent)
{
    this->mLabelText->setString("Hello CocosBuilder!!!");
}

好了, 现在运行一下, 点击按钮, 就会看到Hello Cocos2d-x!!!变成了Hello CocosBuilder!!!了.
#####13
刚才我们提到变量绑定较init函数(更别提运行更早的构造函数了)更晚. 那么如何运行后就控制这些控件呢?
方法当然是有, 我们需要增加一个CCNodeLoaderListener, 并实现其接口.新增代码如下:

, public cocos2d::extension::CCBSelectorResolver
, public cocos2d::extension::CCNodeLoaderListener
{
    ///......代码省略鸟
    virtual void onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader);
    ///......代码省略鸟
}
void MainScene::onNodeLoaded(cocos2d::CCNode *pNode, cocos2d::extension::CCNodeLoader *pNodeLoader)
{
    this->mLabelText->setString("All Loaded");
}

好啦, 运行就能看到All Loaded啦.

{ img /upload/2012-12/ccb-sbs-2-002.png }

  • 本帖最后由 young40 于 2012-12-29 05:27 编辑 *

3.修改AppDelegate.cpp中默认的启动scene

CCScene *pScene = MainScene::scene(); //HelloWorld::scene();

4.注意CCB中发布选项的设置, 并发布一次.

5.如果没有错误的话, 你应该可以看到运行的效果.

Update: @王哲Walzer 说,CCB大部分是美术在用, 在美术圈讨论, 所以程序圈较少看到人在讨论, 其实用的公司挺多的. http://weibo.com/1702027805/zay18wLT5

代码打包下载:http://pan.baidu.com/share/link?shareid=158075&uk=2281999082
*]本文是系列文章, 请查看其他文章:
*]http://young40.github.com/blog/2012/12/21/cocosbuilder-step-by-step-part-one/
*]http://young40.github.com/blog/2012/12/25/cocosbuilder-step-by-step-part-two/
*]http://young40.github.com/blog/2012/12/28/cocosbuilder-step-by-step-part-three/

谢谢您耐心看完此文, 希望能对您有些帮助.如果有什么问题, 意见, 建议, 拍砖, 欢迎留言或者联系我.新浪微博: http://weibo.com/young40 http://weibo.com/young40