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类,不知道该怎么翻译,有人叫它点九图,有人叫它九宫图,有有人叫它九妹图。

那么什么是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、需要引用的头文件及命名空间


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的话,默认为整张图片的大小。

而在 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、引入头文件及命名空间:


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、运行结果

时间: 2024-11-15 11:39:15

cocos2dx——九宫格CCScale9Sprite的相关文章

cocos2dx基础篇(12)——点九图CCScale9Sprite

[引言] 本来是想学学控件类CCControl的另一个子类按钮控件CCControlButton的.但是发现里面有一个参数牵扯到CCScale9Sprite这个类.看到CCScale9Sprite,很容易联想到精灵类CCSprite.两者又有什么区别呢?因此我就去网上收了一些有关CCScale9Sprite的资料来学习. [参考文献] [1] http://blog.csdn.net/nynyvkhhiiii/article/details/12782249 [2] http://www.cnb

【Cocos2d-x】源码分析之 2d/ui/UILayout

#ifndef __LAYOUT_H__ #define __LAYOUT_H__ #include "ui/UIWidget.h" NS_CC_BEGIN namespace ui { typedef enum { LAYOUT_COLOR_NONE,//空 LAYOUT_COLOR_SOLID,//单一固定颜色的 LAYOUT_COLOR_GRADIENT//有梯度变化的 }LayoutBackGroundColorType;//容器背景颜色类型 typedef enum { LA

购买李宁Cocos2d-x套餐,送最新出的《Cocos2d-x游戏实战指南》签名书一本

活动时间:2016-10-18至2016-11-30 通过本套餐,可完全了解Cocos2d-x 3.x的相关技术,以及掌握C++语言,并具有一定的项目实战经验. Cocos2d-x游戏开发套餐:http://edu.51cto.com/pack/view/id-114.html <Cocos2d-x游戏实战指南>封面 本书月底出版,触控科技副总裁Jane.微软开放体验和合作事业部开发技术顾问梅颖广.51CTO学院运营总监曹亚莉.哈尔滨工业大学  王峥  联袂推荐 目录 第1章     初识CO

cocos2d-x 之CCControlButton的使用方法

偶在今天想通过某一个按钮的按下松开实现针对于某一个动画的切换,之前使用的CCMenuItemImage,大概代码如下: CCMenuItemImage *pFightItem = CCMenuItemImage::create(        "Normal.png","Selected.png",this,        menu_selector(SecondScene::menuFightCallback)); pFightItem->setPositi

Cocos2d-x 自定义按钮类控制精灵攻击----之游戏开发《赵云要格斗》

本篇要讲讲怎么自定义按钮类,并通过这个按钮类的对像来控制精灵的攻击.在看本篇之前最好先看看上一篇 Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发<赵云要格斗>,要素材和项目代码的把邮箱留下吧,因为这个项目还没弄完,我一直在改. 精灵的攻击也是一个动画,只不过,这个动画只播放一次,相当于在界面上加一个按钮,然后你点一次按钮,精灵就播放一次动画. 一.自定义按钮类 按钮可以用COCOS2D-X自带的,想着方便一点,我就自己封装了一个按钮类ControlButton,在里面添加一个

cocos2dx注册场景 使用CCEditBox实现输入框

我们在开始玩一个游戏时,通常要做的第一件事就是注册账号,下面就让我们来制作一个简单的注册场景,我所使用的cocos2dx版本为2.2.2 在这个场景中最主要的元素就是输入框和按钮,我从网上找了一些素材(也有自己P的),样子不太好看,但是最终的效果都是一样的. 在这个场景中,元素的摆放和按钮的功能都比较简单,唯一有些困难的就是输入框.在cocos2dx2.2.2中输入框可以使用CCTextFieldTTF和CCEditBox来实现,我们这里使用的是CCEditBox. 下面我们先来看看这个注册场景

cocos2d-x 2.2.3 之菜单分析(1)

TextEdit-Menu CCtextFieldTTF cocos2d – x 中提供的 bool T04ZORDER::init() { if (!CCLayer::init()) { return false; } CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCTextFieldTTF * textField; textField = CCTextFieldTTF::textFieldWithPlaceHold

xcode 运行 cocos2dx 项目问题总结

由于管理公司游戏项目ios的打包,且都是cocos2dx项目.经常碰到各种各样的问题,打算以后碰到的问题记录下来... 1.这个是折腾了我挺久的一个问题 Undefined symbols for architecture armv7: "cocos2d::CCDictionary::removeObjectForKey(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator&l

cocos2dx基础篇(13)——按钮控件CCControlButton

[引言] 按钮类CCControlButton继承于控件类CCControl. 控件类CCControl主要向子类提供了一系列的控件触发事件.当子控件触发相关的事件后,就会执行相关的控件事件回调函数.这与之前讲的CCMenu中的菜单按钮回调是类似的. 控件类CCControl主要有三个子类: (1)开关控件CCControlSwitch (2)滑块控件CCControlSlider (3)按钮控件CCControlButton 本节讲的是其子类其中之一:按钮类CCControlButton. [