【嘮叨】
本來是想學學控件類CCControl的另一個子類按鈕控件CCControlButton的。但是發現裏面有一個參數牽扯到CCScale9Sprite這個類。看到CCScale9Sprite,很容易聯想到精靈類CCSprite。兩者又有什麼區別呢?因此我就去網上收了一些有關CCScale9Sprite的資料來學習。
【致謝】
http://blog.csdn.net/zaojiahua/article/details/21295535
http://blog.csdn.net/onerain88/article/details/8273219
【Demo下載】
【3.x】
(1)去掉“CC”
(2)其他幾乎無變化。
【v3.3】
我們在 ui模塊 下實現了一個新的Scale9Sprite類。它的內部實現比之前的Scale9Sprite更爲簡潔,功能也更爲強大。
重新實現這個類的主要的原因是:Scale9Sprite在UI模塊被大量使用。
現在UI模塊不再依賴於extension模塊。 通過採用全新的 ui::Scale9Sprite ,很多部件類內部的代碼更加簡潔,優雅。
【CCScale9Sprite】
對於CCScale9Sprite類,不知道該怎麼翻譯,有人叫它點九圖,有人叫它九宮圖,有有人叫它九妹圖。i_f08.gif
那麼什麼是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頭文件
using namespace cocos2d::extension; //引用cocos2d::extension命名空間
3、常用操作
CCScale9Sprite繼承於CCNodeRGBA,所以除了可以使用以下自定義的操作外,還可以使用節點類CCNode、以及節點顏色類CCNodeRGBA的相關函數操作。
/************************************************************************/
/* 以上面原理部分提到的圖片爲例 */
/************************************************************************/
class CCScale9Sprite : public CCNodeRGBA
{
/**
* 創建的三類方式
* 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");
static CCScale9Sprite* create(const char* file);
static CCScale9Sprite* create(const char* file, CCRect rect);
static CCScale9Sprite* create(const char* file, CCRect rect, CCRect capInsets);
static CCScale9Sprite* create(CCRect capInsets, const char* file);
//使用精靈幀來創建
static CCScale9Sprite* createWithSpriteFrame(CCSpriteFrame* spriteFrame);
static CCScale9Sprite* createWithSpriteFrame(CCSpriteFrame* spriteFrame, CCRect capInsets);
//使用精靈幀的名稱來創建
static CCScale9Sprite* createWithSpriteFrameName(const char* spriteFrameName);
static CCScale9Sprite* createWithSpriteFrameName(const char* spriteFrameName, CCRect capInsets);
/**
* 屬性設置
* setSpriteFrame , setCapInsets ,
* setPreferredSize , setContentSize ,
* setOpacity , setColor
*/
//設置精靈幀
virtual void setSpriteFrame(CCSpriteFrame * spriteFrame);
//設置中間部分區域對應的矩形大小
CC_PROPERTY(CCRect, m_capInsets, CapInsets);
//設置需要生成的尺寸大小,默認爲精靈圖的原始大小
CC_PROPERTY(CCSize, m_preferredSize, PreferredSize);
//CCScale9Sprite是通過這個來拉伸的,而CCSprtie是通過setScale來拉伸。
virtual void setContentSize(const CCSize & size);
//設置透明度
virtual void setOpacity(GLubyte opacity);
virtual GLubyte getOpacity();
//設置顏色
virtual void setColor(const ccColor3B& color);
virtual const ccColor3B& getColor();
};
4、使用說明:
4.1、關於參數
當使用CCScale9Sprite::create(const char* file, CCRect rect, CCRect capInsets);進行創建的時候,必須要注意理解 rect 和 capInsets 這兩個參數。
在曾經講到的精靈類CCSprite中,是否還記得下列創建的方法?
CCSprite::create(const char *pszFileName, const CCRect& 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"
using namespace cocos2d::extension;
3、編寫測試對比函數test
/**
* file:圖片資源名稱,如"sp.png"
* index:第幾組測試數據
*/
void HelloWorld::test(const char* file, int index)
{
//獲取可視區域尺寸大小
CCSize mysize = CCDirector::sharedDirector()->getVisibleSize();
//獲取可視區域的原點位置
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
//屏幕正中心位置
CCPoint midPos = 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,不設置capInsets
CCScale9Sprite* scale9Sprite1 = CCScale9Sprite::create(file);
scale9Sprite1->setPosition( ccp(120 * index, mysize.height/2) );
this->addChild(scale9Sprite1);
//不設置capInsets,拉伸
scale9Sprite1->setContentSize( CCSizeMake(80, 80) );
//scale9Sprite2,設置capInsets
CCScale9Sprite* 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、測試三組圖片
bool HelloWorld::init()
{
if ( !CCLayer::init() )
{
return false;
}
test("Icon.png", 1); //用Icon.png做測試
test("CloseNormal.png", 2); //用CloseNormal.png做測試
test("Rect.png", 3); //用Rect.png做測試
return true;
}
5、運行結果
轉載網址:http://blog.51cto.com/shahdza/1543284