• 7、Cocos2dx 3.0游戏开发找小三之3.0版本号的代码风格


    重开发人员的劳动成果,转载的时候请务必注明出处http://blog.csdn.net/haomengzhu/article/details/27691337

    Cocos2d-x代码风格
    前面我们已经多次提到 Cocos2d-x 源自于 Cocos2d-iPhone。Cocos2d-iPhone 是一个十分出色的游戏引擎,很多优秀的 iOS平面游戏都基于 Cocos2d-iPhone 开发。而它的实现语言是 Objective-C。因此,Cocos2d-x 也就沿袭了 Objective-C 的代码风格。 
    这么做的主要原因例如以下:
    出于对 Cocos2d-iPhone 程序猿习惯的照应,以及对该引擎的尊敬。 
    方便不同语言下 Cocos2d游戏的移植。
    为了实现 Objective-C 风格的内存管理,要求引擎採用特殊的命名规范。


    接下来我们将具体介绍 Cocos2d-x 的代码风格。


    命名空间与类名称
    Cocos2d-x 拥有一个包括其它所有头文件的文件"cocos2d.h"。通常。我们仅仅须要在使用时包括这个头文件,就能够使用引擎的所有功能了。

    Cocos2d-x 的类都放置于 cocos2d 命名空间下。以引擎文件夹下的"cocos/2d/CCLayer.h"为例,我们能够看到文件的首位有两个宏:NS_CC_Begin 和 NS_CC_END。

    查看宏的定义可知,这两个宏相当于把全部的类型都包括在了 cocos2d 命名空间下。

    游戏中。我们常使用引擎提供的还有一个宏 USING_NS_CC 来引用 cocos2d 命名空间:
    #define USING_NS_CC using namespace cocos2d

    类的命名与 Cocos2d-iPhone 一致,由类库缩写加上类名称组成,当中类库缩写採用大写,类名称採用驼峰法。
    Cocos2d 2.0的 缩写是 CC,因此 Cocos2d-x 2.0的类都拥有 CC 前缀。比如表示动作的类就叫做 CCAction。

    相比于Cocos2d 2.0,Cocos2d 3.0更简洁;

    从此不再见到以CC开头的类,由于CC被废掉了,而且定义的时候用auto;

    举个样例:
    v2.2  
    CCSprite* sprite=CCSprite::create();  
    v3.0  
    auto sprite=Sprite::create();

    若想了解很多其它信息,官方站点上有 3.X 2.X 之前的差异说明:
    cocos2d-x 3.0 与cocos2d-x 差异说明链接

    构造函数与初始化
    在 Cocos2d-x 中创建对象的方法与 C++开发人员的习惯迥乎不同。 在 C++中。 我们仅仅须要调用类的构造函数就可以创建一个对象,既可直接创建一个栈上的值对象。也能够使用 new 操作符创建一个指针,指向堆上的对象。

    而在 Cocos2d-x 中,不管是创建对象的类型,还是创建对象的方法都与 C++不同。


    Cocos2d-x 不使用传统的值类型,全部的对象都创建在堆上。然后通过指针引用。
    创建 Cocos2d-x 对象通常有两种方法:
    一种是首先使用 new 操作符创造一个未初始化的对象,然后调用 init 系列方法来初始化;
    另外一种是使用静态的工厂方法直接创建一个对象。

    以下我们首先介绍第一种方法。


    在 Objective-C 中并没有构造函数。创建一个对象须要先为对象分配内存。然后调用初始化方法来初始化对象,这个过程就等价于 C++中的构造函数。 
    与 Objective-C 一样。 Cocos2d-x 也採用了这个步骤。

     

    Cocos2d-x 类的构造函数通常没有參数,创建对象所需的參数通过 init 开头的一系列初始化方法传递给对象。

    创建对象的过程例如以下所看到的。
    使用 new 操作符调用构造函数,创建一个没有初始化过的空对象。
    选择合适的初始化方法,并调用它来初始化对象。

    Cocos2d-x 的初始化方法都以 init 作为前缀。因此能够轻易辨认出来。

    初始化方法返回一个布尔值,代表是否成功初始化该对象。


    以下我们提供一个从文件初始化精灵(CCSprite)的样例:
    auto sprite1 = new CCSprite();
    sprite1->initWithFile("bg.png");

    在这个样例中。我们首先调用构造函数创建一个未经初始化的 Sprite 对象。然后在 Sprite 提供的初始化方法中选择了从文件创建精灵的初始化方法 Sprite::initWithFile(const char* filename)来初始化精灵。

    另外一种方法则是使用类自带的工厂方法来创建对象。
    在 Cocos2d-x 中。很多类会自带一系列工厂方法,这些工厂方法是类提供的静态函数。

    仅仅要提供必要的參数,就会返回一个完毕了初始化的对象。
    通常 init 系列的初始化方法都会有其相应的工厂方法。它们的名称类似。參数一致,都能够用于创建对象。
    在 Cocos2d-x 的旧版本号中,工厂方法通常以类的名称(不包括前缀)开头,
    而在 Cocos2d-x 2.0 及兴许版本号中,工厂方法的名称统一为 create。
    在名称冲突的情况下,也可能採用以 create 作为前缀的其它函数名。

    我们仍然以创建精灵为例,以下的两条语句等价。
    前者为引擎旧版本号中的方法,后者为新版本号中的方法,它们都会创建一个与第一种方法所述类似的精灵:
    Sprite* sprite2 = Sprite::spriteWithFile("bg.png");
    Sprite* sprite3 = Sprite::create("bg.png");

    这两种方法都能够创建 Cocos2d-x 对象,然而它们在内存管理方面还是有一点点差异的。
    使用构造函数创建的对象。它的全部权已经属于调用者了,使用工厂方法创建的对象的全部权却并不属于调用者,
    因此,使用构造函数创建的对象须要调用者负责释放,而使用工厂方法创建的对象则不须要。

    在游戏中。我们须要不断地创建新的游戏元素,通常採取的方法是从 Cocos2d-x 提供的游戏元素类派生出新的类,并在初始化方法中建立好我们所需的游戏元素。

    这个过程与微软.NET 框架下的 Windows Form 开发类似。

    比如在 Hello World 中,我们从 Layer 类派生出 HelloWorld 类 (这是一个层) , 并重载了 HelloWorld 类的 init()方法, 在这种方法中为 HelloWorld层加入内容。

    为了保证初始化方法能够被子类重载,须要确保初始化方法声明为虚函数:
    virtual bool init();
    作为參考,我们提供一个典型的 init()方法框架例如以下:
    bool init()
    {
     if(Layer::init())
    
    {
    //在此处写入初始化这个类所需的代码
    return true;
    }
    return false;
    }

    选择器
    在 Objective-C 中,选择器(Selector)是类似于 C++中的类函数指针的机制。
    因为 Cocos2d-x 继承了 Cocos2d-iPhone 的代码风格,因此也提供了一系列类似于 Objective-C 中创建选择器语法的宏,用来创建函数指针。
    这些宏都仅仅有一个參数SELECTOR,表示被指向的类方法。

    在Cocos2d-x2.0中将这些宏列举例如以下:
    schedule_selector(SELECTOR)
    callfunc_selector(SELECTOR)
    callfuncN_selector(SELECTOR)
    callfuncND_selector(SELECTOR)
    callfunc_selector(SELECTOR)
    menu_selector(SELECTOR)
    event_selector(SELECTOR)
    compare_selector(SELECTOR)

    从3.0開始。事件回调函数由原来的schedule_selector和menu_selector等变成CC_CALLBACK_0、CC_CALLBACK_1、CC_CALLBACK_2、CC_CALLBACK_3。

    以下我们来看第 1 章中的 Hello World 样例。
    在这个样例中,我们在 HelloWorld 类的 init()方法中加入了一个菜单,当用户点击该菜单时。就会触发此类中的 menuCloseCallback()方法。
    能够看到,初始化菜单的后两个參数各自是被调用对象与Cocos2d-x 选择器:
     auto closeItem = MenuItemImage::create(
                                            "CloseNormal.png",
                                            "CloseSelected.png",
                                            CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));

    当中CC_CALLBACK_1宏是将函数与对象绑定在一起,1表示这个函数有一个參数。当点击这个button时。会调用这个回调函数。

    除了基于c++11的这个形式的改变,用法与先前同样。


    属性
    C++的类成员仅仅有方法与字段,没有属性和事件,这给开发人员带来了不便。
    为了实现 Objective-C 中提供的属性功能,我们不得不用法来模拟 get 和 set 訪问器。
    Cocos2d-x 规定了属性訪问器的方法名称以 get 或 set 为前缀,后接属性名。
    在 Node 中包括大量属性,
    比如用于给节点做标记的 Tag 属性,它的訪问器分别为 getTag()和 setTag(int aTag),
    事实上现原 理大致例如以下: 
    int _tag; ///< a tag. Can be any number you assigned just to identify this node
    virtual int getTag() const;
    virtual void setTag(int aTag) 
        
    /// tag getter
    int Node::getTag() const
    {
        return _tag;
    }
        
    /// tag setter
    void Node::setTag(int var)
    {
        _tag = var;
    }

    在这个样例中。属性的类型是 int,处理较为简单。

    当涉及到内存管理。开发中我们对数值类型、结构体类型、Cocos2d-x对象的处理方法都不尽同样。

    为每个属性编写一个或两个訪问器方法是一项十分枯燥的任务,为了避免反复性的工作。Cocos2d-x 提供了一系列宏来帮助我们方便地创建属性。
    下表列举了全部属性相关的宏。它们定义在引擎文件夹中的"cocosaseCCPlatformMacros.h"中。

    Cocos2d-x 3.0中与属性相关的宏


    这些宏仅仅要写在类的定义之中就可以。
    每一个宏都有 3 个參数,各自是:varType,属性类型,假设属性类型是对象,须要写成指针的形式;
    varName。属性的私有字段名称。funName,属性的訪问器名称,也就是紧接在 get 或 set 前缀后的部分。
    利用 Cocos2d-x 提供的宏,以Layer为例。Layer属性定义就能够用以下一条语句取代了:
    CC_SYNTHESIZE(cocos2d::Layer*, m_pLayer, Layer);

    单例
    相对于前面的内容,单例(singleton)则是一个非常易于理解的概念。
    在 Cocos2d-x 引擎中,我们能看到大量单例的身影,它们大部分出如今一些系统资源管理类中。
    单例模式保证了全局有且仅仅有一个实例对象,保证自己主动地初始化该对象,
    使得程序在不论什么时候不论什么地方都能够訪问、获取该对象。

    比如,Cocos2d-x 3.0的游戏流程控制器 Director 是一个独一无二的控制器,用于切换游戏场景。
    换句话说。不可能同一时候存在两个 Director 实例。

    在这样的情况下, Cocos2d-x 採用了单例的技巧。

     

    用户能够通过类提供的静态方法获取独一无二的实例。 而不须要自己来创建。

    观察 Director 的代码:
    // singleton stuff
    static DisplayLinkDirector *s_SharedDirector = nullptr;
    Director* Director::getInstance()
    {
        if (!s_SharedDirector)
        {
            s_SharedDirector = new DisplayLinkDirector();
            s_SharedDirector->init();
        }
    
        return s_SharedDirector;
    }

    能够发现,Director 维护了一个静态的 Director 实例,在第一次使用前初始化。
    为了訪问 Director 控制器,我们能够使用例如以下代码:
    Director::getInstance()->replaceScene(newScene);
    这条语句使用 Director::getInstance()获取 Director的唯一实例,然后调用 replaceScene 来切换到新场景。

    郝萌主友情提示:
    熟悉新风格,新特性,使用cocos2d-x引擎会更方便噢、、、
  • 相关阅读:
    Python的运算符
    RabbitMQ 的配置文件
    安装新版本的rabbitmq
    Ubuntu 16.04 安装rabbitmq
    Python Web 版本tailf, grep
    解决pycharm问题:module 'pip' has no attribute 'main'
    Python argparse
    Ansible 并行和异步
    cef相关
    浏览器透明设置例子,qt5.6才支持
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5265109.html
Copyright © 2020-2023  润新知