文章 [cocos2d] 利用texture atlases生成动画 中介绍了如何生成动画并绑定在CCSprite实例上。

使用该代码遇到了几个问题,值得mark下

问题1、多实例

问题描述:

新建一个PlayerSprite类继承CCSprite,若在PlayerSprite类中使用文中代码生成会出现问题。

  1. //生成sprite(动画将绑定在sprite上)
  2. CCSprite *sprite = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];

问题出现在于这句。
因为PlayerSprite已经是CCSprite类,当PlayerSprite实例化时,此行代码会再把CCSprite实例化,之后的动画会绑定在新的sprite上。

解决方法:

1、在PlayerSprite类中删除此句代码,并将之后的所有的sprite改成 self 即可。(注意最后还有一句addChild要删除)

  1. @interface PlayerSprite : CCSprite
  2. @end
  3. @implementation PlayerSprite
  4. //利用软件将5帧png贴图生成1张大的png贴图和plist
  5. CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
  6. //读取plist并缓存plist包含的贴图
  7. [frameCache addSpriteFramesWithFile:@"sprite.plist"];
  8. NSMutableArray *frames = [NSMutableArray arrayWithCapacity:];
  9. int i;
  10. for (i = ; i <= ; i++){
  11. //假设命名为1.png 2.png。。。。
  12. NSString *file = [NSString stringWithFormat:@"%i.png",i];
  13. //从缓存中读取贴图生成动画帧
  14. CCSpriteFrame *frame = [frameCache spriteFrameByName:file];
  15. //加入到动态数组中
  16. [frames addObject:frame];
  17. }
  18. //利用动画帧生成动画对象
  19. CCAnimation *anim = [CCAnimation animationWithSpriteFrames:frames delay:0.05f];
  20. //生成sprite(动画将绑定在sprite上)
  21. //此句删除
  22. // CCSprite *sprite = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
  23. //生成在屏幕中间
  24. self.position = CGPointMake(screenSize.width / , screenSize.height / );
  25. //利用animate运行动画
  26. CCAnimate *animate = [CCAnimate actionWithAnimation:anim];
  27. //重复播放动画
  28. CCRepeatForever *repeat = [CCRepeatForever actionWithAction:animate];
  29. [self runAction:repeat];
  30. //加入到场景中
  31. //此句也要删除,在适当的地方补回此句代码
  32. // [self addChild:sprite z:0 tag:1];
  33.  
  34. @end

修改后的代码

2、然后在适当的地方实例化

  1. PlayerSprite *sprite = [PlayerSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
  2. [self addChild:sprite z: tag:];

经验:

copy代码一定要明白每一行代码的用处~

问题2、contentSize为0

问题描述:开始出现问题1的时候我是直接把该代码删除

然后直接在适当的地方使用下面代码实例化。(如果不使用texture的相关属性不会有明显的问题)

  1. PlayerSprite *sprite = [PlayerSprite node];

如果此时要获得sprite大小的话会发现返回值为0。

  1. //sprite的contentSize大小
    CGSize size1 = sprite.contentSize;
  2.  
  3. //sprite所使用的贴图大小,使用纹理贴图集会发生问题,返回为纹理贴图的size
    CGSize size2 = sprite.texture.contentSize;
  4.  
  5. //返回的是sprite大小(包括旋转,缩放,变换)
  6. CGRect rect = sprite.boundingBox;

根据cocos2d库的源代码追溯下去寻找,发现如果使用spriteWithXXX实例化,最终会调用CCTexture2D获得贴图的大小;而直接使用[CCSprite node]初始化则少了该步,最后导致实例没有正确的size值;

  1. @implementation CCSprite
  2.  
  3. //....
  4.  
  5. -(id)initWithFile:(NSString*)filename{
  6. //.....省略
  7.  
  8. CCTexture2D *texture = [[CCTextureCache sharedCache] addImage:filename];
  9.  
  10. if ( texture ){
  11. CGRect rect = CGRectZero;
  12. rect.size = texture.contentSize;
  13. return [self initWithTexture:texture rect:rect];
  14. }
  15.  
  16. [self release];
  17. return nil;
  18.  
  19. }
  20.  
  21. //.....
  22. @end

CCSprite Source Code

解决方法:

同问题1,使用spriteWithXXX实例化即可

  1. PlayerSprite *sprite = [PlayerSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"1.png"]];
  2. [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、贴图复用/获得已缓存的贴图

  1. 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的若干问题与误区的更多相关文章

  1. cocos2D(三)---- 第一cocos2d的程序代码分析

    在第一讲中已经新建了第一个cocos2d程序,执行效果例如以下: 在这讲中我们来分析下里面的代码,了解cocos2d的工作原理,看看屏幕上的这个"Hello World"是怎样显示 ...

  2. 三、第一个cocos2d程序的代码分析

    http://blog.csdn.net/q199109106q/article/details/8591706 在第一讲中已经新建了第一个cocos2d程序,运行效果如下: 在这讲中我们来分析下里面 ...

  3. 基于cocos2d开发的android小游戏——採花仙

    /*cocos 2d 已经成为了如今移动端游戏开发的强有力的工具,眼下主流游戏中多採用cocos 2d游戏引擎. 我也尝试了一下该引擎.我是用的是cocos2d-android,以后要移植到Cocos ...

  4. Cocos2d-android (05) 渐变动画(颜色,淡入淡出。。。)

    淡入淡出.颜色渐变及动作重复执行 import org.cocos2d.actions.base.CCRepeatForever; import org.cocos2d.actions.interva ...

  5. Cocos2d-android (04) 执行多个动作

    先后.同时执行多个动作及动作序列执行结束后的事件 import org.cocos2d.actions.instant.CCCallFunc; import org.cocos2d.actions.i ...

  6. Cocos2d-android (03) 向量

    向量的基本运算及动作 import org.cocos2d.actions.interval.CCJumpBy; import org.cocos2d.actions.interval.CCMoveB ...

  7. Cocos2d-android (02) 添加一个精灵对象

    什么是精灵: 1.精灵就是游戏当中的一个元素,通常用于代表画面当前中的一个事物,例如主人公,NPC和背景元素等: 2.一个精灵对象通常都与一张图片关联 3.精灵对象可以通过动作对象(CCAction) ...

  8. cocos2d-x实战 C++卷 学习笔记--第4章 使用菜单

    前言: 菜单中包含菜单项,菜单项类是 MenuItem ,每个菜单项都有三个基本状态:正常.选中和禁止. (MenuItem)菜单分类: (文本菜单)MenuItemLabel : MenuItemA ...

  9. cocos2d_android 瞬间动作

    该文章所写的瞬间动作主要有CCFlipX,CCFlipY,CCHide,CCShow 当中CCFlipX是以Y轴为中心旋转,CCFlipY是以X轴为中心旋转,CCHide将精灵对象隐藏,CCShow将 ...

随机推荐

  1. CentOS7安装Python3.5

    2. 安装Python的依赖包 yum -y groupinstall "Development tools" yum -y install openssl-devel sqlit ...

  2. mac下通过docker搭建LEMP环境

    在mac下通过docker搭建LEMP环境境 1.安装virtualbox.由于docker是在lxc环境的容器 2.安装boot2docker,用于与docker客户端通讯 > brew up ...

  3. Andriod中WebView加载登录界面获取Cookie信息并同步保存,使第二次不用登录也可查看个人信息。

    Android使用WebView加载登录的html界面,则通过登录成功获取Cookie并同步,可以是下一次不用登录也可以查看到个人信息,注:如果初始化加载登录,可通过缓存Cookie信息来验证是否要加 ...

  4. PS之火焰铁锈字

    效果图 素材一:将下图在PS中打开,选择菜单:编辑>定义图案,命名后关闭图案 素材二 1.新建如下画布 2.将素材二拖入新建好的画布(使用移动工具) 3.先将文字图层复制4次(ctrl+J)并且 ...

  5. not exists 跟not in 纪念一下

  6. H TML5 之 (1) 初识HTML5

    新特性 HTML5 中的一些有趣的新特性: 用于绘画的 canvas 元素 用于媒介回放的 video 和 audio 元素 对本地离线存储的更好的支持 新的特殊内容元素,比如 article.foo ...

  7. 利用Inltellj创建javadoc ,用jd2chm创建chm

    现在有些框架都不带javadoc 就需要自己去生成,而且真正用起来还是chm的最方便,所以写篇日志记录一下 下面我就拿struts2的源码来来举个栗子 1.第一步:创建一个空的java项目,导入框架源 ...

  8. framework 4.5.1安装时发生严重错误

    http://jingyan.baidu.com/article/a501d80c0a74b4ec630f5ee5.html http://jingyan.baidu.com/article/d807 ...

  9. 逻辑回归:使用SGD(Stochastic Gradient Descent)进行大规模机器学习

    Mahout学习算法训练模型 mahout提供了许多分类算法,但许多被设计来处理非常大的数据集,因此可能会有点麻烦.另一方面,有些很容易上手,因为,虽然依然可扩展性,它们具有低开销小的数据集.这样一个 ...

  10. 分享一个自己写的基于TP的关系模型(2)

    1.增加多对多关系的处理 /** * 定义关系 * @return array */ public function test4(){ //参数说明 //关联的模型 //主表关联字段 //关联中间表 ...