cocos2dx3.2 整体概览(三)—— Scene(场景)
2014-09-26 16:31
260 查看
上一节中对导演有了初步的认识,而导演只是控制好游戏的流程,具体游戏的内容却需要开发者去布置好一个一个的场景。因此在学习的过程中,我们有必要了解场景。
由于自建工程后自动生成了HelloWorld,从程序中我们知道,默认运行的场景就是HelloWorld:
因此,我们可以直接通过自动生成的HelloWorld来了解怎么设计一个场景。
首先,可以看一下HelloWorld的头文件中对于HelloWorld这个场景类的声明:
其实对于这个我已开始很奇怪,因为他既然是HelloWorld这个场景,他干什么继承的是Layer(层),为什么不直接继承Scene(场景),于是只好了解一下其中的函数。
首先,对于第一个函数:
这个静态函数的功能很明显,就是创建一个场景。导演所调用的场景就是HelloWorld类调用该函数创造的。该函数的创建过程很简单,只有四句话:
这四条语句非常简单。创建场景 → 创建层(由于HelloWorld继承自层,这里创建的层就是他自己) → 将该层添加到刚创建的场景中 → 返回该场景。
通过这个可以想到,新创建的scene为这个场景渲染树的根节点,他只有一个子节点,就是HelloWorld这个层。而在初始化添加节点是,往往都是this->addChild,因此,新添加的节点最多只能是HelloWorld这个层的儿子,不可能成为scene的儿子(当然,如果刻意你刻意的话……)。我猜测,或许这就是不直接继承场景的目的。
然后,关于下一个函数:
从名字上,可以知道他是该层初始化的函数,具体过程,注释写的非常清楚,这里不做赘述。
而另一个函数:
是关闭按钮的回调函数,在初始化init中,添加了一个关闭按钮:
该函数,就是当游玩者点击关闭按钮时所触发的事件。
最后出现了一个宏定义的函数:
看一下他的实现,可以知道,这个的功能是为特殊类型,这里是Layer类型(HelloWorld正继承自他),定义create函数。就是在createScene中HelloWorld调用的create函数:
查看该宏定义的实现:
可以知道,这里相当于声明了一个create函数,返回类型__TYPE__,就是传入的值(HelloWorld)。该函数的实现很简单,首先创建该类型的实例:
这里相当于:
然后判定该实例指针是否存在,不存在就释放指针:
然后返回空:
存在的话就调用该实例的init函数,进行初始化,如果初始化进行顺利,则设置该指针自动释放并且返回该指针:
这就是创建Scene的一个基本的框架,实际上很容易理解,我们只要在init中完成对场景的初始化,导演再去调用该场景时,我们所部署的场景就会展示在我们面前。
由于自建工程后自动生成了HelloWorld,从程序中我们知道,默认运行的场景就是HelloWorld:
auto scene = HelloWorld::createScene(); director->runWithScene(scene);
因此,我们可以直接通过自动生成的HelloWorld来了解怎么设计一个场景。
首先,可以看一下HelloWorld的头文件中对于HelloWorld这个场景类的声明:
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" class HelloWorld : public cocos2d::Layer { public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // a selector callback void menuCloseCallback(cocos2d::Ref* pSender); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__
其实对于这个我已开始很奇怪,因为他既然是HelloWorld这个场景,他干什么继承的是Layer(层),为什么不直接继承Scene(场景),于是只好了解一下其中的函数。
首先,对于第一个函数:
static cocos2d::Scene* createScene();
这个静态函数的功能很明显,就是创建一个场景。导演所调用的场景就是HelloWorld类调用该函数创造的。该函数的创建过程很简单,只有四句话:
auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene;
这四条语句非常简单。创建场景 → 创建层(由于HelloWorld继承自层,这里创建的层就是他自己) → 将该层添加到刚创建的场景中 → 返回该场景。
通过这个可以想到,新创建的scene为这个场景渲染树的根节点,他只有一个子节点,就是HelloWorld这个层。而在初始化添加节点是,往往都是this->addChild,因此,新添加的节点最多只能是HelloWorld这个层的儿子,不可能成为scene的儿子(当然,如果刻意你刻意的话……)。我猜测,或许这就是不直接继承场景的目的。
然后,关于下一个函数:
virtual bool init();
从名字上,可以知道他是该层初始化的函数,具体过程,注释写的非常清楚,这里不做赘述。
而另一个函数:
void menuCloseCallback(cocos2d::Ref* pSender);
是关闭按钮的回调函数,在初始化init中,添加了一个关闭按钮:
///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2)); // create menu, it's an autorelease object auto menu = Menu::create(closeItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1);
该函数,就是当游玩者点击关闭按钮时所触发的事件。
最后出现了一个宏定义的函数:
CREATE_FUNC(HelloWorld);
看一下他的实现,可以知道,这个的功能是为特殊类型,这里是Layer类型(HelloWorld正继承自他),定义create函数。就是在createScene中HelloWorld调用的create函数:
auto layer = HelloWorld::create();
查看该宏定义的实现:
#define CREATE_FUNC(__TYPE__) \ static __TYPE__* create() \ { \ __TYPE__ *pRet = new __TYPE__(); \ if (pRet && pRet->init()) \ { \ pRet->autorelease(); \ return pRet; \ } \ else \ { \ delete pRet; \ pRet = NULL; \ return NULL; \ } \ }
可以知道,这里相当于声明了一个create函数,返回类型__TYPE__,就是传入的值(HelloWorld)。该函数的实现很简单,首先创建该类型的实例:
__TYPE__ *pRet = new __TYPE__();
这里相当于:
HelloWorld *pRet = new HelloWorld();
然后判定该实例指针是否存在,不存在就释放指针:
delete pRet; pRet = NULL;
然后返回空:
return NULL;
存在的话就调用该实例的init函数,进行初始化,如果初始化进行顺利,则设置该指针自动释放并且返回该指针:
pRet->autorelease(); return pRet;
这就是创建Scene的一个基本的框架,实际上很容易理解,我们只要在init中完成对场景的初始化,导演再去调用该场景时,我们所部署的场景就会展示在我们面前。
相关文章推荐
- cocos2dx3.2 整体概览(二)—— Director(导演)
- cocos2dx 3.2 渲染(Director::drawScene 在游戏loop里每帧调用。 内部实际通过调用场景内每个node的 visit方法完成渲染)
- cocos2dx3.2 整体概览(一)—— 渲染树
- cocos2dx3.2 整体概览(四)—— Sprite(精灵)
- cocos2dx3.3开发FlappyBird总结八:载入场景LoadingScene
- cocos2dx基础篇(26)——场景切换CCTransitionScene
- cocos2dx3.2 由Hello_World看整体思路
- 【cocos2dx 3.2】Flappy Bird开发超详细讲解(三)预加载场景和开始场景
- Cocos2dx 场景类-Scene
- 【cocos2dx 3.2】一个都不能死6 主场景层
- Cocos2dx学习笔记5:场景(Scene)
- 【cocos2dx 3.2】一个都不能死7 游戏结束场景
- cocos2dx3.2开发 RPG《Flighting》(七)回到战斗场景,更新角色的叠放次序
- cocos2dx-3.0(3)------Scene 场景
- 利用cocos2dx 3.2开发消灭星星(四)游戏主场景
- cocos2dx3.2开发 RPG《Flighting》(五)只能行走的战斗场景
- cocos2dx 3.2 学习篇之三(场景的创建与切换)
- 【cocos2dx 3.2】一个都不能死6 主场景层
- cocos2dx3.2学习笔记之Scene、Layer、Sprite
- 【cocos2dx 3.2】一个都不能死7 游戏结束场景