学习cocos2dx就要了解它最基础的东西,那就是纹理和精灵。
1.CCTexture2D
为什么先讲CCTexture2D呢,因为我觉得这个是cocos2dx最基础的一个对象,就是纹理贴图,因为我们看到的所有东西都是由一张张纹理构成的。
CCTexture2D是贴图纹理,是缓存到GPU中的图片数据。它是cocos2d-x渲染图形的重要参数,用来贴图,因为cocos2d-x使用opengl es绘制2d图形的,它的尺寸是2的n次方。
CCTexture2D* cache = CCTextureCache::sharedTextureCache()->addImage("hero.png");
2.CCSprite
CCSprite是显示到场景中的精灵,是被实际画出来的东西,它是CCNode的子类,它的内部封装了CCTexture2D(纹理)。
CCSprite的创建:
一般我们通过CCSprite提供的工厂方法来创建CCSprite对象,而CCSprite提供了不止一个这样的方法,我们分别来看:
1.最简单的create(),该方法不带任何参数,通过它可以返回一个不带纹理的空CCSprite对象,当然创建成功之后你可以调用CCSprite对象的初始化方法进行初始化。
CCSprite * pSprite = CCSprite::create();
2.通过指定图片文件名来创建create(const char * pszFileName),该方法的参数是图片文件的资源位置。
CCSprite * pSprite = CCSprite::create("test.png");
CCRect rect; rect.setRect(0,0,100,100); CCSpriteFrame * pFrame = CCSpriteFrame::create("test.jpg",rect); CCSprite * pSprite3 = CCSprite::createWithSpriteFrame(pFrame);
CCImage * image = new CCImage(); image->initWithImageFile("test.jpg",CCImage::kFmtJpg);//指定图片路径和图片格式 CCTexture2D * tex = new CCTexture2D(); tex->initWithImage(image);
CCSprite * pSprite2 = CCSprite::createWithTexture(tex);
CCRect rect; rect.setRect(0,0,100,100); CCSprite * pSprite2 = CCSprite::createWithTexture(tex,rect);
CCRect rect; rect.setRect(0,0,100,100); CCSpriteFrame * pFrame = CCSpriteFrame::create("test.jpg",rect); CCSprite * pSprite3 = CCSprite::createWithSpriteFrame(pFrame);
bool initWithTexture(Texture2D* pobTexture, const Rect& rect); bool initWithTextureFilename(const std::string& filename, const Rect& rect); bool initWithTexture(Texture2D* pobTexture, const Rect& rect, bool rotated, const Vec2& offset, const Size& originalSize);
所以CCSpriteFrame都是他用过Texture2D来初始化的,然后再创建Sprite供我们用。
比如我们要利用打包的plist图集的一张图片来创建精灵。
就像上面的,我们那就需要使用Sprite:createWithSpriteFrameName(‘’)来创建或者先创建一个SpriteFrame来创建Sprite了。
CCSprite也可以用来定义动画层的每一帧,定义好厚以CCAction的形式作用到一个CCSprite上来呈现动画效果
CCTexture2D和CCSpriteFrame都是我们看不到的,我们真正能看到的应该是CCSprite,也就是最终呈现在游戏界面内的。
是用于提高精灵渲染速度的技术。它可以提高渲染大量相同精灵的速度,不过它同纹理贴图集配合使的效率最高。如果你将纹理贴图集与精灵批处理配合使用的话,你只要调用一次渲染方法就可以完成纹理贴图集里所有图片的渲染。
“渲染方法调用”(draw call)是把必要的信息传递给图形处理硬件以完成整个或者部份图片渲染的过程。当你使用CCSprite的时候,每生成一个CCSprite节点都会调用一次渲染方法。每一次渲染方法调用导致的系统开销叠加起来会使游戏的帧率大约降低15%或者更多(除非你使用CCSpriteBatchNode,它的作用是作为一个额外的层用于添加多个精灵节点。前提是这些精灵节点使用的是同一个纹理贴图)。
CCSpriteBatchNode
每次系统在屏幕上渲染一张贴图时,图形处理硬件必须首先准备渲染,然后渲染图形,最后在完成渲染以后进行清理。上述过程是每一次在启动渲染和结束渲染之间存在的固定系统开销。如果图形处理硬件知道你需要使用同一张纹理贴图渲染一组精灵的话,图形处理硬件将只需要为这一组精灵执行一次准备,渲染,最后清理的过程了。
你可以看到屏幕上有几百个相同的子弹。如果你逐个渲染它们的话,你的游戏帧率将会下降至少15%。如果你使用CCSpriteBatchNode,你就可以避免帧率的下降。
把使用同一张纹理贴图的一组CCSprite节点添加到同一个CCSpriteBatchNode里,比逐个渲染CCSprite要高效很多。
以下是生成CCSprite的常用代码:
CCSprite *sprite=CCSprite::create("sprite.png"); this->addChild(sprite);
CCSpriteBatchNode *node=CCSpriteBatchNode::create("s1.png"); this->addChild(node); for(int i=0;i<100;i++){ CCSprite *sprite=CCSprite::create("s1.png"); node->addChild(sprite); }
Texture2D * TextureCache::addImage(const std::string &path) { Texture2D * texture = nullptr; Image* image = nullptr; std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path); if (fullpath.size() == 0) { return nullptr; } auto it = _textures.find(fullpath); if( it != _textures.end() ) texture = it->second; if (! texture) { // all images are handled by UIImage except PVR extension that is handled by our own handler do { image = new (std::nothrow) Image(); bool bRet = image->initWithImageFile(fullpath); CC_BREAK_IF(!bRet); texture = new (std::nothrow) Texture2D(); if( texture && texture->initWithImage(image) ) { // texture already retained, no need to re-retain it _textures.insert( std::make_pair(fullpath, texture) ); } } while (0); } return texture; }
6.CCSpriteFrameCache
CCSpriteFrameCache精灵帧缓存类,它是管理CCSpriteFrame的内存池,跟CCTextureCache功能一样,不过跟CCTextureCache不同的是,如果内存池中不存在要查找的帧,它会提示找不到,而不会去本地加载图片。它的内部封装了一个字典:CCDictionary *m_pSpriteFrames,key为帧的名称。通过.plist和.png图片来缓存了一些CCSpriteFrame的对象,这个类解决碎图问题,大大提高了效率,通过一些工具把一些碎图(小图片)整合到一张大图片中,通过加载一次贴图纹理,就把所有的整合到大图中的图片加载了进去,缓存到CCSpriteFrameCache 对象中,以后就可以通过碎图的名字,从CCSpriteFrameCache 对象中获取精灵帧对象。 然后可以使用获取的精灵帧做其他处理。