上文中讲到怎么往框架中加东西?回顾一下上文关键代码:
//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的图,这里肯定也要给的