cocos2d-x 的两大基类

cocos2d-x 有两个重要的基类,一个管理引用计数的 Ref,别一个则定义许多基本属性的 Node

cocos2d-x 中的基本概念 说到 create 函数的时候提到 cocos2d-x 的内存管理机制。cocos2d-x 的内存管理机制借鉴了OC的内存管理机制,实现方法就是 Ref 这个类(去掉些碍眼的东西):

class Ref
{
public:
    // 保有
    void retain();
    // 释放
    void release();
    // 自动管理
    Ref* autorelease();
    // get 引用计数
    unsigned int getReferenceCount() const;
protected:
    Ref();
public:
    virtual ~Ref();
protected:
    // 引用计数
    unsigned int _referenceCount;
    friend class AutoreleasePool;
};

类很简单,只有一个字段:

unsigned int _referenceCount;

保存当前对象有多少个引用,创建对象时初始化为 1,当等于 0 时会自动调用析构函数释放内存;

四个函数也很简单, retain release 分别是在原引用计数上+1-1,保存对象时需要 retain, 不需要保存时 release,引擎有封装的数据容器,可以避免忘记 retain release,所以一般情况下用不到。

Ref* autorelease();

只在创建对象时调用一次,添加到内存池内,在引用计数为 0 时自动释放内存;在默认的 create 函数中都有调用,自己写 create 时也要记得调用。

最后一个函数就是获取当前的引用计数,见名知意。

Ref 几乎是所有类的父类,除了一些简单的数据类,所以在许多回调函数中使用Ref 作参数,可以在回调函数内使用动态类型转化为原来的类型。

Node 是个内容很多的类,挑出一些常用的来看:

class Node : public Ref
{
public:
    static Node * create();
    
    virtual void addChild(Node * child);
    virtual void addChild(Node * child, int localZOrder);
    virtual void addChild(Node* child, int localZOrder, int tag);
    virtual void addChild(Node* child, int localZOrder, const std::string &name);
    
    void scheduleUpdate(void);    
    virtual void update(float delta);
    virtual void onEnter();
    virtual void onExit();
protected:
    // Nodes should be created using create();
    Node();
    virtual ~Node();
    virtual bool init();
protected:
    float _rotationX;   //旋转 以X轴 
     float _rotationY;   //旋转 以Y轴
    
     float _scaleX;      //放缩 X Y Z
    float _scaleY;
    float _scaleZ;   

    float _skewX;       // 倾斜 X Y
    float _skewY;

    Vec2 _position;    //位置
    Vec2 _anchorPoint; //锚点   

    Size _contentSize; //大小尺寸

    int _localZOrder;  //本地渲染顺序
    float _globalZOrder;    //全局渲染顺序

    int _tag;           //标签
    std::string _name;  //名字

    bool _running; //是否运行 
    bool _visible; //是否可见 
 
    Vector<Node*> _children;    //子节点
    Node *_parent;              //父节点
    
    Director* _director;                // 导演
    Scheduler *_scheduler;              // 定时器
    ActionManager *_actionManager;      // 动作管理器
    EventDispatcher* _eventDispatcher;  // 监听管理器
}

上面的属性基本都有 set get 方法(下面有几个没有);旋转,放缩,倾斜 可以改变节点的形状;位置 节点在屏幕中的位置,父节点的位置影响子节点的位置 ;锚点 影响自身变形的效果; 大小 节点在屏幕中的矩形大小,一般同显示的图片,字体大小相同,可以更改;本地渲染顺序 影响兄弟节点的渲染顺序, 全局 影响所有节点 , 两个都是值大的, 显示在上面,值小的会被挡到,全局赋盖本地; 标签, 名字都是作标记用,便于快速找到标记的节点,用法相同,函数不同而已; 子节点 可以有多个,父节点只有一个,后面的 导演,定时器,动作 监听管理器在游戏初始化完成就有了,Node 构造时引用这些,合理利用这些已有的指针引用可以写出简捷,高效的代码。

属性挑出来的就有这么多,对应的方法就更多了,这里只拿 addChild 举个例子, addChild 有四个重载,必不可少的是 Node 节点,次之是本地渲染顺序,最后是用标签或名字打个标记, 这样的参数顺序并不一定合你意,没什么,用其他函数修改就行,你也可以给 Node 在添加两个函数,在cocos2d-x 开头配置(Windows 平台)中说过,新建项目会拷贝整个引擎,在一个项目里修改源码不影响其他项目,如果你觉得添加的功能十分实用,有必要保留下来,可以到Github上提交代码。

另外有几个有用的函数

virtual void update(float delta);

每帧调用,某些需要即时处理的内容可以重写这个函数把需要处理代码放在这里,但要在其他函数里调用scheduleUpdate(),不然不会执行。

virtual void onEnter();

virtual void onExit();

这两个是即将进入,离开节点是调用,处理一些运行时态度方便,自动调用。

这三个函数需要注意的量 : 在重写的代码里调用父类的updateonEnteronExit 不然会出意想不到的问题。

create init 函数是从 Node 类开始的,init 中调用的父类的 init 最终会来到这个类,Node 类的 init 只返回 true;

bool Node::init()
{
    return true;
}

Ref 是大部分类的基类方便管理内存,常用作函数参数,可转化为原类型

Node 类提供了大量的属性,虚函数,提高代码重用,减少程序员的重复劳动

作者:H·K
出处:http://www.cnblogs.com/pythian/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。
原文地址:https://www.cnblogs.com/pythian/p/4614268.html