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();

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

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

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

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

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

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

时间: 2024-12-12 23:05:31

cocos2d-x 的两大基类的相关文章

Java入门到精通——框架篇之Spring源码分析Spring两大核心类

一.Spring核心类概述. Spring里面有两个最核心的类这是Spring实现最重要的部分. 1.DefaultListableBeanFactory 这个类位于Beans项目下的org.springframework.beans.factory.support包下. XmlBeanFactory(位于org.springframework.beans.factory.xml包)继承自DefaultListableBeanFactory,而DefaultListableBeanFactory

4.5. scrapy两大爬虫类_Spider

一:Spider Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取 的动作及分析某个网页(或者是有些网页)的地方. class scrapy.Spider是最基本的类,所有编写的爬虫必须继承这个类. 主要用到的函数及调用顺序为: __init__() : 初始化爬虫名字和start_urls列表 start_requests() 调用make_requests_fro

【转载】 C++多继承中重写不同基类中相同原型的虚函数

本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: virtual void TestA(); }; class CBaseB { public: virtual void TestB(); }; class CDerived : public CBaseA, public CBaseB { public: virtual void TestA()

C++的虚基类知识点

当在多条继承路径上有一个公共的基类,在这些路径的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类. class x1:virtual public x{//... ...};class x2:virtual public x{//... ...};虚基类的初始化 虚基类(虚拟继承)的初始化与一般多继承的初始化在语法上是一样的,但构造函数的调用次序不同. 派生类的构造函数的调用次序有三个原则:(1)虚基类的构造函数在非虚基类之

【c++】虚基类

何要使用虚基类: 为何避免多层继承中出项多个公共基类所造成的歧义现象 虚基类用法 派生类继承基类时,加上一个virtual关键词则为虚拟基类继承. 在上图程序运行中,我们发现class bass的构造函数只调用了一次,因此obj.a就不会产生二义性了. 问题1: 在这我们要特别留意下obj.a的结果123,为何它不是122也不是124,偏偏是123呢? 构造函数调用的顺序: 从结果可以看出,从最底层派生类grand开始查找,我们发现grand先调用虚基类derive_v的构造函数:对derive

重拾C++之虚函数和虚基类以及抽象类

一.引言 好久没接触过C++了,今天突然要用一点感觉号蛋疼,用惯了python感觉C++一点都不会了. 声明了一个类的对象居然用这种方法,脑子绝对是被驴(python)踢了 class A{  ...  }  a=A();//尼玛这都能行,被踢大了 二.虚函数和一般函数 虚函数就是加了vritual关键字的函数,引入虚函数的目的是为了实现多态性(在此为运行时的多态性),即可以通过父类的指针调用子类的对象,从而产生不同的效果.     virtual void show(){         co

4.2.1 Codec基类

在codecs模块里定义了与codec对象进行交互的接口,也可以使用它作为其它编解码的基类. 在Python里要求codec对象需要有四个接口:无状态的encoder,无状态的decoder,StreamReader和StreamWriter.而StreamReader和StreamWriter通常是由无状态的encoder/decoder通过文件协议来实现.同时codec对象还需要处理在编码和解码里出现的错误. 4.2.1.1 错误处理 codecs模块通过errors字符串参数来实现不同的错

面向对象--多继承&amp;派生类对象内存布局分析&amp;各基类指针所指向的位置分析

背景 原文链接:ordeder  http://blog.csdn.net/ordeder/article/details/25477363 关于非虚函数的成员函数的调用机制,可以参考: http://blog.csdn.net/yuanyirui/article/details/4594805 成员函数的调用涉及到面向对象语言的反射机制. 虚函数表机制可以查看下面这个blog: http://blog.csdn.net/haoel/article/details/1948051 总结为: 其一

asp.net mvc webform和razor的page基类区别

接触过asp.net mvc的都知道,在传统的webform的模式下,page页面的基类是这样声明的: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage" %> 如果是partial view的话,则是这样声明的: <%@ Control Language="C#" Inherits=&q