cocos2d-x: 死磕"HelloWorld"(4)——HelloWorld场景的创建
2014-07-05 07:39
381 查看
该篇将分析万众瞩目的HelloWorld场景是如何出现的。我们在上一篇中已经看到在应用初始化函数applicationDidFinishLaunching()中调用了HelloWorld::scene()来创建场景。因此答案就在HelloWorld::scene()里,我们将对它进行详解。但是在分析之前,我们先来复习一下cocos2d-x的渲染框架,也就是cocos2d-x渲染对象的层次结构。渲染框架主要就是四个概念: 导演类director,场景类scene,图层类layer,精灵类sprite。一个app只有一个导演,它指挥场景的切换和运行。每一个场景里面又包含前后图层,而每一个图层里面又包含人物精灵。所以渲染的对象只有三个,即场景,图层和精灵。它们都继承自一个基本的渲染节点类,即CCNode类。场景包含图层,图层包含精灵,反过来说,精灵在图层内,图层在场景内。场景最大。导演只需把最大的指挥好就行了。可以利用CCNode的成员函数addChild()把精灵加入到图层里,或者把图层加入到场景里。
先来看一下HelloWorld类头文件:
HelloWorldScene.h
可见HelloWorld类继承自图层类,而非场景类。它共有四个成员函数,分别是图层初始化函数init(),场景创建函数scene(),关闭回调函数menuCloseCallback()(在上一篇中提到过用来关闭程序),还有图层创建函数create()(通过宏实现)。其中scence()和create()都是静态函数,分别返回CCScene指针和HelloWorld指针。接下来,我们马上会看到scene()调用了create(),而create()又调用了init(),而init()又调用了menuCloseCallback()。下面就先来看一下HelloWorld::scene()具体定义:
HelloWorldScene.cpp
第一个create()是场景类的静态成员函数,因此是一般性的,HelloWorld图片肯定不是从这里进入。再者HelloWorld图片应该先绑定一个精灵,然后将该精灵添加到图层里。因此HelloWorld图片肯定是从第二个create()进入的。我们现在就来看看第二个create()的定义。它的定义由宏CREATE_FUNC(HelloWorld)实现。该宏的定义为:
CCPlatformMacros.h
该定义和CCLayer类中的create()定义基本一致,只是它们创建的对象属于不同的类。由于它们所调用的init()是一虚函数,因此HelloWorld类里的create()创建的对象调用HelloWorld类本身的init()。我们现在就来看看HelloWorld类里的init()函数:
HelloWorldScene.cpp
一个简单的游戏到此就算制作完成了。作为一个简单的例子,HelloWorld场景只有一个图层,从该图层初始化函数中可以看出,该图层只包含了一个关闭按钮,一个标签,和一个带HelloWorld纹理的精灵。如果要做更为复杂生动的游戏,可以往该初始化函数中添加新的内容。
接下来会用两个篇章来分析场景的渲染。它对于单纯的游戏制作者而言可以不用理会,但是可以帮助我们理解引擎的工作原理。
先来看一下HelloWorld类头文件:
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" class HelloWorld : public cocos2d::CCLayer { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__
可见HelloWorld类继承自图层类,而非场景类。它共有四个成员函数,分别是图层初始化函数init(),场景创建函数scene(),关闭回调函数menuCloseCallback()(在上一篇中提到过用来关闭程序),还有图层创建函数create()(通过宏实现)。其中scence()和create()都是静态函数,分别返回CCScene指针和HelloWorld指针。接下来,我们马上会看到scene()调用了create(),而create()又调用了init(),而init()又调用了menuCloseCallback()。下面就先来看一下HelloWorld::scene()具体定义:
HelloWorldScene.cpp
CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create();//创建了一个场景类对象,并返回该场景的指针。 // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create();//利用静态成员函数create()创建一个HelloWorld图层,并返回该图层的指针。注意HelloWorld的基类CCLayer里也有一个静态成员函数creat(),但是该静态成员函数被HelloWorld重载了。题外话:静态函数直接绑定类,被所有实例共享,所以不存在多态,不能虚函数化。 // add layer as a child to scene scene->addChild(layer);//将该图层添加到场景里面。 // return the scene return scene;//返回该场景。 }
第一个create()是场景类的静态成员函数,因此是一般性的,HelloWorld图片肯定不是从这里进入。再者HelloWorld图片应该先绑定一个精灵,然后将该精灵添加到图层里。因此HelloWorld图片肯定是从第二个create()进入的。我们现在就来看看第二个create()的定义。它的定义由宏CREATE_FUNC(HelloWorld)实现。该宏的定义为:
CCPlatformMacros.h
#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; \ } \ }
该定义和CCLayer类中的create()定义基本一致,只是它们创建的对象属于不同的类。由于它们所调用的init()是一虚函数,因此HelloWorld类里的create()创建的对象调用HelloWorld类本身的init()。我们现在就来看看HelloWorld类里的init()函数:
HelloWorldScene.cpp
bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() )//利用基类成员函数CCLayer::init()对图层对象进行初始化。如果初始化失败则退出函数,返回假。 { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();//获取可视大小。 CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();//获取原点。 ///////////////////////////// // 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 CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback));//创建关闭图标,调用menuCloseCallback pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 , origin.y + pCloseItem->getContentSize().height/2));//设置关闭图标位置。 // create menu, it's an autorelease object CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);//利用关闭图标创建一个按钮。 pMenu->setPosition(CCPointZero);//设置按钮位置。 this->addChild(pMenu, 1);//将按钮添加到当前图层。 ///////////////////////////// // 3. add your codes below... // add a label shows "Hello World" // create and initialize a label CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE);//创建一个Hello World标签 // position the label on the center of the screen pLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height - pLabel->getContentSize().height));//设置标签位置。 // add the label as a child to this layer this->addChild(pLabel, 1);//添加标签到当前图层。 // add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("HelloWorld.png");//利用HelloWorld.png纹理创建一个精灵。 // position the sprite on the center of the screen pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));//设置精灵位置。 // add the sprite as a child to this layer this->addChild(pSprite, 0);//添加精灵到当前图层。 return true; }
一个简单的游戏到此就算制作完成了。作为一个简单的例子,HelloWorld场景只有一个图层,从该图层初始化函数中可以看出,该图层只包含了一个关闭按钮,一个标签,和一个带HelloWorld纹理的精灵。如果要做更为复杂生动的游戏,可以往该初始化函数中添加新的内容。
接下来会用两个篇章来分析场景的渲染。它对于单纯的游戏制作者而言可以不用理会,但是可以帮助我们理解引擎的工作原理。
相关文章推荐
- cocos2d-x: 死磕"HelloWorld"(2)——应用实例的创建
- cocos2d-x: 死磕"HelloWorld"(6)——场景渲染的实施
- cocos2d-x: 死磕"HelloWorld"(5)——场景渲染准备工作
- cocos2d-x: 死磕"HelloWorld"(3)——游戏运行主函数run()
- cocos2d-x: 死磕"HelloWorld"(1)——入口函数及其带来的疑问
- arm系统启动后运行 helloworld ("hello world" 被封装为ramdisk)
- 6.1 创建"Hello World"图形用户界面
- cocos2d-x简单游戏<打飞机>代码实现|第四部分:主场景<Helloworld.m>
- 创建"Hello World"图形用户界面
- Cocos2d-x简单游戏<打飞机>代码实现|第四部分:主场景<Helloworld.h>
- 1.3创建一个“HelloWorld"程序
- 创建"Hello World"图形用户界面
- Cocos2d-x--"Hello World"深入分析
- cocos2d 游戏开发:Cocos2d v3 "hello world"+显示飞船
- cocos2d 游戏开发:Cocos2d v3 "hello world"+显示飞船
- 自己动手写操作系统--"Hello, OS world!"http://blog.csdn.net/zieckey/archive/2007/05/15/1609908.aspx
- c程序中不使用分号输出"Hello, world"
- 17种"Hello World"!
- "Hello world" ,frist program
- 一个简单的"Hello World"