[ 李华明Himi ](http://www.himigame.com/about-himi)原创,转载务必在明显处注明:
转载自[【黑米GameDev街区】](http://www.himigame.com/) 原文链接: [http://www.himigame.com/iphone-cocos2d/525.html](http://www.himigame.com/iphone-cocos2d/525.html "【iOS-Cocos2d游戏开发之二十一")
[](http://blog.csdn.net/xiaominghimi/article/details/6993764)
上周貌似没有写新的博文,那么今天Himi写个精品的博文奉献给童鞋们;
(不少童鞋说Himi的教程最近都没有源码放出=。 =,这里我解释下,一般我没有放出源码的博文那肯定已经将代码贴出来了,这点是肯定的,否则Himi一定给出源码的)
本篇的知识点如下:
1.两种方式实现自定义精灵;
2.两种方式让精灵利用多帧播放动画
3.为你的精灵设置带有攻击帧的动画,当执行攻击动作的中间会执行扣血等逻辑,然后接着播放动作喔~
首先第一种如何自定义精灵:
两种自定义一个精灵当然无疑我们仍然继承CCSprite,首先看第一种自定义方式,Himi新建一个类,名字是MySprite,代码如下,大家一看就很清晰了;
**MySprite.h**
~~~
//
// MySprite.h
// HimiAnimationsTestPro
//
// Created by 华明 李 on 11-11-20.
// Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//
#import "CCSprite.h"
@interface MySprite : CCSprite{
}
+(id) mySpriteInitWithImage:(NSString*)fileName;
-(id) initWithMySpriteImage:(NSString*)fileName;
@end
~~~
**MySprite.m**
~~~
//
// MySprite.m
// HimiAnimationsTestPro
//
// Created by 华明 李 on 11-11-20.
// Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//
#import "MySprite.h"
@implementation MySprite
+(id) mySpriteInitWithImage:(NSString*)fileName
{
return [[[self alloc] initWithMySpriteImage:fileName] autorelease];//这里仿照cocos2d原理,自动清理精灵
}
-(id) initWithMySpriteImage:(NSString*)fileName
{
if ((self = [super initWithFile:fileName]))
{
//初始化的东东都写在这里喔~
}
return self;
}
-(void) dealloc
{
//内存清理
[super dealloc];
}
@end
~~~
大家以后自定义精灵的时候可以将我这个当模版即可!如果你不想自定义的精灵传参,那就直接自己修改下构造函数即可,初始化的时候写死名字即可(比如一般游戏主角不需要传入图片名字作为参数,直接在我们主角类的构造中将图片资源名写死即可)
然后我们用第二种方式,所谓第二种方式其实就是修改我们的初始化函数,让其精灵初始化的方式改成帧缓存创建:(适合利用TP打包工具出的图进行来创建精灵)
代码如下:(这里Himi为了让童鞋们看得清楚,Himi新建一个类,名字是MySpriteByFrame)
**MySpriteByFrame.h**
~~~
//
// MySprite.h
// HimiAnimationsTestPro
//
// Created by 华明 李 on 11-11-20.
// Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//
#import "CCSprite.h"
@interface MySpriteByFrame : CCSprite{
}
+(id) mySpriteInitWithFrameName:(NSString*)frameName;
-(id) initWithMySpriteFrameName:(NSString*)frameName;
@end
~~~
**MySpriteByFrame.m**
~~~
//
// MySprite.m
// HimiAnimationsTestPro
//
// Created by 华明 李 on 11-11-20.
// Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//
#import "MySpriteByFrame.h"
@implementation MySpriteByFrame
+(id) mySpriteInitWithFrameName:(NSString*)fileName
{
return [[[self alloc] initWithMySpriteFrameName:fileName] autorelease];//这里仿照cocos2d原理,自动清理精灵
}
-(id) initWithMySpriteFrameName:(NSString*)fileName
{
if ((self = [super initWithSpriteFrameName:fileName]))
{
//初始化的东东都写在这里喔~
}
return self;
}
-(void) dealloc
{
//内存清理
[super dealloc];
}
@end
~~~
大家注意两种自定义精灵.m类中的 if((self = XXX)这里是重要的区别,一个是直接索引资源名称,一个是通过名称找到帧缓存中的帧;
OK,两种创建的方式的自定义精灵都完成了,下面我们来尝试创建吧:
~~~
//---------创建一个我们自定义的MySprite精灵吧(利用文件名直接创建)
//1.import 自定义类.h (#import "MySprite.h")
MySprite*mySprite=[MySprite mySpriteInitWithImage:@"Icon.png"];
mySprite.position=ccp(70,size.height*0.5);
[self addChild:mySprite];
//---------创建一个我们自定义的MySpriteByFrame精灵吧(利用帧缓存中的文件名创建)
//@@@@注意因为是从帧缓存里找到对应名字的帧,那么肯定需要将用到的帧放在缓存里。
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"mySpriteFrames-hd.plist"];
MySpriteByFrame *mySpriteByF =[MySpriteByFrame mySpriteInitWithFrameName:@"himi.png"];
mySpriteByF.position=ccp(300,size.height*0.5);
[self addChild:mySpriteByF];
~~~
注意:利用帧来创建的时候必须要将使用的帧首先加载到帧缓存中,这里Himi利用TP打包工具将一张名字为himi.png的图打包到mySpriteFrames-hd.plist中了,也就是下面这句代码将himi.png图加载到帧缓存中了,否则报错找不到喔;
~~~
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"mySpriteFrames-hd.plist"];
~~~
加载的图片资源图如下:
![](https://box.kancloud.cn/2016-03-31_56fcd01e32be2.png)
注意这里的-hd 文件和非-hd的文件的区别,不太懂的童鞋请移步到这篇博文:
[【iOS-Cocos2d游戏开发之九】讲解CCSpriteBatchNode与TP工具的".pvr.ccz",".plist"共用的终极精灵优化及注意事项!](http://blog.csdn.net/xiaominghimi/article/details/6761811)
运行截图如下:
![](https://box.kancloud.cn/2016-03-31_56fcd01e4d252.png)
下面Himi来介绍第二个知识点:两种方式让精灵利用多帧播放动画
Himi这里就不细说了,直接提供给大家Himi封装好的两个方法:(Himi使用的cocos2d-iphone版本是1.0.0)
先唠叨一句,刚才上面说过了,创建精灵一种是利用直接索引文件名字来创建,另外一种就是直接利用帧缓存来创建,那么让一个精灵实现动画的播放当然也一样对应分为两种方式;直接上代码:**
**CCAnimationHelper.h**
~~~
//
// CCAnimationHelper.h
// SpriteProject
//
// Created by Himi on 11-8-6.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "cocos2d.h"
@interface CCAnimation (Helper)
//直接索引图片名称
+(CCAnimation*) animationWithFile:(NSString*)name frameCount:(int)frameCount delay:(float)delay;
//利用帧缓存中的帧名称
+(CCAnimation*) animationWithFrame:(NSString*)frame frameCount:(int)frameCount delay:(float)delay;
@end
~~~
**CCAnimationHelper.m**
~~~
// CCAnimationHelper.m
// SpriteProject
//
// Created by Himi
#import "CCAnimationHelper.h"
@implementation CCAnimation (Helper)
//直接索引图片名称
+(CCAnimation*) animationWithFile:(NSString*)name frameCount:(int)frameCount delay:(float)delay
{
NSMutableArray* frames = [NSMutableArray arrayWithCapacity:frameCount];
NSString* file;
for (int i = 0; i < frameCount; i++)
{
file =nil;
file = [NSString stringWithFormat:@"%@%i.png", name, i];
CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:file];
CGSize texSize = texture.contentSize;
CGRect texRect = CGRectMake(0, 0, texSize.width, texSize.height);
CCSpriteFrame* frame = [CCSpriteFrame frameWithTexture:texture rect:texRect];
[frames addObject:frame];
}
return [CCAnimation animationWithFrames:frames delay:delay];
}
//利用帧缓存中的帧名称
+(CCAnimation*) animationWithFrame:(NSString*)frame frameCount:(int)frameCount delay:(float)delay
{
NSMutableArray* frames = [NSMutableArray arrayWithCapacity:frameCount];
NSString* file;
for (int i = 1; i <= frameCount; i++)
{
file =nil;
file = [NSString stringWithFormat:@"%@%i.png", frame, i];
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
CCSpriteFrame* frame = [frameCache spriteFrameByName:file];
[frames addObject:frame];
}
return [CCAnimation animationWithFrames:frames delay:delay];
}
@end
~~~
~~~
+(CCAnimation*) animationWithFile:(NSString*)name frameCount:(int)frameCount delay:(float)delay{};
//参数讲解:name:资源文件名 ;frameCount 总帧数 ; delay :每一帧的刷新时间
+(CCAnimation*) animationWithFrame:(NSString*)frame frameCount:(int)frameCount delay:(float)delay{};
//参数讲解:frame:帧文件名 ;frameCount 总帧数 ; delay :每一帧的刷新时间
~~~
注意:
1、类有(help)的表示对原有的类进行扩展;
2、动作帧都要按照himi0.png,himi1.png,himi2.png,这样子命名,当然拉你不想这样可以修改这两个方法即可;
3.注意Himi这里的两个方法,一个是从0开始喔,另外一个是从1开始的,如果你用帧缓存进行创建动作就要从himi1.png,开始命名,嘿嘿~**
下面是使用方法:
~~~
//--@@@@@@@--第二个知识点--@@@@@@@
//利用文件名创建动作
//--首先导入#import "CCAnimationHelper.h"
MySprite*mySprite=[MySprite mySpriteInitWithImage:@"himi0.png"];
mySprite.position=ccp(140,mySprite.contentSize.height*0.5);
[self addChild:mySprite];
CCAnimation*anim=[CCAnimation animationWithFile:@"himi" frameCount:12 delay:0.1];
CCAnimate* animate = [CCAnimate actionWithAnimation:anim];
CCSequence *seq = [CCSequence actions:animate,nil];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:seq];
[mySprite runAction:repeat];
//利用帧缓存中的文件名创建动作
//--首先导入#import "CCAnimationHelper.h"
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"];
MySpriteByFrame *mySpriteByF =[MySpriteByFrame mySpriteInitWithFrameName:@"himi1.png"];
mySpriteByF.position=ccp(350,size.height*0.5);
[self addChild:mySpriteByF];
anim=[CCAnimation animationWithFrame:@"himi" frameCount:12 delay:0.1];
animate = [CCAnimate actionWithAnimation:anim];
seq = [CCSequence actions:animate,nil];
repeat = [CCRepeatForever actionWithAction:seq];
[mySpriteByF runAction:repeat];
~~~
这里要提醒童鞋们的有两点:
1.利用帧缓存创建动画的时候要注意要提前将帧加载到缓存里喔~
2.Himi这两个方法没有写一样,所以动作帧的命名一个从0开始,另外一个从1开始!童鞋们可以自行改过来哈
运行截图如下:
![](https://box.kancloud.cn/2016-03-31_56fcd01e7670f.png)
【扯皮一下,如果你在我的Android或者iOS群中,你感觉这张哆啦A梦图熟悉不~嘿嘿,Himi的7个群都是这个GIF做为群头像,娃哈哈,我自己做的 娃哈哈;】
第三点知识点:为你的精灵设置攻击帧;
首先跟一些童鞋简单说下何谓攻击帧,假如主角攻击一个怪物的时候,肯定播放攻击动作,但是!你是在攻击动作开始的时候就扣怪物血还是攻击动作结束后扣怪物血呢?都不是!!!因为很不真实!所以我们应该当攻击动作播放到设定的某一帧的时候进行扣怪物血或者其他逻辑,然后继续播放剩下的攻击动作,这样才更加的真实!
那么OK,这里Himi仍然封装成一个方法让你直接使用即可;首先看下代码:
~~~
//带有攻击帧的动画
+(CCAnimation*) animationWithFrameFromStartFrameIndex:(NSString*)frame startFrameCountIndex:(int)startFrameIndex frameCount:(int)frameCount delay:(float)delay
{
NSMutableArray* frames = [NSMutableArray arrayWithCapacity:frameCount];
NSString* file;
file =nil;
for (int i = startFrameIndex; i < frameCount+startFrameIndex; i++)
{
file = [NSString stringWithFormat:@"%@%i.png", frame, i];
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
CCSpriteFrame* frame = [frameCache spriteFrameByName:file];
[frames addObject:frame];
}
return [CCAnimation animationWithFrames:frames delay:delay];
}
~~~
~~~
+(CCAnimation*) animationWithFrameFromStartFrameIndex:(NSString*)frame startFrameCountIndex:(int)startFrameIndex frameCount:(int)frameCount delay:(float)delay {}
//参数介绍:frame :帧名字; startFrameIndex:指定播放起始帧 ; frameCount:帧总数 ; delay:每帧的刷新时间
~~~
使用方法如下:
~~~
//--@@@@@@@--第三个知识点--@@@@@@@
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"];
MySpriteByFrame *mySpriteAni =[MySpriteByFrame mySpriteInitWithFrameName:@"himi1.png"];
mySpriteAni.position=ccp(260,size.height*0.5);
[self addChild:mySpriteAni];
//首先执行前6帧动画
CCAnimation*anim=[CCAnimation animationWithFrameFromStartFrameIndex:@"himi" startFrameCountIndex:1 frameCount:6 delay:0.1];
CCAnimate* animate = [CCAnimate actionWithAnimation:anim];
//攻击帧执行的函数
CCCallFunc *downEnemyHp =[CCCallFunc actionWithTarget:self selector:@selector(downEnemyHp)];
//后6帧动画
anim=[CCAnimation animationWithFrameFromStartFrameIndex:@"himi" startFrameCountIndex:7 frameCount:6 delay:0.1 ];
CCAnimate* animateForAttackIndex = [CCAnimate actionWithAnimation:anim];
CCSequence *seq = [CCSequence actions:animate,downEnemyHp,animateForAttackIndex,nil];
[mySpriteAni runAction:seq];
---------回调函数
-(void)downEnemyHp{
CCLabelTTF *label = (CCLabelTTF*)[self getChildByTag:99];
[label setString:@"攻击帧"];
}
~~~
前六帧-》回调downEnemyHp函数-》继续播放剩下的播放帧数
运行截图如下:
![](https://box.kancloud.cn/2016-03-31_56fcd01eb2233.png)
![](https://box.kancloud.cn/2016-03-31_56fcd01eea069.png)
OK,继续忙了~由于本文知识点较多和较细节,这里Himi放出源码,我的动作相关的封装都在CCAnimationHelper.h/.m中喔,注意不要改类名,因为这个类是Himi对cocos2d源码进行的扩展!**
[http://www.himigame.com/iphone-cocos2d/525.html](http://www.himigame.com/iphone-cocos2d/525.html "【iOS-Cocos2d游戏开发之二十一")
- 前言
- 【Iphone 游戏开发】游戏引擎剖析
- [Object-C语言随笔之一]Mac os 下搭建iOS开发环境
- [Object-C语言随笔之二] 《NSLog》常用的打印调试语句与自动排版
- [Object-C语言随笔之三] 类的创建和实例化以及函数的添加和调用!
- [Object-C语言随笔之四]创建视图并绘制简单图形
- 【iOS-Cocos2d游戏开发之一】搭建cocos2d游戏引擎环境HelloWorld!
- 【iOS-Cocos2d游戏开发之二】Cocos2D 游戏开发资源贴(教程以及源码)
- 【iOS-Cocos2d游戏开发之三】CCScene切换的所有特效(28种)以及设置屏幕横竖屏!
- 【iOS-Cocos2d游戏开发之四】独自收集Cocos2d提供的字体!共57种(有对照的字体图)
- 【iOS-Cocos2d游戏开发之五】多触点与触屏事件详解(单一监听、事件分发)【11月28日更新】
- 【iOS-Cocos2d游戏开发之六】对触屏事件追加讲解,解决无法触发ccTouchMoved事件[重要!]
- 【iOS-Cocos2d游戏开发之七】在cocos2d中添加/删除系统组件,并解决View设置透明会影响View中的其他组件的问题!【11月28日更新解决添加组件Cocos2d动画停止播放的BUG】
- 【iOS-Cocos2d游戏开发之八】开启高清(960*640)模式问题与解答、图片适配以及设置iphone横竖屏
- 【iOS-Cocos2d游戏开发之九】讲解CCSpriteBatchNode与TP工具的&quot;.pvr.ccz&quot;,&quot;.plist&quot;共用的终极精灵优化及注意事项!
- 【iOS-Cocos2d游戏开发之十】添加粒子系统特效并解决粒子特效与Layer之间的坐标问题;
- 【iOS-Cocos2d游戏开发之十一】使用Box2d物理系统以及在cocos2d框架添加Box2d物理系统lib包的方法
- 【iOS-Cocos2d游戏开发之十二】浅析使用C++/C/OC进行iOS游戏混编出现“failed with exit”问题与小结;
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 【iOS-Cocos2d游戏开发之十四】音频/音效/视频播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d进行视频播放!)
- 【iOS-Cocos2d游戏开发之十五】详解CCProgressTimer 进度条并修改cocos2d源码实现“理想”游戏进度条!
- 【iOS-Cocos2d游戏开发之十六】添加本地通知(UILocalNotification)以及添加系统组件滚动视图(UIScrollView)!【2011年11月15日更新】
- 【iOS-Cocos2d游戏开发之十七】灵活使用精灵可视区域(TextureRect)与锚点(anchorPoint),并结合可视区域与锚点制作进度条!
- 【iOS开发必备指南合集】申请企业级IDP、真机调试、游戏接入GameCenter 指南(实现仿官方的成就提示)、游戏接入OpenFeint指南;
- 【iOS-Cocos2d游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/动画播放出现毛边以及禁止游戏中自动锁屏问题!【2011年12月18日补充】
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取&quot;产品付费数量等于0的问题&quot;】
- 【iOS-cocos2d-X 游戏开发之一】在Mac下结合Xcode搭建Cocos2d-X开发环境!
- 【iOS-cocos2d-X 游戏开发之二】【必看篇】总结阐述Cocos2d-X与Cocos2d-iphone区别;
- 【iOS-Cocos2d游戏开发之十九】游戏数据存储的四种常用方式NSKeyedArchiver/NSUserDefaults/Write写入/SQLite3
- 【iOS-Cocos2d游戏开发之二十】精灵的基础知识点总汇(位图操作/贴图更换/重排z轴等)以及利用CCSprite与CCLayerColor制作简单遮盖层!
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建!
- 【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)!
- 【iOS-cocos2d-X 游戏开发之三】Mac下配置Android NDK环境并搭建Cocos2d-x环境并Eclipse正常编译运行Cocos2dX自带TestsDemo项目!
- 【iOS-cocos2d-X 游戏开发之四】Cocos2dX创建Android NDK新项目并编译导入Eclipse中正常运行!
- 【iOS-cocos2d-X 游戏开发之五】游戏存储之Cocos2dX自带CCUserDefault类详解;
- 【iOS-cocos2d-X 游戏开发之六】使用Base64算法对Cocos2dX自带CCUserDefault游戏存储数据编码!
- 【iOS-cocos2d-X 游戏开发之七】整合Cocos2dX的Android项目到Xcode项目中,Xcode编写&amp;编译代码,Android导入打包运行即可!
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!拒绝iap Free!让iphone越狱用户无从下手!【2012年5月2日更新防护iap Free的方法】
- 【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!
- 【iOS-cocos2d-X 游戏开发之九】Cocos2dx利用CCSAXParser解析xml数据&amp;CCMutableDictionary使用与注意!
- 【iOS-cocos2d-X 游戏开发之十】自定义CCSprite/Layer/CCNode及静态类模版&amp;自定义类细节说明&amp;Cocos2dx触屏事件讲解
- 【iOS-cocos2d-X 游戏开发之十一】New CCSprite()带来的错误&amp;使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!
- 【iOS-cocos2d-X 游戏开发之十二】自定义Cocos2dx摇杆(增强Joystick),增加摇杆跟随用户触点作为摇杆坐标,让摇杆不再死板!
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- 【iOS-cocos2d-X 游戏开发之十四】Xcode中c++&amp;Object-C混编,详细介绍如何在cocos2dx中访问object函数以及Apple Api
- 【iOS-cocos2d-X 游戏开发之十五】Cocos2dx中响应Android的Back(返回)与Menu(小房子)事件&amp;&amp;Cocos2dx自动释放粒子内存函数!
- 【iOS-cocos2d-X 游戏开发之十六】配置你的Cocos2dx项目编译后的Android自动使用(-hd)高清图&amp;设置Android自适应屏幕、缩放比例方法!
- 【Cocoa(mac) Application 开发系列之四】动作编辑器(Cocos2dx)制作流程详解及附上响应鼠标滚轴事件、反转坐标系、导入/创建资源目录等知识点代码!
- 【Cocos2d-X(2.x) 游戏开发系列之一】cocos2dx(v2.x)与(v1.x)的一些常用函数区别讲解!在2.x版CCFileData类被去除等
- 【Cocos2d-X(2.x) 游戏开发系列之二】cocos2dx最新2.0.1版本跨平台整合NDK+Xcode,Xcode编写&amp;编译代码,Android导入打包运行即可!
- 【Cocos2dX(2.x)_Lua开发之三】★重要必看篇★在Lua中使用自定义精灵(Lua脚本与自创建类之间的访问)及Lua基础讲解
- 【Cocos2d-X(2.x) 游戏开发系列之三】最新版本cocos2d&#173;2.0&#173;x&#173;2.0.2使用新资源加载策略!不再沿用-hd、-ipad、-ipadhd添加后缀方式
- 【Cocos2d-X(1.x 2.x) 修复篇】iOS6 中 libcurl.a 无法通过armv7s编译以及iOS6中无法正常游戏横屏的解决方法
- 【Cocos2d-X(1.x 2.x) 】iOS6与iphone5适相关设置随笔(解决第三方类库无法通过armv7s编译的方法、添加Default-568h@2x.png)