【唠叨】

本来是想学学控件类CCControl的另一个子类按钮控件CCControlButton的。但是发现里面有一个参数牵扯到CCScale9Sprite这个类。看到CCScale9Sprite,很容易联想到精灵类CCSprite。两者又有什么区别呢?因此我就去网上收了一些有关CCScale9Sprite的资料来学习。


【致谢】

http://blog.csdn.net/zaojiahua/article/details/21295535

http://blog.csdn.net/onerain88/article/details/8273219


【Demo下载】

https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E7%82%B9%E4%B9%9D%E5%9B%BECCScale9Sprite


【3.x】

(1)去掉“CC”

(2)其他几乎无变化。


【v3.3】

我们在ui模块下实现了一个新的Scale9Sprite类。它的内部实现比之前的Scale9Sprite更为简洁,功能也更为强大。

重新实现这个类的主要的原因是:Scale9Sprite在UI模块被大量使用。

现在UI模块不再依赖于extension模块。 通过采用全新的ui::Scale9Sprite,很多部件类内部的代码更加简洁,优雅。




【CCScale9Sprite】

对于CCScale9Sprite类,不知道该怎么翻译,有人叫它点九图,有人叫它九宫图,有有人叫它九妹图。

那么什么是CCScale9Sprite呢?CCScale9Sprite对象,是一种CCSprite对象的变形,它的用法和CCSprite类似,不同点是:CCScale9Sprite对象有个特性就是缩放贴图时可以尽量不失帧。

如下图所示,用普通的CCSprite拉伸后四个角模糊失真了,而是用CCScale9Sprite进行拉伸后,依旧很清晰。


1、原理

CCScale9Sprite的实现非常巧妙,是通过1个CCSpriteBatchNode和9个CCSprite来实现的,原理很简单,通过将原纹理资源切割成9部分(PS: 这也是叫九宫图的原因),根据想要的尺寸,完成以下的三个步骤:

(1)保持4个角部分不变形

(2)单向拉伸4条边(即在4个角两两之间的边,比如上边,只做横向拉伸)

(3)双向拉伸中间部分(即九宫图的中间部分,横向,纵向同时拉伸,PS:拉伸比例不一定相同)

CCSpriteBatchNode的资源为整个的纹理,9个CCSprite对应于纹理的9个部分(根据纹理不同,9部分所占比例会有所不同),根据想要的尺寸,将9部分拼装在一起!


2、需要引用的头文件及命名空间

//#include"cocos-ext.h"//包含cocos-ext.h头文件usingnamespacecocos2d::extension;//引用cocos2d::extension命名空间//


3、常用操作

CCScale9Sprite继承于CCNodeRGBA,所以除了可以使用以下自定义的操作外,还可以使用节点类CCNode、以及节点颜色类CCNodeRGBA的相关函数操作。

///************************************************************************//*以上面原理部分提到的图片为例*//************************************************************************/classCCScale9Sprite:publicCCNodeRGBA{/***创建的三类方式*create,createWithSpriteFrame,createWithSpriteFrameName*///使用图片资源名来创建//参数说明://rect整个图的矩形大小//capInsets中间部分区域对应的矩形大小//rect=CCRectMake(0,0,80,80);//capInsets=CCRectMake(12,12,56,56);//create("sp.png",rect,capInsets);//create(capInsets,"sp.png");staticCCScale9Sprite*create(constchar*file);staticCCScale9Sprite*create(constchar*file,CCRectrect);staticCCScale9Sprite*create(constchar*file,CCRectrect,CCRectcapInsets);staticCCScale9Sprite*create(CCRectcapInsets,constchar*file);//使用精灵帧来创建staticCCScale9Sprite*createWithSpriteFrame(CCSpriteFrame*spriteFrame);staticCCScale9Sprite*createWithSpriteFrame(CCSpriteFrame*spriteFrame,CCRectcapInsets);//使用精灵帧的名称来创建staticCCScale9Sprite*createWithSpriteFrameName(constchar*spriteFrameName);staticCCScale9Sprite*createWithSpriteFrameName(constchar*spriteFrameName,CCRectcapInsets);/***属性设置*setSpriteFrame,setCapInsets,*setPreferredSize,setContentSize,*setOpacity,setColor*///设置精灵帧virtualvoidsetSpriteFrame(CCSpriteFrame*spriteFrame);//设置中间部分区域对应的矩形大小CC_PROPERTY(CCRect,m_capInsets,CapInsets);//设置需要生成的尺寸大小,默认为精灵图的原始大小CC_PROPERTY(CCSize,m_preferredSize,PreferredSize);//CCScale9Sprite是通过这个来拉伸的,而CCSprtie是通过setScale来拉伸。virtualvoidsetContentSize(constCCSize&size);//设置透明度virtualvoidsetOpacity(GLubyteopacity);virtualGLubytegetOpacity();//设置颜色virtualvoidsetColor(constccColor3B&color);virtualconstccColor3B&getColor();};//


4、使用说明:


4.1、关于参数

当使用CCScale9Sprite::create(const char* file, CCRect rect, CCRect capInsets);进行创建的时候,必须要注意理解rect 和 capInsets 这两个参数。

在曾经讲到的精灵类CCSprite中,是否还记得下列创建的方法?

//CCSprite::create(constchar*pszFileName,constCCRect&rect);//

该方法就是使用pszFileName图片资源,并从中截取某区域矩形的小图rect,来创建CCSprite精灵。当然若为设置rect的话,默认为整张图片的大小。

而在CCScale9Sprite中的 rect其实用法也是一样的。如果是需要整张图片资源sp.png的话,只要设置rect为整张图片的大小,坐标为(0,0)即可。

另外对于capInsets的设置,则是决定了CCScale9Sprite的九宫分割的区域大小。若未对CCScale9Sprite的capInsets进行设置,创建的九宫图的分区为九等分。capInsets则是设置了中间区域的大小,从而得到其他8块区域的大小。(这样就不一定是等分了)


4.2、关于图片拉伸

我们都知道CCSprite 的拉伸方式是通过 setScale(); 来实现的,而对于 CCScale9Sprite则不同。它是通过setContentSize(const CCSize & size); 来实现图片的拉伸。不过貌似使用setPreferredSize(const CCSize & size); 的效果类似?




【代码实战】


1、使用三组图片进行测试


2、引入头文件及命名空间:

//#include"cocos-ext.h"usingnamespacecocos2d::extension;//


3、编写测试对比函数test

///***file:图片资源名称,如"sp.png"*index:第几组测试数据*/voidHelloWorld::test(constchar*file,intindex){//获取可视区域尺寸大小CCSizemysize=CCDirector::sharedDirector()->getVisibleSize();//获取可视区域的原点位置CCPointorigin=CCDirector::sharedDirector()->getVisibleOrigin();//屏幕正中心位置CCPointmidPos=ccp(mysize.width/2,mysize.height/2);//CCSprite,精灵拉伸CCSprite*sprite1=CCSprite::create(file);sprite1->setPosition(ccp(120*index,mysize.height-60));this->addChild(sprite1);//精灵拉伸sprite1->setScale(2.0f);//scale9Sprite1,不设置capInsetsCCScale9Sprite*scale9Sprite1=CCScale9Sprite::create(file);scale9Sprite1->setPosition(ccp(120*index,mysize.height/2));this->addChild(scale9Sprite1);//不设置capInsets,拉伸scale9Sprite1->setContentSize(CCSizeMake(80,80));//scale9Sprite2,设置capInsetsCCScale9Sprite*scale9Sprite2=CCScale9Sprite::create(file);scale9Sprite2->setPosition(ccp(120*index,60));this->addChild(scale9Sprite2);//设置capInsets,并拉伸scale9Sprite2->setCapInsets(CCRectMake(3,3,34,34));scale9Sprite2->setContentSize(CCSizeMake(80,80));}//


4、测试三组图片

//boolHelloWorld::init(){if(!CCLayer::init()){returnfalse;}test("Icon.png",1);//用Icon.png做测试test("CloseNormal.png",2);//用CloseNormal.png做测试test("Rect.png",3);//用Rect.png做测试returntrue;}//


5、运行结果