[cocos2d]关于CCSprite的若干问题与误区
文章 [cocos2d] 利用texture atlases生成动画 中介绍了如何生成动画并绑定在CCSprite实例上。
使用该代码遇到了几个问题,值得mark下
问题1、多实例
问题描述:
新建一个PlayerSprite类继承CCSprite,若在PlayerSprite类中使用文中代码生成会出现问题。
//生成sprite(动画将绑定在sprite上)
CCSprite *sprite = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
问题出现在于这句。
因为PlayerSprite已经是CCSprite类,当PlayerSprite实例化时,此行代码会再把CCSprite实例化,之后的动画会绑定在新的sprite上。
解决方法:
1、在PlayerSprite类中删除此句代码,并将之后的所有的sprite改成 self 即可。(注意最后还有一句addChild要删除)
即
@interface PlayerSprite : CCSprite
@end
@implementation PlayerSprite
//利用软件将5帧png贴图生成1张大的png贴图和plist
CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
//读取plist并缓存plist包含的贴图
[frameCache addSpriteFramesWithFile:@"sprite.plist"];
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:];
int i;
for (i = ; i <= ; i++){
//假设命名为1.png 2.png。。。。
NSString *file = [NSString stringWithFormat:@"%i.png",i];
//从缓存中读取贴图生成动画帧
CCSpriteFrame *frame = [frameCache spriteFrameByName:file];
//加入到动态数组中
[frames addObject:frame];
}
//利用动画帧生成动画对象
CCAnimation *anim = [CCAnimation animationWithSpriteFrames:frames delay:0.05f];
//生成sprite(动画将绑定在sprite上)
//此句删除
// CCSprite *sprite = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
//生成在屏幕中间
self.position = CGPointMake(screenSize.width / , screenSize.height / );
//利用animate运行动画
CCAnimate *animate = [CCAnimate actionWithAnimation:anim];
//重复播放动画
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:animate];
[self runAction:repeat];
//加入到场景中
//此句也要删除,在适当的地方补回此句代码
// [self addChild:sprite z:0 tag:1]; @end
修改后的代码
2、然后在适当的地方实例化
PlayerSprite *sprite = [PlayerSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
[self addChild:sprite z: tag:];
经验:
copy代码一定要明白每一行代码的用处~
问题2、contentSize为0
问题描述:开始出现问题1的时候我是直接把该代码删除
然后直接在适当的地方使用下面代码实例化。(如果不使用texture的相关属性不会有明显的问题)
PlayerSprite *sprite = [PlayerSprite node];
如果此时要获得sprite大小的话会发现返回值为0。
//sprite的contentSize大小
CGSize size1 = sprite.contentSize; //sprite所使用的贴图大小,使用纹理贴图集会发生问题,返回为纹理贴图的size
CGSize size2 = sprite.texture.contentSize; //返回的是sprite大小(包括旋转,缩放,变换)
CGRect rect = sprite.boundingBox;
根据cocos2d库的源代码追溯下去寻找,发现如果使用spriteWithXXX实例化,最终会调用CCTexture2D获得贴图的大小;而直接使用[CCSprite node]初始化则少了该步,最后导致实例没有正确的size值;
@implementation CCSprite
//....
-(id)initWithFile:(NSString*)filename{
//.....省略
CCTexture2D *texture = [[CCTextureCache sharedCache] addImage:filename];
if ( texture ){
CGRect rect = CGRectZero;
rect.size = texture.contentSize;
return [self initWithTexture:texture rect:rect];
}
[self release];
return nil;
}
//.....
@end
CCSprite Source Code
解决方法:
同问题1,使用spriteWithXXX实例化即可
PlayerSprite *sprite = [PlayerSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
[self addChild:sprite z: tag:];
经验:
由此可以看出CCSprite与CCLayer,CCScene的继承类实例过程有不同的地方,
CCSprite的继承类用spriteWithXXX实例化的话,不会调用继承类的init方法,而只会调用CCSprite的init方法。
而对于CCLlayer与CCScene的继承类,因为是用XXLayer *layer = [XXLayer node]此类方式实例化,而 node实则上是[[[self alloc] init] autorelease]的缩写,会调用继承类的init方法。
问题3、贴图复用/获得已缓存的贴图
PlayerSprite *sprite = [PlayerSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
可能有人会发现在问题1、2中sprite使用的贴图是frameCache中获得的,那么有没方法获得已经缓存好的贴图而不是每次都要重新加载呢?
Learn iPhone and iPad Cocos2D Game Development一书中作者在第七章中介绍到一个比较好的方法
( Scrolling With Joy -> Advanced Parallax Scrolling -> Re-creating the Background in Code)
待续
[cocos2d]关于CCSprite的若干问题与误区的更多相关文章
- cocos2D(三)---- 第一cocos2d的程序代码分析
在第一讲中已经新建了第一个cocos2d程序,执行效果例如以下: 在这讲中我们来分析下里面的代码,了解cocos2d的工作原理,看看屏幕上的这个"Hello World"是怎样显示 ...
- 三、第一个cocos2d程序的代码分析
http://blog.csdn.net/q199109106q/article/details/8591706 在第一讲中已经新建了第一个cocos2d程序,运行效果如下: 在这讲中我们来分析下里面 ...
- 基于cocos2d开发的android小游戏——採花仙
/*cocos 2d 已经成为了如今移动端游戏开发的强有力的工具,眼下主流游戏中多採用cocos 2d游戏引擎. 我也尝试了一下该引擎.我是用的是cocos2d-android,以后要移植到Cocos ...
- Cocos2d-android (05) 渐变动画(颜色,淡入淡出。。。)
淡入淡出.颜色渐变及动作重复执行 import org.cocos2d.actions.base.CCRepeatForever; import org.cocos2d.actions.interva ...
- Cocos2d-android (04) 执行多个动作
先后.同时执行多个动作及动作序列执行结束后的事件 import org.cocos2d.actions.instant.CCCallFunc; import org.cocos2d.actions.i ...
- Cocos2d-android (03) 向量
向量的基本运算及动作 import org.cocos2d.actions.interval.CCJumpBy; import org.cocos2d.actions.interval.CCMoveB ...
- Cocos2d-android (02) 添加一个精灵对象
什么是精灵: 1.精灵就是游戏当中的一个元素,通常用于代表画面当前中的一个事物,例如主人公,NPC和背景元素等: 2.一个精灵对象通常都与一张图片关联 3.精灵对象可以通过动作对象(CCAction) ...
- cocos2d-x实战 C++卷 学习笔记--第4章 使用菜单
前言: 菜单中包含菜单项,菜单项类是 MenuItem ,每个菜单项都有三个基本状态:正常.选中和禁止. (MenuItem)菜单分类: (文本菜单)MenuItemLabel : MenuItemA ...
- cocos2d_android 瞬间动作
该文章所写的瞬间动作主要有CCFlipX,CCFlipY,CCHide,CCShow 当中CCFlipX是以Y轴为中心旋转,CCFlipY是以X轴为中心旋转,CCHide将精灵对象隐藏,CCShow将 ...
随机推荐
- MFC/VC++ UI界面美化技术
1. 工具: 1.1设备环境类: Windows下的绘图操作说到底就是DC操作.DC(Device Context设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它. ...
- linux 上不去网
linux 上不去网 ip dns无误 ping可以到达网关 可能原因 网卡睡眠 ethtool eht0 //查看eht0网口基本设置 mii-tool -w eth0
- div a块状布局
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- [功能帮助类] 最新的Functions 类 (转载)
代码 using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptogr ...
- python基础知识一
数 python中有4种类型的数--整数.长整数.浮点数和复数. --2是一个整数 --长整数不过是大一些的整数 --3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里52.3E-4表 ...
- Bootstrap: 样式CSS:carousel轮换 图片的使用
Bootstrap 轮播(Carousel)插件 Bootstrap轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式.除此之外,内容也是足够灵活的,可以是图像.内嵌框架.视频或者其 ...
- 读懂IL代码(三)
由于要写毕业论文的缘故,最近比较没有时间写,总是要抽出时间抽出时间.诶,这样的生活比较烦躁. 这一篇主要写委托.类.方法的IL代码,一一来说明. 委托:搞过C#的都应该清楚,委托实际上是一个类.编译器 ...
- 月薪10K必备--C#下拉框联动
下拉框联动 很多网站上都用到下拉框联动,就是第一个下拉框没有选择任何项,第二个下拉框就没有选项.这样的做法更加谨慎,更加紧密. 下面我就教大家怎么做下拉框联动: 首先在窗 ...
- 《paste命令》-linux命令五分钟系列之二十
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- [Neural Networks] Momentum
一.目的 加快参数的收敛速度. 二.做法 另第t次的权重更新对第t+1次的权重更新造成影响. 从上式可看出,加入momentum后能够保持权重的更新方向,同时加快收敛.通常alpha的取值为[0.7, ...