Hello world分析

1. “resource”文件夹

用于存放图片、音频和配置等资源文件。为了方便管理,可以创建在其中创建子文件夹。Cocos2d-x为我们屏蔽了不同平台对于文件路径的定义。

2. “incluce”和“source”文件夹

这两个文件夹用来存放游戏头文件和源代码文件。项目模板为我们添加的三个文件分别为”main.h”,”main.cpp”和”resource.h”,它们是平台相关的程序文件,为Window专有。

通常情况下,程序入口与资源文件管理在不同平台下是不同的,但是cocos2d-x的模板已经基本为我们处理好这些细节,不需要对它们进行修改。

3. “AppDelegate.h”和”AppDelegate.cpp”文件

这两个文件是cocos2d-x游戏的通用入口文件,类似于一般windows工程中主函数所在的文件。AppDelegate在iOS工程中就是程序的入口文件。

Cocos2d-x来源于Cocos2d-iPhone,在很多方面沿袭了Cocos2d-iPhone的使用习惯。

AppDelegate.cpp

1. bool applicationDidFinishLaunching()

程序启动后将调用这个方法,默认启动后已经包含了游戏启动后的必要准备:

// initialize director
// 初始化游戏引擎控制器CCDirector,以便启动游戏引擎
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
// turn on display FPS 使用FPS显示
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
// 设置绘制间隔
pDirector->setAnimationInterval(1.0 / );
// create a scene. it's an autorelease object
// 创建HelloWorld场景
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
// 表示已经正常初始化
return true;
// 开启高分辨率屏幕(如iOS系列设备的Retina屏幕)支持
// pDirector->enableRetinaDisplay(true);

开启FPS显示:FPS即每秒帧速率,即屏幕每秒重绘的次数,启用后会在游戏左下角显示。在游戏开发阶段,可以方便地确定游戏运行是否流畅。

绘制间隔:指两次绘制间隔的时间间隔,因此绘制间隔的倒数就是FPS的上限。过低的每秒重绘次数会使动画显示出现卡顿的现象,而提高每秒重绘次数会导致设备运算量大幅增加,造成更高的能耗。人眼的刷新频率为每60次一秒。

2. void applicationDidEnterBackground()

应用程序将要进入后台时会调用这个方法,如用户把软件程序切换到后台,或手机接到电话或短信后程序被系统切换到后台时,会调用这个方法。 此时,应该暂停游戏中正在播放的音乐或音效。动作激烈的游戏成应该在此时进行暂停操作,以便玩家暂时离开游戏不会遭受重大损失。

3. void applicationWillEnterForeground()

与applicationDidEnterBackground(()方法成对出现,在应用回到前台时被调用。相对地,通常在这里继续播放刚才暂停的音乐,显示游戏暂停菜单等。

4. “HelloWorldScene.h”和”HelloWorldScene.cpp”文件

定义了Hello World项目中默认的游戏场景。

Cocos2d游戏中可以简单概括为:场景、层、精灵,而这两个文件就是Hello World场景的实现文件。每个游戏组件都可以添加一个到另一个组件中,形成层次关系。 Hello中定义了一个HelloWorld类,该类继承自CCLayout类,因此HelloWorld本身就是一个层。HelloWorld类包含一个静态函数和两个实例方法。

static CCScene* scene()

在层下设置一个创建场景的静态函数。我们为Hello World层写了一个CCLayout的子类,在子类中为层添加各种精灵或是逻辑处理代码。 然而我们的Hello World场景十分简单,只包含了一个层,没有任何其他需要处理的问题。因此,除了创建CCScene的一个子类之外,也可以直接使用静态函数来创建一个空场景,再把层置入场景之间,这样也十分便捷,示例代码如下所示:

CCScene *scene = CCScene::create();
HelloWorld *layout = HelloWorld::create();
Scene->addChild(layout);
bool init()

初始化HelloWorld类

基本概念

1. 场景与流程控制

把那些内容想到不变的游戏元素集合称作场景,把游戏在场景之间切换的过程叫做流程控制。

场景的实现是CCScene。

2. 层

隶属于场景下的游戏元素。通常,一个复杂场景会拥有多个层,一个层会显示一部分视觉元素,空白部分为透明或半透明,以实现多个层的重叠显示。层与层之间按照顺序叠放在一起,就组成了一个复杂的场景。

层的实现是CCLayout

3. 精灵

隶属于层,是场景中的可见图形。可以这样认为,一家看到的一切几乎都是由精灵构成的。

通常,一个精灵可以不断变化,变化的方式包括:移动、旋转、缩放、变形、显现、消失、动画效果等。

精灵的实现是CCSprite。

4. 节点与渲染树

从组织关系的角度来说,游戏元素按照树形结构组织起来;

从绘图的角度来说,图形按照自上而下的顺序绘制出来。

关系图实质上安排了图元的绘图方式,关系图中的每一个元素称作节点(node),关系图则称作渲染树(rendering tree)。渲染场景的过程就是遍历渲染树的过程。

一旦建立起渲染树,组织复杂的场景就变得十分简单。我们赋予每个节点一系列属性,包括节点相对于父节点的位置、旋转角度、缩放比例和变形参数等,就可以逐层创建复杂的对象或动作。

Cocos2d-x也采用了渲染树架构。任何可见的游戏元素都派生自Cocos2d-x节点(CCNode),常见的游戏元素都有场景、层和精灵等。

(实际开发中,如果有特殊要求,也不必拘泥于这个层次顺序。)

5. 动作与动画

动作作用于游戏元素,可以使游戏元素运动起来。常见的动作有移动、转动、闪烁、消失等。动作分为持续性动作与瞬时动作。

持续性动作在一段时间内完成,瞬时动作会瞬间完成。

动作为CCAction类实现,由CCAction类派生出持续性动作类CCActionInterval和瞬时动作类CCActionInstant,所有的动作都派生于以上两个类之一。

动画是一种特殊的持续性动作,它只能应用在精灵上,用于实现帧动画效果。

静止的图片叫帧(frame),帧的序列代表一个动画效果。

在Cocos2d-x中,我们使用多个帧创建帧动画序列(CCAnimation) ,并用帧动画序列创建可作用于精灵的帧动画(CCAnimate)。

代码风格

1. 命名空间与类名称

通常我们只要在使用时包含”cocos2d.h”,就可以使用引擎有全部功能了。 Cocos2d-x的类都放置于cocos2d命名空间下。

2. 构造函数与初始化

Cocos2d-x不使用传统的值类型,所有的对象都创建在堆上,然后通过指针引用。创建Cocos2d-x对象有通常两种方法:

第一种是首先使用new操作符创造一个未初始化的对象,然后调用init系列方法来初始化。

第二种是使用静态的工厂方法直接创建一个对象。

Objective-C中没有构造函数。

区别:使用构造函数创建的对象,它的所有权已经属于调用者了,使用工厂方法创建的对象的所有权是却并不属于调用者,因此,使用构造函数创建的对象需要调用者负责释放,而使用工厂方法创建的对象则不需要。

3. 选择器

在Objective-C中,选择器是类似于C++中的类函数指针的机制,Cocos2d-x也提供了一系列类似于Objective-C中创建选择器语法的宏,用来创建函数指针。

4. 属性

Cocos2d-x规定了属性访问器的方法名称以get或set为前缀,后接属性名。在CCNode中包含大量属性

为了避免重复的工作,Cocos2d-x提供了一系列宏来帮助我们方便地创建属性。

每个宏都有3个参数,分别是:

  • varType,属性类型,如果属性类型是对象,需要写成指针形式;
  • varName,属性的私有字段字称;
  • funName,属性的访问名称,也就是紧接在get或set前缀后的部分

5. 单例

单例模式保证了全局有且只有一个实例对象,保证自动地初始化该对象,使得程序任何时候任何地方都可以访问、获取该对象。

Cocos2d-x中的内存管理

基于Cocos2d-iPhone的Objective-C风格的内存管理是Cocos2d-x的一个特色。把Objective-C的内存管理方式引入C++,使得游戏开发的内存管理难度下降了一个层次。

Cocos2d-x很巧妙地运用了引用计数机制。为了与Objective-C一致,Cocos2d-x了采用了引用计数与自动回收的内存管理机制。

每一个对象包含一个用来控制生命周期的引用计数器,它是CCObject的成员变量,m_Reference。我们可以通过retainCount()方法获得对象当前的引用计数值。在对象通过构造函数创建的时候,该引用值被赋为1,表示对象由创建者所引用。在其它地方需要引用对象时,我们会调用retain()方法,令其引用增1,表示获取该对象的引用权;在引用结束的时候调用release()方法,令其引用计数值减1,表示释放该对象的引用权。

autorelease(),其作用是将对象放入自动回收池(CCAutoreleasePool)。当回收池自身被释放的时候,它就会对池中的所有对象执行一次release(),实现灵活的垃圾回收。即使我们没有手工创建和释放回收池,每一帧结束的时候,自动回收池中的对象也都会被执行一次release()方法。

如果在一帧之内生成了大量的autorelease()对象,将会导致回收池性能下降。因此,在生成autorelease()对象密集的区域前后,我们最好可以手动创建并释放一个回收池。

我们可以通过CCPoolManager的push()和pop()方法来创建或释放回收池。

自动回收池是可以嵌套的,

原则:

  • 程序段必须成对执行retain()和release()或者执行autorelease()来声明开始和结束对象的引用。
  • 工厂方法返回前,应通过autorelease()结束对该对象的引用
  • 对象传值时,应考虑到新旧对象相同的特殊情况
  • 尽量使用release()而不是autorelease()来释放对象引用,以确保性量最优
  • 保存CCObject的子类对象时,应严格使用Cocos2d-x提供的容器,避旬使用STL容器,对象必须以指针形式存入
05-11 13:16