cocos2dx——九宮格CCScale9Sprite


本文轉載於:http://shahdza.blog.51cto.com/2410787/1543284

【嘮叨】

    本來是想學學控件類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類,不知道該怎么翻譯,有人叫它點九圖,有人叫它九宮圖,有有人叫它九妹圖。i_f08.gif

    那么什么是CCScale9Sprite呢?CCScale9Sprite對象,是一種CCSprite對象的變形,它的用法和CCSprite類似,不同點是:CCScale9Sprite對象有個特性就是縮放貼圖時可以盡量不失幀。

    如下圖所示,用普通的CCSprite拉伸后四個角模糊失真了,而是用CCScale9Sprite進行拉伸后,依舊很清晰。

wKiom1P1i7WQlNDAAABOALnKTvQ654.jpg

 

1、原理

    CCScale9Sprite的實現非常巧妙,是通過1個CCSpriteBatchNode和9個CCSprite來實現的,原理很簡單,通過將原紋理資源切割成9部分(PS: 這也是叫九宮圖的原因),根據想要的尺寸,完成以下的三個步驟:

    (1)保持4個角部分不變形

    (2)單向拉伸4條邊(即在4個角兩兩之間的邊,比如上邊,只做橫向拉伸)

    (3)雙向拉伸中間部分(即九宮圖的中間部分,橫向,縱向同時拉伸,PS:拉伸比例不一定相同)

wKiom1P1jjXgE2TMAADVtyZHzc0054.jpg

    CCSpriteBatchNode的資源為整個的紋理,9個CCSprite對應於紋理的9個部分(根據紋理不同,9部分所占比例會有所不同),根據想要的尺寸,將9部分拼裝在一起!

 

2、需要引用的頭文件及命名空間

1
2
3
4
//
     #include "cocos-ext.h"              //包含cocos-ext.h頭文件
     using  namespace  cocos2d::extension;  //引用cocos2d::extension命名空間
//

 

3、常用操作

    CCScale9Sprite繼承於CCNodeRGBA,所以除了可以使用以下自定義的操作外,還可以使用節點類CCNode、以及節點顏色類CCNodeRGBA的相關函數操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//
/************************************************************************/
/* 以上面原理部分提到的圖片為例                                          */
/************************************************************************/
 
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中,是否還記得下列創建的方法?

1
2
3
//
     CCSprite::create( const  char  *pszFileName,  const  CCRect& rect);
//

    該方法就是使用pszFileName圖片資源,並從中截取某區域矩形的小圖rect,來創建CCSprite精靈。當然若為設置rect的話,默認為整張圖片的大小。

wKiom1P1oJnByMWnAADARBo6V0E491.jpg

    而在 CCScale9Sprite 中的 rect 其實用法也是一樣的。如果是需要整張圖片資源sp.png的話,只要設置rect為整張圖片的大小,坐標為(0,0)即可。

    另外對於 capInsets 的設置,則是決定了CCScale9Sprite的九宮分割的區域大小。若未對CCScale9Sprite的capInsets進行設置,創建的九宮圖的分區為九等分。capInsets則是設置了中間區域的大小,從而得到其他8塊區域的大小。(這樣就不一定是等分了)

wKioL1P1pjKwKl99AABZGxOsbUU714.jpg    wKiom1P1pW2DJ51bAABqk6jl0EA981.jpg

 

    4.2、關於圖片拉伸

    我們都知道 CCSprite 的拉伸方式是通過 setScale(); 來實現的,而對於 CCScale9Sprite 則不同。它是通過 setContentSize(const CCSize & size); 來實現圖片的拉伸。不過貌似使用 setPreferredSize(const CCSize & size); 的效果類似?

 


 

【代碼實戰】

 

1、使用三組圖片進行測試

wKiom1P1y3awwwGkAAAMosjZL_o127.jpg    wKioL1P1zI7hAfEWAAALGXvKFrw144.jpg    wKioL1P1zI7QcC8HAAAG9XhV_To288.jpg

 

2、引入頭文件及命名空間:

1
2
3
4
//
     #include "cocos-ext.h"
     using  namespace  cocos2d::extension;
//

 

3、編寫測試對比函數test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//
     /**
      *     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、測試三組圖片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
     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、運行結果

wKioL1P1zwbTpOyHAAESX332c04309.jpg

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM