抄书的笔记来的。
1 一般游戏都有的流程
通常我们把内容相对不变的游戏元素称为场景Scene。在cocos2dx中,场景的实现是CCScene。
2 层是隶属于场景之下的游戏元素。通常,一个复杂场景拥有多个层,一个层会显示一部分视觉元素,空白部分为透明或者半透明,以实现多个层的重叠显示。层与层之间按照顺序叠放在一起,组成了一个复杂的场景。
以捕鱼场景为例,场景可以大致分为4层。
菜单层,触摸层,动作层,背景层。
在Cocos2d-x中,层的实现是CCLayer。
3 精灵隶属于层。玩家控制的主角,AI的控制NPC,地图上的宝箱、石块,甚至游戏的背景图片都是精灵。通常,一个精灵可以不断的变化:移动、旋转、缩放、变形、显示消失、动画效果。
在Cocos2d-x中,精灵的实现是CCSprite。
4 渲染树
渲染场景的过程就是遍历渲染树的过程。
一旦建立起渲染树,组织复杂的场景就变得十分简单。
例如海龟:
建立一个节点表示海龟,在海龟节点下再建立5个精灵,表示腿和躯干。这样,每个动作都是可控的,只要为每个节点设置好了动作,就可以完成复杂的动画。
Cocos2d-x也采用渲染树架构。任何可见的游戏元素都派生自CCNode,常见的游戏元素有场景CCScene,层CCLayer,和精灵CCSprite等。通常游戏按照场景、层、精灵的层次顺序组织。然而在实际开发中,为了实现一些特殊的效果,也不必拘泥于这个层次的顺序。
5
动作(action)作用于游戏元素。
常见的动作有移动、转动、闪烁、消失等。
动作分为持续性动作和瞬时动作。
在Cocos2d-x中,动作由CCAction实现。
由CCAction派生出持续性动作类CCActionInterval和瞬时动作类CCActionInstant。
6
动画(animation)作用于精灵。
静止的图片叫帧(frame)。帧的序列代表一个动画效果。
在Cocos2d-x中,可以使用多个帧创建帧动画序列(CCAnimation),并用帧动画序列创建可作用于精灵的帧动画(CCAnimate)。
7
命名空间和类名称。
引用头文件”cocos2d.h”,就可以使用引擎的全部功能了。
所有的类都在cocos2d命名空间下。
#define USING_NS_CC using namespace cocos2d
所有的类都有前缀CC
8
Cocos2d-x的构造函数通常没有操作。
创建Cocos2d-x的方法有两种:
new创建一个未初始化的对象,然后调用init系列方法初始化。
CCSprite* sprite1 = new CCSprite();
spritel->initWithFile(“HelloWorld.png”);
使用静态的工厂方法。
CCSprite* sprite2 = CCSprite::create(“HelloWorld.png”);
两者的内存管理方式不同。
使用构造函数创建的对象需要使用者负责释放,而使用工厂方法则不需要。
9
选择器,类似C++中的类函数指针机制。
提供一些宏来创建函数指针。
callfunc_selector(SELECTOR)
Menu_selector(SELECTOR)
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
“CloseNormal.png”,
“CloseSelected.png”,
this,
menu_selector(HelloWorld::menuCloseCallback));
10
访问器宏
int tag;
int getTag() { return tag; }
void setTag(int aTag) { tag = aTag; }
CC_SYNTHESIZE(int,tag,Tag);
11
单例模式
保证全局有且仅有一个实例对象,使得程序在任何时候任何地方都可以访问、获取该对象。
在Cocos2d-x中CCDirector是一个独一无二的控制器。
static CCDisplayLinkDirector s_SharedDirector;
CCDirector* CCDirector::sharedDirector(void)
{
static bool s_bFirstUseDirector = true;
if (s_bFirstUseDirector)
{
s_bFirstUseDirector = false;
s_SharedDirector.init();
}
return &s_SharedDirector;
}
CCDirector维护一个静态的CCDirector实例,在第一次使用前初始化。
为了访问CCDirector控制器,使用如下代码:
CCDirector::sharedDirector()->replaceScene(newScene);
12
内存管理机制。采用引用计数和自动回收。
为了实现对象的引用计数记录,Cocos2d-x实现了自己的根类CCObject,引擎中所有的类都派生自CCObject。
每个对象包含一个用来控制生命周期的引用计数器,m_uReference
可以通过retainCount()方法获得对象当前的引用计数值。
在对象通过构造函数创建时,该引用值被赋为1,表示对象由创建者引用。
在其他地方需要引用对象时,我们会调用retainCount()方法,令其计数增1,表示获取对象的引用权。
在引用结束的时候调用release()方法,令其引用计数值减1,表示释放该对象的引用权。
autorelease(),作用是将对象放入自动回收池。当回收池本身释放的时候,会对池中所有对象执行一次release()方法。
虽然Cocos2d-x已经保证每一帧结束后释放一次回收池,并在下一帧开始前创建一个新的回收池,但是在生成autorelease对象密集的区域(通常是循环中)的前后,最好手动创建并释放一个回收池。通过CCPoolManager的push()和pop()方法来创建或释放回收池。
CCPoolManager也是一个单例对象。
CCPoolManager::sharedPoolManager()->push();
for (int i = 0; i < n; ++i)
{
CCString* dataItem = CCString::createWithFormat(“%d”,Data[i]);
stringArray->addObject(dataItem);
}
CCPoolManager::sharedPoolManager()->pop();
autorelease()是可嵌套的。(栈)
13
工厂方法的隐患。
CCObject* factoryMethod()
{
CCObject* ret = new CCObject();
return ret;
}
工厂方法对ret对象的引用函数返回时已经结束,但是它没有释放对ret的引用,埋下了内存泄露的隐患。但是在函数结束前执行release(),显然是不合适的,会使得返回的对象成为了错误指针。
CCObject* factoryMethod()
{
CCObject* ret = new CCObject();
ret->autorelease();
return ret;
}
14
对象传值。
将一个对象赋值给某一指针作为引用的时候,为了遵循内存管理的原则,需要获得新对象的引用权,释放旧对象的引用权。
void SomeClass::setObject(CCObject* other)
{
this->object->release();
other->retain();
this->object = other;
}
当other和object实际上指向同一个对象时,第一个release()可能会触发该对象的回收,这显然不是我们想看到的局面。所以应该先执行retain()来保证other对象有效,然后再释放旧的对象
void SomeClass::setObject(CCObject* other)
{
other->retain();
this->object->release();
this->object = other;
}
1 一般游戏都有的流程
通常我们把内容相对不变的游戏元素称为场景Scene。在cocos2dx中,场景的实现是CCScene。
2 层是隶属于场景之下的游戏元素。通常,一个复杂场景拥有多个层,一个层会显示一部分视觉元素,空白部分为透明或者半透明,以实现多个层的重叠显示。层与层之间按照顺序叠放在一起,组成了一个复杂的场景。
以捕鱼场景为例,场景可以大致分为4层。
菜单层,触摸层,动作层,背景层。
在Cocos2d-x中,层的实现是CCLayer。
3 精灵隶属于层。玩家控制的主角,AI的控制NPC,地图上的宝箱、石块,甚至游戏的背景图片都是精灵。通常,一个精灵可以不断的变化:移动、旋转、缩放、变形、显示消失、动画效果。
在Cocos2d-x中,精灵的实现是CCSprite。
4 渲染树
渲染场景的过程就是遍历渲染树的过程。
一旦建立起渲染树,组织复杂的场景就变得十分简单。
例如海龟:
建立一个节点表示海龟,在海龟节点下再建立5个精灵,表示腿和躯干。这样,每个动作都是可控的,只要为每个节点设置好了动作,就可以完成复杂的动画。
Cocos2d-x也采用渲染树架构。任何可见的游戏元素都派生自CCNode,常见的游戏元素有场景CCScene,层CCLayer,和精灵CCSprite等。通常游戏按照场景、层、精灵的层次顺序组织。然而在实际开发中,为了实现一些特殊的效果,也不必拘泥于这个层次的顺序。
5
动作(action)作用于游戏元素。
常见的动作有移动、转动、闪烁、消失等。
动作分为持续性动作和瞬时动作。
在Cocos2d-x中,动作由CCAction实现。
由CCAction派生出持续性动作类CCActionInterval和瞬时动作类CCActionInstant。
6
动画(animation)作用于精灵。
静止的图片叫帧(frame)。帧的序列代表一个动画效果。
在Cocos2d-x中,可以使用多个帧创建帧动画序列(CCAnimation),并用帧动画序列创建可作用于精灵的帧动画(CCAnimate)。
7
命名空间和类名称。
引用头文件”cocos2d.h”,就可以使用引擎的全部功能了。
所有的类都在cocos2d命名空间下。
#define USING_NS_CC using namespace cocos2d
所有的类都有前缀CC
8
Cocos2d-x的构造函数通常没有操作。
创建Cocos2d-x的方法有两种:
new创建一个未初始化的对象,然后调用init系列方法初始化。
CCSprite* sprite1 = new CCSprite();
spritel->initWithFile(“HelloWorld.png”);
使用静态的工厂方法。
CCSprite* sprite2 = CCSprite::create(“HelloWorld.png”);
两者的内存管理方式不同。
使用构造函数创建的对象需要使用者负责释放,而使用工厂方法则不需要。
9
选择器,类似C++中的类函数指针机制。
提供一些宏来创建函数指针。
callfunc_selector(SELECTOR)
Menu_selector(SELECTOR)
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
“CloseNormal.png”,
“CloseSelected.png”,
this,
menu_selector(HelloWorld::menuCloseCallback));
10
访问器宏
int tag;
int getTag() { return tag; }
void setTag(int aTag) { tag = aTag; }
CC_SYNTHESIZE(int,tag,Tag);
11
单例模式
保证全局有且仅有一个实例对象,使得程序在任何时候任何地方都可以访问、获取该对象。
在Cocos2d-x中CCDirector是一个独一无二的控制器。
static CCDisplayLinkDirector s_SharedDirector;
CCDirector* CCDirector::sharedDirector(void)
{
static bool s_bFirstUseDirector = true;
if (s_bFirstUseDirector)
{
s_bFirstUseDirector = false;
s_SharedDirector.init();
}
return &s_SharedDirector;
}
CCDirector维护一个静态的CCDirector实例,在第一次使用前初始化。
为了访问CCDirector控制器,使用如下代码:
CCDirector::sharedDirector()->replaceScene(newScene);
12
内存管理机制。采用引用计数和自动回收。
为了实现对象的引用计数记录,Cocos2d-x实现了自己的根类CCObject,引擎中所有的类都派生自CCObject。
每个对象包含一个用来控制生命周期的引用计数器,m_uReference
可以通过retainCount()方法获得对象当前的引用计数值。
在对象通过构造函数创建时,该引用值被赋为1,表示对象由创建者引用。
在其他地方需要引用对象时,我们会调用retainCount()方法,令其计数增1,表示获取对象的引用权。
在引用结束的时候调用release()方法,令其引用计数值减1,表示释放该对象的引用权。
autorelease(),作用是将对象放入自动回收池。当回收池本身释放的时候,会对池中所有对象执行一次release()方法。
虽然Cocos2d-x已经保证每一帧结束后释放一次回收池,并在下一帧开始前创建一个新的回收池,但是在生成autorelease对象密集的区域(通常是循环中)的前后,最好手动创建并释放一个回收池。通过CCPoolManager的push()和pop()方法来创建或释放回收池。
CCPoolManager也是一个单例对象。
CCPoolManager::sharedPoolManager()->push();
for (int i = 0; i < n; ++i)
{
CCString* dataItem = CCString::createWithFormat(“%d”,Data[i]);
stringArray->addObject(dataItem);
}
CCPoolManager::sharedPoolManager()->pop();
autorelease()是可嵌套的。(栈)
13
工厂方法的隐患。
CCObject* factoryMethod()
{
CCObject* ret = new CCObject();
return ret;
}
工厂方法对ret对象的引用函数返回时已经结束,但是它没有释放对ret的引用,埋下了内存泄露的隐患。但是在函数结束前执行release(),显然是不合适的,会使得返回的对象成为了错误指针。
CCObject* factoryMethod()
{
CCObject* ret = new CCObject();
ret->autorelease();
return ret;
}
14
对象传值。
将一个对象赋值给某一指针作为引用的时候,为了遵循内存管理的原则,需要获得新对象的引用权,释放旧对象的引用权。
void SomeClass::setObject(CCObject* other)
{
this->object->release();
other->retain();
this->object = other;
}
当other和object实际上指向同一个对象时,第一个release()可能会触发该对象的回收,这显然不是我们想看到的局面。所以应该先执行retain()来保证other对象有效,然后再释放旧的对象
void SomeClass::setObject(CCObject* other)
{
other->retain();
this->object->release();
this->object = other;
}