Cocos2d中的CCSprite

精灵是游戏中十分重要的组成部分,随处可见,如:游戏背景、NPC、人物、道具等。在cocos2d-x引擎中,只要是用图片展示的,基本上需要使用精灵类。

1. 首先来了解一下跟精灵相关的几个类:

(1) CCTexture2D

可以把它看成一个纹理,它是cocos2d-x渲染图形的重要参数,用来贴图,因为cocos2d-x使用opengl es绘制2d图形的,它的尺寸是2的n次方。一般通过以下方式获得:


1

CCTexture2D*
cache = CCTextureCache::sharedTextureCache()->addImage(
"hero.png");

(2) CCSprite

这个就是精灵类,是CCNode的子类,它的内部封装了CCTexture2D(纹理),可以通过下面几种方式初始化精灵对象。


1

2

3

4

5

6

7

8

9

10

11

12

//CCTexture2D表示精灵包含的图片,范围是整张图片

static

CCSprite* spriteWithTexture(CCTexture2D *pTexture);

//CCRect表示图片的指定范围,即从图片的指定矩形区域裁剪

static

CCSprite* spriteWithTexture(CCTexture2D *pTexture,
const

CCRect& rect);

//CCSpriteFrame表示精灵的某一帧,大多数情况下精灵本身的图片有多帧。它内部封装了CCTexture2D和CCRect,可以从一个大图片取出一部分作为一帧。

static

CCSprite* spriteWithSpriteFrame(CCSpriteFrame *pSpriteFrame);

//pszSpriteFrameName表示帧的名字,根据帧名从内存中取出CCSpriteFrame

static

CCSprite* spriteWithSpriteFrameName(
const

char

*pszSpriteFrameName);

//pszFileName表示本地图片文件名

static

CCSprite* spriteWithFile(
const

char

*pszFileName);

static

CCSprite* spriteWithFile(
const

char

*pszFileName,
const

CCRect& rect);

static

CCSprite* spriteWithBatchNode(CCSpriteBatchNode *batchNode,
const

CCRect& rect);

下面是两种比较常用的初始化精灵的方式:


1

2

3

4

CCSprite*
sprite = CCSprite::spriteWithFile(
"hero.png");

/**
或者 **/

CCTexture2D*
cache = CCTextureCache::sharedTextureCache()->addImage(
"hero.png");

CCSprite*
sprite = CCSprite::spriteWithTexture(cache);

(3) CCTextureCache

它相当于CCTexture2D的容器,是内存池,用来缓存CCTexture2D对象的,它内部有一个字典CCMutableDictionary m_pTextures,key为图片的名称,值是CCTexture2D。当调用它的addImage函数添加图片时,会先根据图片名称去内存中查找是否已存在,是则直接取出返回。下面是addImage部分源码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

CCTexture2D
* CCTextureCache::addImage(
const

char

* path)

{

    CCTexture2D
* texture = NULL;

    std::string
pathKey = path;

    CCFileUtils::ccRemoveHDSuffixFromFile(pathKey);

    pathKey
= CCFileUtils::fullPathFromRelativePath(pathKey.c_str());

    texture
= m_pTextures->objectForKey(pathKey);

    std::string
fullpath = pathKey;
//
(CCFileUtils::fullPathFromRelativePath(path));

    if(
! texture )

    {

        /**
.... */

    }

    return

texture;

}

如果需要一次加载多张图片的时候,可以先把图片加载到CCTextureCache中,这样使用图片的时候速度就会很快了。

(4) CCSpriteBatchNode

它是批处理绘制精灵,主要是用来提高精灵的绘制效率的,需要绘制的精灵数量越多,效果越明显。因为cocos2d-x采用opengl es绘制图片的,opengl es绘制每个精灵都会执行:open-draw-close流程。而CCSpriteBatchNode是把多个精灵放到一个纹理上,绘制的时候直接统一绘制该texture,不需要单独绘制子节点,这样opengl es绘制的时候变成了:open-draw()-draw()…-draw()-close(),节省了多次open-close的时间。CCSpriteBatchNode内部封装了一个CCTextureAtlas(纹理图集,它内部封装了一个CCTexture2D)和一个CCArray(用来存储CCSpriteBatchNode的子节点:单个精灵)。注意:因为绘制的时候只open-close一次,所以CCSpriteBatchNode对象的所有子节点都必须和它是用同一个texture(同一张图片),类似下面这样的图片,4个贝壳都在同一纹理上:

在addChild的时候会检查子节点纹理的名称跟CCSpriteBatchNode的是不是一样,如果不一样就会出错,源码:


1

2

3

4

5

6

7

8

void

CCSpriteBatchNode::addChild(CCNode *child,
int

zOrder,
int

tag)

    {

        /**
... */

        //
check CCSprite is using the same texture id

        CCAssert(pSprite->getTexture()->getName()
== m_pobTextureAtlas->getTexture()->getName(),
"");

        /**
... */

    }

下面是使用CCSpriteBatchNode的使用代码示例:


1

2

3

4

5

6

7

8

9

10

11

12

CCSpriteBatchNode*
BatchNode1 = CCSpriteBatchNode::batchNodeWithFile(
"Images/grossini_dance_atlas.png",
50);

   addChild(BatchNode1,
0, kTagSpriteBatchNode);

CCSpriteBatchNode*
BatchNode = (CCSpriteBatchNode*) getChildByTag( kTagSpriteBatchNode );

   int

idx = CCRANDOM_0_1() * 1400 / 100;

   int

x = (idx%5) * 85;

   int

y = (idx/5) * 121;

   CCSprite*
sprite = CCSprite::spriteWithTexture(BatchNode->getTexture(), CCRectMake(x,y,85,121));

   BatchNode->addChild(sprite);

   sprite->setPosition(
ccp( p.x, p.y) );

(5) CCSpriteFrameCache

它是管理CCSpriteFrame的内存池,跟CCTextureCache功能一样,不过跟CCTextureCache不同的是,如果内存池中不存在要查找的帧,它会提示找不到,而不会去本地加载图片。它的内部封装了一个字典:CCDictionary *m_pSpriteFrames,key为帧的名称。CCSpriteFrameCache一般用来处理plist文件(这个文件指定了每个独立的精灵在这张“大图”里面的位置和大小),该文件对应一张包含多个精灵的大图,plist文件可以使用TexturePacker制作。如下图所示:

下面是使用CCSpriteFrameCache的使用代码示例:


1

2

3

4

CCSpriteFrameCache*
cache = CCSpriteFrameCache::sharedSpriteFrameCache();

cache->addSpriteFramesWithFile("animations/grossini.plist",
"animations/grossini.png");

m_pSprite1
= CCSprite::spriteWithSpriteFrameName(
"grossini_dance_01.png");

m_pSprite1->setPosition(
ccp( s.width/2-80, s.height/2) );

只要plist文件跟对应的png图片在同一目录下,且名字相同,则addSpriteFramesWithFile(“animations/grossini.plist”, “animations/grossini.png”)可以改成addSpriteFramesWithFile(“animations/grossini.plist”);

2. CCSpriteBatchNode和CCSpriteFrameCache结合使用

必须保证CCSpriteFrameCache和CCSpriteBatchNode加载的是同一纹理贴图。


1

2

3

4

5

6

7

8

CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("animations/ghosts.plist",
"animations/ghosts.png");

   CCSpriteBatchNode
*aParent = CCSpriteBatchNode::batchNodeWithFile(
"animations/ghosts.png");

   addChild(aParent,
0, kTagSprite1);

   CCSprite
*pFather = CCSprite::spriteWithSpriteFrameName(
"father.gif");

   pFather->setPosition(ccp(
s.width/2, s.height/2));

   aParent->addChild(pFather,
0, kTagSprite2);

时间: 2024-10-08 10:59:27

Cocos2d中的CCSprite的相关文章

Cocos2D中Action的进阶使用技巧(一)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 假设认为写的不好请多提意见,假设认为不错请多多支持点赞.谢谢! hopy ;) 大家对Cocos2d中动作的使用大概都非常清楚了,事实上本身action的概念也不复杂. 可是在某些情况下,一般的动作不能满足我们需求的时候,我们就必须使用更高级的Action方法来解决这个问题. 比方,串行化(不是序列化哦,这是两个全然不同的概念)不同Action的执行-有些童鞋可能会说非常easy,直接用CCActionSequence不就结了,可是等等我

cocos2d 中加入显示文字的三种方式(CCLabelTTF 、CCLabelBMFont 和CCLabelAtlas)

在 cocos2d 中有三个类能够在层或精灵中加入文字: CCLabelTTF CCLabelBMFont CCLabelAtlas      CCLabelTTF CCLabelTTF 每次调用 setString (即改变文字)的时候,一个新的OPENGL 纹理将会被创建..这意味着setString 和创建一个新的标签一样慢. 所以,当你须要频繁的更新它们的时候,尽可能的不用去使用标签对象.  而应该使用CCLabelAtlas或者是CCLabelBMFont. OK, 看下它的用法 CC

Cocos2D iOS之旅:如何写一个敲地鼠游戏(二):Cocos2D中的高清支持

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流之用,请勿进行商业用途.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作! 高清显示和Cocos2D 好吧,有一个好消息 - 在最新版本的Cocos2D中包括了高清屏的完整支持,你可以用下面1-2-3步就可简单搞定! 在调用CCDirector的en

Cocos2D中Node的userObject实例变量使用时一个要注意的地方

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在Cocos2D中,CCNode对象有一个ivar为userObject,它可以用来很方便的存储一些和该对象相关的数据,这样你就没必要费劲的去写子类继承了. 但是要注意的是,如果你的node添加到一个节点当做子类,比如: [someBaba addChild:myNode]; 那么在调用如下一句将myNode从父节点中删除时,其中的userObject也

cocos2d 中使用jni C++ 调用 Java 方法

1.简单数据类型例子 假设我们Java中有这么一个open的静态方法,它没有参数,有一个int的返回值.怎么在C++中调用它呢? package cb.CbCCBLE; public class CbCCBLECentralManager { public static final String TAG = "CbCCBLECentralManager Android"; public static int open() { Log.d(TAG,"open"); r

cocos2d 中使用jni Java 调用 C++ 方法

1.首先是LoadLibrary cocos2d中的C++代码会编译成一个.so文件,放在安卓目录下的libs/armeabi 下,然后java会load进来,这步我们不用做了,因为cocos2d已经帮我们做好了. package cb.CbCCBLE; public class CbCCBLECentralManager { public static final String TAG = "CbCCBLECentralManager Android"; public native

cocos2d中的可见性检测

游戏的在进行一次渲染的时候,通常会提交大量的渲染对象给gpu.在这些需要渲染的对象中,并不是所有对象都会出现镜头中,即有一部分对象是不可见的. 通常有两种方式来完成不可见对象的剔除工作: (1)直接交给图形库帮我剔除,即性能消耗在gpu端: (2)在提交图元给gpu前,在游戏逻辑中进行剔除,即性能消耗在cpu端: 是将剔除操作放在cpu还是gpu来处理,没有一个具体的标准,个人认为,要根据实际情况,如果逻辑方面可以快速进行剔除,可以交由cpu来处理,但是gpu在这方面经过了优化,具有更快的处理能

cocos2d中CCSprite的使用总结 【转】

一.精灵创建及初始化 1.从图片文件创建: CCSprite *sprite = [CCSprite spriteWithFile:@"Icon.png"]; 2.从帧缓存创建: [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"MineSweeping.plist"]; CCSprite *sprite = [CCSprite spriteWithSpriteFrameNa

Cocos2d中的Menu使用

学习cocos2d-x中的菜单主要需要了解:菜单(CCMenu)和菜单项(CCMenuItem)以及CCMenuItem的具体子类. a. 下面来学习一下相关的类. 1. CCMenu 菜单,是CCLayer的子类,是一个层(容器),可以往里面添加菜单项.下面是它的类结构图: CCMenu默认接受触屏事件的优先级是-128(优先级很高,因为值越小,响应触屏事件的优先级越高),可以通过继承它实现自定义的效果,创建CCMenu对象的函数: static CCMenu* menuWithItems(C