cocos2dx-3.0(3)------Scene 场景

本文详细介绍了Cocos2d-x 3.0中Scene的使用,讲解了CREATE_FUNC宏的作用以及如何在init()函数中初始化Layer。内容包括Scene的创建、Layer的添加以及Scene与Layer的关系,为初学者展示了Cocos2d-x游戏开发的基础知识。
摘要由CSDN通过智能技术生成

上文中讲到怎么往框架中加东西?回顾一下上文关键代码:

//create a scene. it's an autorelease object
auto scene = HelloWorld::createScene();

// run
director->runWithScene(scene);

 
auto为c++11新出的功能,相当好用,这里我不想多说,谷歌,度娘比我说的好多了,要让专业人做专业的事,我们打打酱油就行了。这里HelloWorld::createScene()会返回一个场景的指针,然后导演去运行此场景,一次只有一个场景是活动的,不管你有多少个场景, 
下面老规矩看看代码: 

Helloworld类:

USING_NS_CC;

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);
    
	virtual void onEnter();

    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

我一直忘记说那个命名空间USING_NS_CC;是做什么用的,我们进去看看:

#define USING_NS_CC                     using namespace cocos2d

其实他是cocos2d的别称,所以有了他以后,下面cocos2d::Layer可以直接写成Layer了

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

看createScene函数,我们发现首先创建了一个scene对象:

auto scene = Scene::create();
我们进去看,会发现他创建了一个不需要我释放的scene对象,这可以为了省了不少心啊!

auto layer = HelloWorld::create();

看到这里,读者发现,我们根本没有在Helloworld里定义这个函数啊,他怎么出来,并且也不报错,这真特么神奇啊!!老妹,你说这是为什么了?其实他是那个CREATE_FUNC(HelloWorld);这个宏,我们进去看看这个宏就知道了

#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; \
    } \
}

是不是觉得宏还可以这样玩,吊爆了有木有,哈哈哈哈....我们继续

scene->addChild(layer);

// return the scene
return scene;
我们把创建出来layer添加到scene中,然后scene拿来运行,大家有没有发现这其中有一个层次关系


这图意思是scene上必须先添加一个layer,然后layer上可以添加很多东西,比如sprite精灵,menu菜单等等。

从上面那个CREATE_FUNC宏里面我们看到调用了init() 所以我们可以在init()里做好多事,基本一个layer里面要添加的对象都在这里面,如果你觉得全写在里面很乱,完全可以自己封装N个函数,然后你懂的。

下面我们来看看init()函数里都有什么?

bool HelloWorld::init()
{
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    
	//创建精灵
    auto player = Sprite::create("Player.png", Rect(0, 0, 27, 40));
    player->setPosition(Point(player->getContentSize().width/2, visibleSize.height / 2));
    this->addChild(player, 0);
    auto closeItem = MenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
    
    closeItem->setPosition(origin + Point(visibleSize) - Point(closeItem->getContentSize() / 2));


    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Point::ZERO);
    this->addChild(menu, 1);
    
    /
    // 3. add your codes below...


    // add a label shows "Hello World"
    // create and initialize a label
    
    auto label = LabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE);
    
    // position the label on the center of the screen
    label->setPosition(Point(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));


    // add the label as a child to this layer
    this->addChild(label, 1);
	this->setTouchEnabled(true);
    return true;
}
我们看到,先调用父类的init函数,然后就可以开始为所欲为了,这里我们创建了一个精灵对象,精灵说白了就是图片,尼吗游戏就是一堆图片在那移动,尼吗尼吗!!好吧,我愤青了。

//创建精灵
auto player = Sprite::create("Player.png", Rect(0, 0, 27, 40));
player->setPosition(Point(player->getContentSize().width/2, visibleSize.height / 2));
this->addChild(player, 0);
首先我们创建了一个精灵对象,然后设置他显示的位置,取半 是把图片的中心位置和scene中心位置重合,并不是依据什么左上角或右下角,这里是在正央显示。最后需要把他添加到layer中,成功添加了一个精灵。

auto closeItem = MenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
    
closeItem->setPosition(origin + Point(visibleSize) - Point(closeItem->getContentSize() / 2));

// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
首先我们创建一个依据图片的menuitem对象,如果依据汉字(也就是label)就使用 MenuItemLabel 依次类推,如果此时你不把他添加到Menu中,他就不会响应你的鼠标点击,这说明Menu负责了触摸分发,监听事件等,里面有一个CC_CALLBACK_1这货,一看就知道他肯定还有好多兄弟,这个放到以后来说,现在先忽略他。 最后一个创建字体我就不说了,类似的! OK 现在知道怎么处理init()函数了吧。我们继续往下看

最后一个关闭函数

void HelloWorld::menuCloseCallback(Ref* sender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
	MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif

    Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}
只要关心Director::getInstance()->end();他就是用来关闭的。

到此简单的说了最基本的几个函数及里面一些简单的功能,功能虽然简单,但是这都是精髓,如果想要什么功能,都可以自己加。

至此一个简单的cpp-empty-test就说完了,运行起来就可以看到一个雏形了,接下来就要逐步分析各个控件,各个类了。

下面补充的给出一个layer的继承关系图,因为前一篇都给了Application的图,这里肯定也要给的






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值