cocos2dx--CCSprite,CCSpriteFrame,CCTexture,CCSpriteBatchNode
学习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 * pSprite = CCSprite::create(); 2.通过指定图片文件名来创建create(const char * pszFileName),该方法的参数是图片文件的资源位置。 CCSprite * pSprite = CCSprite::create("test.png"); 3.通过指定图片文件名并给出图片显示区域create (const char *pszFileName,const CCRect &rect),第二个参数是CCRect对象的引用。 CCRect rect; rect.setRect(0,100,100); CCSpriteFrame * pFrame = CCSpriteFrame::create("test.jpg",rect); CCSprite * pSprite3 = CCSprite::createWithSpriteFrame(pFrame); 4.通过指定CCTexture2D材质对象来创建createWithTexture (CCTexture2D *pTexture),这里的参数类型是一个我们之前没见过的类。我们知道Cocos2d是基于显卡编程的,因此在创建显示对象时,我们实际上是通过纹理贴图来让它们拥有丰富的显示内容的。实际上纹理贴图才是CCSprite对象的内部显示原理,而之前的两个方法只是将纹理对象的创建封装到了内部。 为了创建纹理,我们首先需要一个CCImage对象,具体见下: CCImage * image = new CCImage(); image->initWithImageFile("test.jpg",CCImage::kFmtJpg);//指定图片路径和图片格式 CCTexture2D * tex = new CCTexture2D(); tex->initWithImage(image); 这样一个纹理便可用了: CCSprite * pSprite2 = CCSprite::createWithTexture(tex); 5.通过上面的方法创建出来的CCSprite对象的显示区域为整个纹理,通过createWithTexture (CCTexture2D *pTexture,const CCRect &rect)方法可以给CCSprite对象指定显示区域: CCRect rect; rect.setRect(0,100); CCSprite * pSprite2 = CCSprite::createWithTexture(tex,rect); 6.最后我们来看通过CCSpriteFrame对象创建CCSprite的两个方法:createWithSpriteFrame (CCSpriteFrame *pSpriteFrame)和createWithSpriteFrameName (const char *pszSpriteFrameName),其实主要是前一个方法。 这里的关键是CCSpriteFrame是什么?CCSpriteFrame拥有一个纹理对象(CCTexture2D)和一个矩形对象(CCRect),我们可以将它理解为CCSprite和CCTexture2D的中间者,CCSprite通过CCSpriteFrame来了解需要显示的内容以及显示的区域。具体地: CCRect rect; rect.setRect(0,rect); CCSprite * pSprite3 = CCSprite::createWithSpriteFrame(pFrame); 3.CCSpriteFrame CCSpriteFrame是相对于动画来说的概念,代表动画中“帧”,CCSpriteFrame 是贴图纹理CCTexture2D中某块区域,或者这个贴图纹理。 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,也就是最终呈现在游戏界面内的。
4.CCSpriteBatchNode 是用于提高精灵渲染速度的技术。它可以提高渲染大量相同精灵的速度,不过它同纹理贴图集配合使的效率最高。如果你将纹理贴图集与精灵批处理配合使用的话,你只要调用一次渲染方法就可以完成纹理贴图集里所有图片的渲染。 CCSprite *sprite=CCSprite::create("sprite.png"); this->addChild(sprite); 当然,向CCSpriteBatchNode添加一个CCSprite节点不会有任何效率上的提高。 接下来,我把许多使用同一张纹理贴图的精灵节点添加到了同一个CCSpriteBatchNode里 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); } CCSpriteBatchNode的作用很像CCLayer,因为它本身并不显示在屏幕上。不过你只能把CCSprite加入CCSpriteBatchNode。CSpriteBatchNode将一个图片文件名作为参数,使用这个参数的原因是所有被添加进CCSpriteBatchNode的CCSprite节点都必须使用同一个图片文件。如果你没有在CCSprite中使用相同的图片,你将会在调试窗口中得到报错信息。 什么时候应该使用CCSpriteBatchNode? 当你需要显示两个或者更多个相同的CCSprite节点时,你可以使用CCSpriteBatchNode。组合在一起的CCSprite节点越多,使用CCSpriteBatchNode得到的效果提升就越大。 不过也有一些限制。因为所有的CCSprite节点都添加到同一个CCSpriteBatchNode中,所以所有CCSprite节点都会使用相同的z-order(深度)来渲染. 另一个缺点是所有添加到同一个CCSpriteBatchNode中的CCSprite节点必须使用同一个纹理贴图。不过那也意味着CCSpriteBatchNode非常适合使用纹理贴图集。使用纹理贴图集的时候,你不仅仅局限于渲染一张图片;你可以把不同的图片放到同一个纹理贴图集中,然后利用CCSpriteBatchNode将所有图片渲染出来,以提高渲染速度。 5.CCTextureCache CCTextureCache贴图纹理缓存类,这个类可以把一些图片加载到GPU之后,缓存起来,以后直接取就可以了。它相当于CCTexture2D的容器,是内存池,用来缓存CCTexture2D对象的,它内部有一个字典CCMutableDictionary m_pTextures,key为图片的名称,值是CCTexture2D。当调用它的addImage函数添加图片时,会先根据图片名称去内存中查找是否已存在,是则直接取出返回。下面是addImage部分源码: 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |