关于在cocos2dx中继承Sprite的分析与技巧

本文章特指使用C++作为编程语言,基于cocos2dx游戏引擎开发游戏。

在cocos2dx中,sprite作为精灵类是使用最为频繁的类,与其它类相比,如:Node, Layer或Scene,Sprite最大的不同是它包含一个纹理,通过OpenGL的渲染,在游戏中呈现出来。游戏中的主角,怪物,背景,或是精灵的血条等都是通过Sprite来实现的。

在cocos2dx中,关于创建Sprite的类,根据输入参数的不同有以下几个工厂函数,

    static Sprite* create()
    static Sprite* create(const std::string& filename)
    static Sprite* create(const std::string& filename, const Rect& rect)
    static Sprite* createWithTexture(Texture2D *texture)
    static Sprite* createWithTexture(Texture2D *texture, const Rect& rect, bool rotated=false)
    static Sprite* createWithSpriteFrame(SpriteFrame *spriteFrame)
    static Sprite* createWithSpriteFrameName(const std::string& spriteFrameName)

顺便提醒,工厂函数中Sprite的实例都调用了autorelease(),所以由工厂函数返回的实例一般立即通过addChild到加入到父节点中,这样它的引用计数加一,表示有人在使用这个实例,这个实例不能被自动释放。当然,如果你不想立即加入到父节点中,也可以调用retain()函数直接对其引用计数加1,不然在主循环的下一次,就会将其回收,这是cocos2dx内存自动回收的机制决定的。

在游戏的开发过程中,使用Sprite最频繁的编码就是三部曲 (1)创建Sprite (2)加入layer中 (3)设置精灵位置:

Sprite *sprite = Sprite::create("hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));

第一行创建Sprite的实例,也就是创建了一个类Sprite的对象,这个是在工厂函数中实现的,

    Sprite *sprite = new Sprite();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;

我们重点关注第一句:

Sprite *sprite = new Sprite();

它决定了工厂函数创建的实例是Sprite类型,所以当在编码中调用Sprite的虚函数时,调用的就是Sprite类中的相应函数。

可能你会有这样一个问题:如果我想重载一个虚函数,在这个函数中实现自己需要的一些特殊行为,该怎么做?

答案是:必须继承Sprite创建一个你自己精灵类,在类中重载这个虚函数,这样还不够,必须定义这个新的继承类的工厂函数,在这个工厂函数中创建这个类的对象,

class MySprite : public Sprite
{
    static MySprite * create(const char *pszFileName);
}

MySprite * MySprite ::create(const char *filename)
{
    MySprite *sprite = new MySprite();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease(); return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

在程序中使用MySprite的代码与Sprite类似,

MySprite *sprite = MySprite::create("hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));

如果输入参数不同,可以参考Sprite类的实现,创建不同输入参数的工厂函数。

所以,按照目前cocos2dx的设计,在Sprite的继承类中,必须重新实现新类的工厂函数,在工厂函数中创建新类的实例,这样新类中重载的虚函数就会被调用到。

使用C++编程,经常需要继承Sprite来定制和封装游戏特定的精灵。有时候可能需要在Sprite的基础上进行多次继承,来达到类重用的目的。

本文下面提供两种方法,提供给读者参考。在这两种方法中,不需要在继承类中重新实现工厂函数。

  1. 在工厂函数中,实例作为输入参数传入
MySprite * MySprite ::create(Sprite* sprite, const char *filename)
{
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

调用MySprite的代码:

MySprite *sprite = new MySprite();
MySprite::create(sprite, "hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));

在MySprite的基础上再做继承时,就不需要实现工厂函数了。

例如:从MySprite继承新类MySprite2:

class MySprite2 : public MySprite
{
    ...
}

调用MySprite2的代码:

MySprite2 *sprite = new MySprite2();
MySprite::create(sprite, "hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));

2. 创建newInstance的虚函数

第二种方法,我们可以通过虚函数newInstance来避免重复创建工厂函数。在newInstance中创建新类的对象。

class MySprite : public Sprite
{
    Sprite* newInstance();
}

Sprite* MySprite::newInstance()
{
    return new MySprite();
}

调用MySprite的代码:

MySprite::create("hero.png");
this->addChild(sprite);
sprite->setPosition(Point(100, 200));

第二种方法的好处是在使用MySprite时与Sprite的完全相同,但需要在继承类中实现虚函数newInstance()。

本文抛砖引玉,在您的实现过程中也许会有更好的方法,欢迎讨论,共同进步。

关于在cocos2dx中继承Sprite的分析与技巧,布布扣,bubuko.com

时间: 2024-10-09 19:25:07

关于在cocos2dx中继承Sprite的分析与技巧的相关文章

Cocos2d-x中由sprite来驱动Box2D的body运动(用来制作平台游戏中多变的机关)

好久都没写文章了,就来一篇吧.这种方法是在制作<胖鸟大冒险>时用到的.<胖鸟大冒险>中使用Box2D来进行物理模拟和碰撞检測,因此对每一个机关须要创建一个b2body.然后<胖鸟>是依据<超级马里奥兄弟>设计的,所以机关能够是各种运动轨迹的平台,绕圈转的乌龟,蹦蹦跳的乌龟等.假设用box2d来做这些运动的话要自己写这些轨迹.可是Cocos2d-x已经提供了非常多的action,自己添加action也非常方便.反过来用sprite去设置box2d的b2body

JAVA学习(六):JAVA中的继承及其常见问题分析

JAVA中的继承及其常见问题分析 1.JAVA中继承的定义 JAVA中,类的继承是通过扩展其他类而形成新类来实现的,原来的类称为父类(Super Class)或基类,新的类称为原来类的子类或派生类.在子类中,不仅包含了父类的属性和方法,还可以增加新的属性和方法,从而使得父类的基本特征可被所有子类对象共享. 注:类的继承并不改变类成员的访问权限,也就是说,如果父类的成员是公有的.被保护的或默认的,它的子类仍具有相应的这些特性. /**********************************

cocos2d-x与ios内存管理分析(在游戏中减少内存压力)

Cocos2d-x与ios内存管理分析(在游戏中减少内存压力) 猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网--Cocos2Dev.com,谢谢! 年 原文地址: http://www.cocos2dev.com/?p=281 注:自己以前也写过Cocos2d-x如何优化内存的使用,以及内存不足的情况下怎么处理游戏.今天在微博中看到有朋友介绍了下内存,挺详细的.不知道是谁写的,我记录下. 一,iOS与图片内存 在iOS上,图片会被自动缩放到2的N次方大小.比如一张1024*102

Cocos2d-x中的基础概念

Cocos2d-x中的基础概念 尊重原创:http://cn.cocos2d-x.org/tutorial/show?id=1926 在你阅读本章节之前你可能知道一些关于Cocos2d-x的知识,但是你可能想知道更多关于如何使用Cocos2d-x来制作出自己梦想的游戏. 没问题,让我们从现在开始. Cocos2d-x是一个跨平台的游戏引擎.什么是游戏引擎?现在不要被这个问题吓到! 一个游戏引擎就是一个可以提供大多游戏常用功能的软件作品.你之前也许听到过将它称之为API或者框架.但在本书中我们会使

cocos2d-x 之 CCArray 源码分析

cocos2d-x 自己实现了一个数组CCArray ,下面我们来分析一下CCArray的源码 CCArray继承CCObject,所以,CCArray也具有引用计数功能和内存自动管理功能. 数组的源码如下: class CC_DLL CCArray : public CCObject { public: /************************************************************************/ /* 构造析构函数 */ /*******

cocos2dx Scene,Layer,Sprite的理解

layer,scene,sprite的默认锚点都是0.5,0.5 三者都继承自Node节点,暂时没看出有什么区别,或者下面的话是对的吧. 在cocos2d-x中,一个应用可以有多个scene,但任何时刻只能有一个是acitve的. 一个CCScene由多个CCNode组成,一般是包含若干个CCLayer,而CCLayer又包含多个CCSprite. 需要注意的是,CCScene,CCLayer和CCSprite都继承了CCNode,只不过后者还有其他的父类,使用多继承进行实现. 可以得知coco

cocos2d-x中的Box2D物理引擎

在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引擎的时候,大多数开发者会选择Box2D.Box2D是一款用来模拟刚体在物理世界运动的仿真引擎.通过Box2D物理引擎,世界中的物体就可以按照运动定律进行运动. 注:Box2D下的类都是以b2为前缀的,希望不要与你的命名相冲突 1. 首先我们介绍下需要用到的基本概念. 世界(world) :世界代表了

cocos2dx 中切换场景内存占用过高的处理

cocos2dx 中切换场景内存占用过高的处理 1.运行场景: CCScene *pScene = HelloWorld::scene(); pDirector->runWithScene(pScene); 2.替换场景: (1) CCScene *pScene=SceneTestScene::scene(); CCDirector::sharedDirector()->replaceScene(pScene); (2) CCScene *pScene=SceneTestScene::scen

cocos2d-x 中的基本概念

在 cocos2d-x 开头配置(Windows 平台)中,介绍了新建工程,这篇就介绍下 cocos2d-x 的一些概念.(前提是需要有C++的面向对象的基本知识和C++11的常用知识) 层,场景,导演,精灵,菜单 打开新建的工程(不管是VS,XCODE, Eclipse对 cocos2d-x 都一样),在 Classes 下找到 AppDelegate.h  AppDelegate.cpp  HelloWorldScene.h  HelloWorldScene.cpp 暂时先不管 AppDel