Cocos2dx学习笔记(21)——点九图

本章介绍UI控件之一的点九图。

本文仅供个人记录和复习,不用于其他用途

3.x版本

3.x版本除了去掉CC,其他再无变化。不过在3.3版本之后,出现了新的UI模块,原来的ControlSliderControlButton等等都改为了全新的类。当然,这个部分以后再说。

CCScale9Sprite

点九图、九宫图、九妹图,总之随便你怎么称呼它,我们的关注点在于它是个什么东西。看看这个类的名字,很显然,这个图由9个精灵构成,而且与缩放密切相关。事实上,我们在使用scale缩放时,图片会失真。为了解决这个问题,Cocos采用了点九图的方式来解决。

原理

点九图将纹理分成九个部分,依据以下步骤:

  • 保持4个角部分不变形
  • 单向拉伸4条边(即在4个角两两之间的边,比如上边,只做横向拉伸)
  • 双向拉伸中间部分(即九宫图的中间部分,横向,纵向同时拉伸,PS:拉伸比例不一定相同)

拉伸完毕后,将九个部分拼接在一起,就形成了缩放后的图片。

头文件和命名空间

1
2
#include "cocos-ext.h"
USING_NS_CC_EXT;

常用操作

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
class CCScale9Sprite : public CCNodeRGBA
{
// 使用图片资源名来创建
// 参数说明:
// 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);
// 设置精灵帧
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();
};

图片拉伸

点九图不使用setScale()进行缩放,而是使用setContentSize(const CCSize & size)

代码示例

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
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) );
}

注意事项

未设置capInsets时,图片九等分。设置了capInsets后,那么中间区域的大小就是capInsets的值。