cocos2dx3.2 整体概览(三)—— Scene(场景)

上一节中对导演有了初步的认识,而导演只是控制好游戏的流程,具体游戏的内容却需要开发者去布置好一个一个的场景。因此在学习的过程中,我们有必要了解场景。

由于自建工程后自动生成了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函数。就是在createSceneHelloWorld调用的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中完成对场景的初始化,导演再去调用该场景时,我们所部署的场景就会展示在我们面前。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值