CCSprite动态换图片

本文介绍了Cocos2d-x中如何使用CCSprite动态更换图片,包括通过TexturePacker创建贴图集,利用CCSpriteFrameCache缓存更换图片,以及CCSpriteBatchNode的使用来提高性能。同时,文章提到了如何为图片添加遮罩和使用PVRTC压缩技术减少内存占用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CCSprite更换图片  

2013-05-01 21:01:43|  分类: 游戏开发|字号 订阅

在使用CCSprite对象时,经常遇到需要更换贴图的时候。

比如在上个贪食蛇的游戏中,蛇前进的方向发生变化,蛇头的图片就要随着改变。

在网上查了些资料,实验并总结了一下。

首先需要把四个方向的蛇头图片使用texturepacker软件生成一个贴图集。

代码如下:

  1. // 首先载入贴图集  
  2. CCSpriteBatchNode *spriteBatch=CCSpriteBatchNode::batchNodeWithFile("snake.png");  
  3. this->addChild(spriteBatch);  
  4. CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("snake.plist");  
  5. // 生成Sprite  
  6. CCSprite *headSprite=CCSprite::spriteWithSpriteFrameName("headup.png");  
  7. //需要更换图片时  
  8. CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("headleft.png");  
  9. headSprite->setDisplayFrame(frame);  


1. 已经add的sprite重设z轴

[self reorderChild:sprite z:10];

 

2. 替换Sprite的图片

CCTexture2D texture =[[CCTextureCache sharedTextureCache] addImage: @”pa_icon.png”];

[sprite2 setTexture:texture];

还有一种方法

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@”pa_png@2x.plist”];

CCSpriteFrame* myFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@”pa_icon.png”];

[sprite2 setDisplayFrame:myFrame];

利用Sprite缓存来替换图片,更高效。

 

3. 为图片添加遮罩

简单的只需要增加一个layer

CCLayerColor *layer =[CCLayerColor layerWithColor:ccc4(0, 0, 0, 127)];

[self addChild:layer];

但是需要背景颜色一致,并且layer默认是全屏的。


cocos2d中的图片使用(CCSpriteBatchNode)

最先接触到的是CCSprite,就是一张图片,可以是背景可以是一个按钮图片。如下

CCSprite *bg1 = [CCSprite spriteWithFile:@"bg1.png"];

bg1.anchorPoint = CGPointZero;

bg1.position = CGPointMake(100, 200);

[self addChild:bg1 z:1];

但一个scene中如果有很多的图片将会导致占用很多内存,加载速度变慢。这时候就需要使用CCSpriteBatchNode了,有两个工具可以用来做这个事情

TexturePacker    免费版中会将倒出的图片中加入红色。 拥有zwoptex的90%的功能

zwoptex          7天免费试用   在线版免费但功能少http://zwoptexapp.com/flashversion


谁叫我没钱呢,只好使用zwoptex的在线版生成png图片和plist文件,本来相买TexturePacker的,功能强大用起来很方便,但转换成的pvr.ccz图片不能加载到CCSpriteFrameCache里面,最后也没找到问题原因。但zwoptex的在线版就没有这个问题,下面是代码


CCSpriteBatchNode *s = [CCSpriteBatchNode batchNodeWithFile: @"p.png"];

[self addChild:s z:1];

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"p.plist"];


CCSprite *next = [CCSprite spriteWithSpriteFrameName:@"next.png"];

next.position=ccp(450,600);

[s addChild:next z:1];


但zwoptex不能导出pvr格式的图片,所以使用texturetool工具来转换图片,这个工具是iphone sdk自带的。位于

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin


我是将这个路径加入到mac的环境变量里面了,这样很多sdk的命令都可以很方便的使用

sudo vim /etc/paths 

然后讲sdk的路径加入到paths中就可以,你可以在任何目录输入$texturetool来查看是否添加成功


$texturetool -e PVRTC -o ./p.pvr -f PVR ./p.png


更费劲的来了,因为p.plist文件是zwoptex导出的所以他里面会记着p.png这个图片,但我们现在是pvr了,所以要修改p.plist文件。

根据分析addSpriteFramesWithFile的源码看出来,一种是通过plist里面metadata中的textureFileName来获取图片的,另一种是没有metadata则默认为png。zwoptex则是后一种。所以只好修改成前一种了。TexturePacker输出的是前一种


使用pvr则需要在代码中加入[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];

然后是压缩图片,ccz是怎样压缩出来的我没有找到方法,只好使用gz

$gzip p.pvr

也可以使用 https://github.com/cjhanson/PNGPOTimizer/tree/CCZ  需要自己编译

压缩后的大小还是很可观的,pvr文件是37K pvr.gz文件是12K



精灵是2D游戏中得主角,这次就总结一下cocos2d-x中精灵的使用。

一,加载

首先,创建一个变量 CCSprite *pSprite;

加载函数分为两组initWithXXXX和spriteWithXXXX,其主要的区别是使用initWithXXXX的手工作业,而spriteWithXXXX是纯自动化作业。在SpriteWithXXXX中,先分配内存,然后加载,最后加入到autorelease中。而前者只有加载的部分,分配内存以及释放都需要靠自己。下边全部以spriteWithXXXX函数说明。

1,从文件中直接加载

从文件中加载很简单,只需要 CCSprite::spriteWithFile("文件完整名称"); 其中文件名必须是完整路径,用cocos2d-x生成的项目中Resources目录为根目录。若有一个文件目录为..\Resources\chars\a.png 则 文件名部分就应该为"chars/a.png"。值得注意的是,在WINDOWS下,后缀名大写小写无所谓,但是在MAC下,后缀的大小写必须与文件完全一致,否则无法加载。

此函数还有一个重载函数,后边多一个CCRect参数,可以通过此参数设定加载图片中某个矩形区域。

2,间接加载

有些经常被用到或者需要频繁加载移除的一些资源,如果每次都从文件中加载,程序的效率会变得非常低,通常的做法是将这些文件先读到缓存中,然后再从缓存中加载。

CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszFilename);

这个函数将一个图片加入缓存并返回一个CCTexture2D的指针。然后就可以

pSprite = CCSprite::spriteWithTexture(pTexture);

如果一个资源已经被加入到了缓存,addImage是不会再加一遍的。程序中我很少会直接用spriteWithTexture这个函数,因为需要保存pTexture的指针。而在spriteWithFile函数中起内部就已经使用了上述过程。

另一种间接加载方法是利用SpriteFrame。SpriteFrame是把一个大的图片划分掉,每一个矩形区域就是一个SpriteFrame。其实如果这个SpriteFrame在大图中的矩形区域已知的话,可以直接使用CCTexture2D的方式,使用CCRect参数。SpriteFrame给我们提供了一种快捷,简便的方式,就是将这个矩形区域信息保存到plist文件中,并通过一个名称作为索引。生成这种大图也有很多工具,我使用过两种工具,一个是 Zwoptex 是一个在线的免费工具,另一个我常用的是 TexturePacker。这是一个收费软件,不过免费版也能满足基本的需要。这两种工具可以生成一个.plist文件和一个图片文件。存放的时候讲这两个关联的文件放在同一个目录下。在需要使用的时候,我们可以将它加载到缓存中:

CCSpriteFrameCache *pCache = CCSpriteFrameCache::sharedSpriteFrameCache();

pCache->addSpriteFramesWithFile("XXXX.plist");

其中plist文件的路径是完整路径。

然后可以用两种方式加载

pSprite = CCSprite::spriteWithSpriteFrame(pCache->spriteFrameByName(szFrameName));

pSprite = CCSprite::spriteWithSpriteFrameName(szFrameName);

看起来第一个函数比较麻烦,实际上,第二个函数调用的是第一个函数。。。。值得说明的是,这里的szFrameName不需要完整路径,而是文件名索引。

 

二,常用操作

精灵加载完了就改各种使用了。

1,锚点

锚点就是所有旋转,移动,缩放的参考点。cocos2-x中默认的锚点是中心点。锚点用比例来表示范围为0-1,(0,0)点代表左下点,(1,1)代表右上点。设置的函数为setAnchorPoint(ccp(0.5, 0.5));

2,旋转

setRotation(angle) 其中angle为角度不是弧度。正数为顺时针旋转,负数为逆时针旋转。

3,位置

setPosition(ccp(xPos, yPos)) xPos和yPos为相对于父节点锚点的位置。

4,缩放

setScale(s);   // 整体缩放

setScaleX(s); // 原图片坐标X轴缩放

setScaleY(s); // 原图片坐标Y轴缩放

s为比例,s = 1表示原尺寸。

5,倾斜

setSkewX(s); // 原图片坐标X轴倾斜

setSkewY(s); // 原图片坐标Y轴倾斜

X轴向右为正,Y轴向上为正。

6,透明度

setOpacity(s);

s范围0-255,0完全透明,255完全不透明。

7,可见

setIsVisible(bVisible)

bVisible为bool值true代表可见false代表不可见

8,翻转

setFlipX(bFlip);  // 水平翻转

setFlipY(bFlip);  // 竖直翻转

bFlip为true,则图片翻转,false不翻转。注意,翻转是针对原图片的操作,水平翻转相当于在图片编辑软件里水平翻转一样。不根据锚点进行翻转。翻转以后,设置的以前设置的锚点不会随着图片的翻转而改变。比如设置右下角为锚点,则翻转以后,锚点为翻转后的图片的右下角(是不是有点绕?)

最后,初始化完成后,不要忘了使用addChild加入到父节点,否则是不会显示的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值