Cocos2dx学习笔记(1)——认识HelloWorld

新的天地,欢迎来到Cocos2dx的世界!让我们认识认识游戏引擎最基本的概念!

本文仅供个人记录和复习,不用于其他用途

工程的基本文件

工程文件

新建工程所得到的就是这四个基本文件。AppDelegate.cppAppDelegate.h是游戏的通用入口文件,控制着游戏的主要设定和生命周期。至于HelloWorldScene便是用于实现开头的标题画面。

AppDelegate.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bool AppDelegate::applicationDidFinishLaunching()
{
// 初始化游戏引擎控制器CCDirector,设置游戏窗口名字和大小
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
{
glview = GLViewImpl::createWithRect("Practice", Rect(0, 0, 960, 640));
director->setOpenGLView(glview);
}
// 设置内容展示大小
director->getOpenGLView()->setDesignResolutionSize(960, 640, ResolutionPolicy::SHOW_ALL);
// 打开帧数显示,用于游戏开发过程中的测试
director->setDisplayStats(true);
// 默认帧数是60帧
director->setAnimationInterval(1.0 / 60);
FileUtils::getInstance()->addSearchPath("res");
// 创建一个场景
auto scene = HelloWorld::createScene();
// 启动场景
director->runWithScene(scene);
return true;
}

该方法用于游戏的启动,进行必要的准备。场景的启动以及必要的游戏参数是由单例director设置,该单例由getInstance()方法获得。需要注意的是,3.0版本中的单例获取由sharedDirector()变为了getInstance()

1
2
3
4
void AppDelegate::applicationDidEnterBackground()
{
Director::getInstance()->stopAnimation();
}

该方法用于游戏的暂停处理,比如手机玩游戏接到电话时,或者主动将游戏转入后台时,就将调用这个方法,同时还可以暂停游戏中播放的音乐。

1
2
3
4
void AppDelegate::applicationWillEnterForeground()
{
Director::getInstance()->startAnimation();
}

该方法用于游戏从后台切回前台时,继续游戏的进程。例如打完电话或者想继续玩游戏了,就将调用这个方法。一般在这里显示游戏的暂停菜单,继续播放刚刚暂停的音乐。

HelloWorldScene.h

1
2
3
4
5
6
7
class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(HelloWorld);
};

这是一个最基本的层,HelloWorld类继承自Layer,这里要注意的是3.0版本中基本元素不用加上CC的前缀,例如CCLayer直接用Layer代替即可。

static cocos2d::Scene* createScene()用于创建HelloWorld中显示的场景内容,因为这是最简单的HelloWorld程序,所以直接在层中创建一个场景,并返回这个场景的指针供director启动。virtual bool init()用于初始化,添加对应的图片等元素进入场景。

CREATE_FUNC(HelloWorld)是一个宏,用于HelloWorld层的内存分配,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = nullptr; \
return nullptr; \
} \
}

Cocos引擎没有使用C++中的析构函数和构造函数,为了方便回收内存,Cocos采用了回收池的机制,例如,给每一块分配的内存加上一个计数器,分配时计数加1,想要删除时计数减1,这样能够实现内存的回收处理。上述代码中给HelloWorld类分配了一块内存,并判断内存是否分配成功,若成功,检查init()方法是否初始化成功,如果都成功,将指针送入自动回收池,并返回指针。autorelease()事实上省去了手动的添加计数器,能够自动的处理回收操作,但不宜大量使用。

HelloWorldScene.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
auto rootNode = CSLoader::createNode("MainScene.csb");
addChild(rootNode);
return true;
}

这个是最简单的init()方法,除了加入标题界面便没有其他的功能。虽然没有使用构造函数,但同样得判断父类有没有执行初始化,即判断Layerinit()方法有没有成功。另外,此处的MainScene.csb文件是CocosStudio中建立好的场景,关于CocosStudio的使用,我还不是特别了解,因此以后再加以总结。此处创建一个精灵,并添加入标题图片是一样的效果,只不过当标题界面复杂时便不是很方便,而且CocosStudio主要是提供给美工使用,能够加强分工合作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Scene* HelloWorld::createScene()
{
// 创建一个场景
auto scene = Scene::create();
// 创建HelloWorld层
auto layer = HelloWorld::create();
// 将层加入场景
scene->addChild(layer);
// 返回场景指针
return scene;
}

createScene()中,主要就是创建新场景和自定义的层,并将层加入场景中。addChild()是Cocos中很重要的一个方法,用于将子节点加入到父节点,便于调动。正是这种由父到子,层层地渲染下来的方法,便构成了我们熟悉的游戏场景。