您的位置:首页 > 移动开发 > Cocos引擎

撸到猴年马月之保卫萝卜(一)cocos2d-x 基本概念

2014-02-15 16:05 483 查看
抄书的笔记来的。

1 一般游戏都有的流程


 
  通常我们把内容相对不变的游戏元素称为场景Scene。在cocos2dx中,场景的实现是CCScene。
 
2 层是隶属于场景之下的游戏元素。通常,一个复杂场景拥有多个层,一个层会显示一部分视觉元素,空白部分为透明或者半透明,以实现多个层的重叠显示。层与层之间按照顺序叠放在一起,组成了一个复杂的场景。
  以捕鱼场景为例,场景可以大致分为4层。
  菜单层,触摸层,动作层,背景层。
  在Cocos2d-x中,层的实现是CCLayer。
  
3 精灵隶属于层。玩家控制的主角,AI的控制NPC,地图上的宝箱、石块,甚至游戏的背景图片都是精灵。通常,一个精灵可以不断的变化:移动、旋转、缩放、变形、显示消失、动画效果。


 
  在Cocos2d-x中,精灵的实现是CCSprite。
  
4 渲染树


 
渲染场景的过程就是遍历渲染树的过程。
一旦建立起渲染树,组织复杂的场景就变得十分简单。
例如海龟:


 
建立一个节点表示海龟,在海龟节点下再建立5
4000
个精灵,表示腿和躯干。这样,每个动作都是可控的,只要为每个节点设置好了动作,就可以完成复杂的动画。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息